app/Customize/Controller/ProductController.php line 553

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Customize\Controller;
  13. use Customize\Entity\School;
  14. use Customize\Form\Type\MatomeCartType;
  15. use Eccube\Controller\AbstractController;
  16. use Eccube\Entity\BaseInfo;
  17. use Eccube\Entity\Master\ProductStatus;
  18. use Eccube\Entity\Product;
  19. use Eccube\Event\EccubeEvents;
  20. use Eccube\Event\EventArgs;
  21. use Eccube\Form\Type\AddCartType;
  22. use Eccube\Form\Type\Master\ProductListMaxType;
  23. use Eccube\Form\Type\Master\ProductListOrderByType;
  24. use Eccube\Form\Type\SearchProductType;
  25. use Eccube\Repository\BaseInfoRepository;
  26. use Eccube\Repository\CustomerFavoriteProductRepository;
  27. use Eccube\Repository\Master\ProductListMaxRepository;
  28. use Customize\Repository\ProductRepository;
  29. use Customize\Repository\RecommendXRepository;
  30. use Customize\Repository\RecommendYRepository;
  31. use Customize\Repository\RecommendSizeRepository;
  32. use Customize\Repository\ProductSchoolRepository;
  33. use Customize\Repository\SetProductRepository;
  34. use Customize\Repository\SchoolRepository;
  35. use Eccube\Repository\ProductClassRepository;
  36. use Customize\Service\CartService;
  37. use Eccube\Service\PurchaseFlow\PurchaseContext;
  38. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  39. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  40. use Knp\Component\Pager\PaginatorInterface;
  41. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  42. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  43. use Symfony\Component\HttpFoundation\Request;
  44. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  45. use Symfony\Component\Routing\Annotation\Route;
  46. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  47. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  48. use Customize\Repository\BrotherRepository;
  49. class ProductController extends AbstractController
  50. {
  51.     /**
  52.      * @var PurchaseFlow
  53.      */
  54.     protected $purchaseFlow;
  55.     /**
  56.      * @var CustomerFavoriteProductRepository
  57.      */
  58.     protected $customerFavoriteProductRepository;
  59.     /**
  60.      * @var CartService
  61.      */
  62.     protected $cartService;
  63.     /**
  64.      * @var ProductRepository
  65.      */
  66.     protected $productRepository;
  67.     /**
  68.      * @var BaseInfo
  69.      */
  70.     protected $BaseInfo;
  71.     /**
  72.      * @var AuthenticationUtils
  73.      */
  74.     protected $helper;
  75.     /**
  76.      * @var ProductListMaxRepository
  77.      */
  78.     protected $productListMaxRepository;
  79.     private $title '';
  80.     /**
  81.      * @var RecommendXRepository
  82.      */
  83.     protected $recommendXRepository;
  84.     /**
  85.      * @var RecommendYRepository
  86.      */
  87.     protected $recommendYRepository;
  88.     /**
  89.      * @var RecommendSizeRepository
  90.      */
  91.     protected $recommendSizeRepository;
  92.     /**
  93.      * @var ProductSchoolRepository
  94.      */
  95.     protected $productSchoolRepository;
  96.     /**
  97.      * @var SetProductRepository
  98.      */
  99.     protected $setProductRepository;
  100.     /**
  101.      * @var SchoolRepository
  102.      */
  103.     protected $schoolRepository;
  104.     /**
  105.      * @var ProductClassRepository
  106.      */
  107.     protected $productClassRepository;
  108.     /**
  109.      * @var BrotherRepository
  110.      */
  111.     protected $brotherRepository;
  112.     /**
  113.      * ProductController constructor.
  114.      *
  115.      * @param PurchaseFlow $cartPurchaseFlow
  116.      * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
  117.      * @param CartService $cartService
  118.      * @param ProductRepository $productRepository
  119.      * @param BaseInfoRepository $baseInfoRepository
  120.      * @param AuthenticationUtils $helper
  121.      * @param ProductListMaxRepository $productListMaxRepository
  122.      * @param RecommendXRepository $recommendXRepository
  123.      * @param RecommendYRepository $recommendYRepository
  124.      * @param RecommendSizeRepository $recommendSizeRepository
  125.      * @param ProductSchoolRepository $productSchoolRepository
  126.      * @param SetProductRepository $setProductRepository
  127.      * @param SchoolRepository $schoolRepository
  128.      * @param ProductClassRepository $productClassRepository
  129.      */
  130.     public function __construct(
  131.         PurchaseFlow $cartPurchaseFlow,
  132.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  133.         CartService $cartService,
  134.         ProductRepository $productRepository,
  135.         BaseInfoRepository $baseInfoRepository,
  136.         AuthenticationUtils $helper,
  137.         ProductListMaxRepository $productListMaxRepository,
  138.         RecommendXRepository $recommendXRepository,
  139.         RecommendYRepository $recommendYRepository,
  140.         RecommendSizeRepository $recommendSizeRepository,
  141.         ProductSchoolRepository $productSchoolRepository ,
  142.         SetProductRepository $setProductRepository,
  143.         SchoolRepository $schoolRepository,
  144.         ProductClassRepository $productClassRepository,
  145.         BrotherRepository $brotherRepository
  146.     ) {
  147.         $this->purchaseFlow $cartPurchaseFlow;
  148.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  149.         $this->cartService $cartService;
  150.         $this->productRepository $productRepository;
  151.         $this->BaseInfo $baseInfoRepository->get();
  152.         $this->helper $helper;
  153.         $this->productListMaxRepository $productListMaxRepository;
  154.         $this->recommendXRepository $recommendXRepository;
  155.         $this->recommendYRepository $recommendYRepository;
  156.         $this->recommendSizeRepository $recommendSizeRepository;
  157.         $this->productSchoolRepository $productSchoolRepository;
  158.         $this->setProductRepository $setProductRepository;
  159.         $this->schoolRepository  $schoolRepository;
  160.         $this->productClassRepository $productClassRepository;
  161.         $this->brotherRepository $brotherRepository;
  162.     }
  163.     /**
  164.      * 商品一覧画面.
  165.      *
  166.      * @Route("/products/list", name="product_list", methods={"GET", "POST"})
  167.      * @Template("Product/list.twig")
  168.      */
  169.     public function index(Request $requestPaginatorInterface $paginator)
  170.     {
  171.         // Doctrine SQLFilter
  172.         if ($this->BaseInfo->isOptionNostockHidden()) {
  173.             $this->entityManager->getFilters()->enable('option_nostock_hidden');
  174.         }
  175.         // handleRequestは空のqueryの場合は無視するため
  176.         if ($request->getMethod() === 'GET') {
  177.             $request->query->set('pageno'$request->query->get('pageno'''));
  178.         }
  179.         // searchForm
  180.         /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  181.         $builder $this->formFactory->createNamedBuilder(''SearchProductType::class);
  182.         if ($request->getMethod() === 'GET') {
  183.             $builder->setMethod('GET');
  184.         }
  185.         $event = new EventArgs(
  186.             [
  187.                 'builder' => $builder,
  188.             ],
  189.             $request
  190.         );
  191.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
  192.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  193.         $searchForm $builder->getForm();
  194.         $searchForm->handleRequest($request);
  195.         // paginator
  196.         $searchData $searchForm->getData();
  197.         $Customer $this->getUser();
  198.         $brother_id $request->get('brother_id''');
  199.         if (!empty($brother_id)) {
  200.             $Brother $this->brotherRepository->find($brother_id);
  201.             if ($Brother) {
  202.                 $Customer $Brother->getCustomer();
  203.             }
  204.         }
  205.         //default sex filtering
  206.         $School $Customer->getSchool();
  207.         if($School->getDefaultSexProductsFilteringFlag() == 1){
  208.             $customer_sex $Customer->getSex()->getId() == '男子' '女子';
  209.             $searchData['name'] = $customer_sex;
  210.         }
  211.         $temporaryOrder false;
  212.         if(is_object($Customer) && !$this->session->get('update_temporary_order_id')){
  213.             if($School){
  214.                 $this->session->set('storeMeasuringFlag'$School->getStoreMeasuringFlag());
  215.                 $this->session->set('schoolMeasuringFlag'$School->getSchoolMeasuringFlag());
  216.                 $this->session->set('onlineFlag'$School->getOnlineFlag());
  217.                 if($this->session->get('temporary_order_id') || $School->getOnlineFlag() == 0){
  218.                     $temporaryOrder true;
  219.                 }
  220.                 else{
  221.                     $temporaryOrder false;
  222.                 }
  223.             }
  224.         }
  225.         $searchData['school_id'] = $request->get('s');
  226.         $qb $this->productRepository->getQueryBuilderBySearchData($searchData);
  227.         $event = new EventArgs(
  228.             [
  229.                 'searchData' => $searchData,
  230.                 'qb' => $qb,
  231.             ],
  232.             $request
  233.         );
  234.         // $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
  235.         $searchData $event->getArgument('searchData');
  236.         $query $qb->getQuery()
  237.             ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  238.         /** @var SlidingPagination $pagination */
  239.         if( $School->getItemVisibleType()==School::ITEM_VISIBLE_TYPE_MATOME){
  240.             $limit 1000000;
  241.         }else{
  242.             $limit = !empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId();
  243.         }
  244.         $pagination $paginator->paginate(
  245.             $query,
  246.             !empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  247.             $limit,array('wrap-queries' => true)
  248.         );
  249.         $ids = [];
  250.         foreach ($pagination as $Product) {
  251.             $ids[] = $Product->getId();
  252.         }
  253.         $ProductsAndClassCategories $this->productRepository->findProductsWithSortedClassCategories($ids'p.id');
  254.         // addCart form
  255.         $forms = [];
  256.         $ProductInSets = [];
  257.         foreach ($pagination as $index=> $Product) {
  258.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  259.             $builder $this->formFactory->createNamedBuilder(
  260.                 '',
  261.                 AddCartType::class,
  262.                 null,
  263.                 [
  264.                     'product' => $ProductsAndClassCategories[$Product->getId()],
  265.                     'allow_extra_fields' => true,
  266.                 ]
  267.             );
  268.             $addCartForm $builder->getForm();
  269.             $forms[$Product->getId()] = $addCartForm->createView();
  270.             $product_ids[$index]=$Product->getId();
  271.             if($Product->getProductType() == 'set'){
  272.                 $ProductInSets[$Product->getId()] = [];
  273.                 $pis_all $this->setProductRepository->findOneBy(['set_product_id'=>$Product->getSetProductId()])->getSetProductProduct();
  274.                 foreach($pis_all as $pis)
  275.                     if( !in_array($pis->getProduct(), $ProductInSets[$Product->getId()]))
  276.                         array_push($ProductInSets[$Product->getId()], $pis->getProduct());
  277.             }
  278.         }
  279.         // 表示件数
  280.         $builder $this->formFactory->createNamedBuilder(
  281.             'disp_number',
  282.             ProductListMaxType::class,
  283.             null,
  284.             [
  285.                 'required' => false,
  286.                 'allow_extra_fields' => true,
  287.             ]
  288.         );
  289.         if ($request->getMethod() === 'GET') {
  290.             $builder->setMethod('GET');
  291.         }
  292.         $event = new EventArgs(
  293.             [
  294.                 'builder' => $builder,
  295.             ],
  296.             $request
  297.         );
  298.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_DISP);
  299.         $dispNumberForm $builder->getForm();
  300.         $dispNumberForm->handleRequest($request);
  301.         // ソート順
  302.         $builder $this->formFactory->createNamedBuilder(
  303.             'orderby',
  304.             ProductListOrderByType::class,
  305.             null,
  306.             [
  307.                 'required' => false,
  308.                 'allow_extra_fields' => true,
  309.             ]
  310.         );
  311.         if ($request->getMethod() === 'GET') {
  312.             $builder->setMethod('GET');
  313.         }
  314.         $event = new EventArgs(
  315.             [
  316.                 'builder' => $builder,
  317.             ],
  318.             $request
  319.         );
  320.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_ORDER);
  321.         $orderByForm $builder->getForm();
  322.         $orderByForm->handleRequest($request);
  323.         $Category $searchForm->get('category_id')->getData();
  324.         //まとめて購入処理 >>>
  325.         $builder $this->formFactory->createNamedBuilder(
  326.             '',
  327.             MatomeCartType::class,
  328.             null,
  329.             [
  330.                 'products' => $pagination,
  331.                 'ProductInSets' => $ProductInSets,
  332.                 'allow_extra_fields' => true,
  333.             ]
  334.         );
  335.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  336.         $matomeForm $builder->getForm();
  337.         $matomeForm->handleRequest($request);
  338.         $back $request->get('back'false);
  339.         $refresh $this->session->get('refresh'true);
  340.         if($back && $request->getMethod() == "GET" && !$refresh){
  341.             $old_matomete_items $this->session->get('matomeItems');
  342.             foreach($old_matomete_items as $product_class_id => $omi){
  343.                 $old_product_class $this->productClassRepository->find($product_class_id);
  344.                 if(isset($omi['set_product_class']['class_list'])){
  345.                     $this->cartService->addProduct($old_product_class, -abs($omi['quantity']), $omi['set_product_class']['class_list'],null,null);
  346.                 }
  347.             }
  348.             $Carts $this->cartService->getCarts();
  349.             foreach ($Carts as $Cart) {
  350.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  351.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  352.                 if ($result->hasError()) {
  353.                     foreach($old_matomete_items as $product_class_id => $omi){
  354.                         if(!empty($omi['quantity'])){
  355.                             $this->cartService->removeProduct($omi['product_class_id']);
  356.                         }
  357.                     }
  358.                     foreach ($result->getErrors() as $error) {
  359.                         $errorMessages[] = $error->getMessage();
  360.                     }
  361.                 }
  362.                 foreach ($result->getWarning() as $warning) {
  363.                     $errorMessages[] = $warning->getMessage();
  364.                 }
  365.             }
  366.             $this->cartService->save();
  367.             $refresh $this->session->set('refresh'true);
  368.         }
  369.         if($matomeForm->isSubmitted() && $matomeForm->isValid()){
  370.             $data $matomeForm->getData();
  371.             $isValid false;
  372.             foreach ($data as $item){
  373.                 foreach ($item as $cart_item){
  374.                     if(!empty($cart_item['quantity'])){
  375.                         $isValid true;
  376.                     }
  377.                 }
  378.             }
  379.             if($isValid){
  380.                 $mData = [];
  381.                 //Go Shopping
  382.                 foreach ($data as $itemKey => $item){
  383.                     foreach ($item as $cart_index => $cart_item){
  384.                         if(!empty($cart_item['quantity'])){
  385.                             $cartProduct $request->get($itemKey)[$cart_index];
  386.                             $setProductClass = [];
  387.                             foreach ($cartProduct as $attrKey => $attr){
  388.                                 if(!empty($attr['ProductClass'])){
  389.                                     $setProductClass[] = $attr['ProductClass'];
  390.                                 }
  391.                             }
  392.                             $this->cartService->addProduct($cart_item['product_class_id'], $cart_item['quantity'], $setProductClass$cart_item['remarks'],null);
  393.                             $mItem = [];
  394.                             $mItem['quantity'] = $cart_item['quantity'];
  395.                             $mItem['set_product_class'] = [];
  396.                             foreach($setProductClass as $spc){
  397.                                 $spc_class $this->productClassRepository->find($spc);
  398.                                 $productInSet $spc_class->getProduct();
  399.                                 if($spc_class && $productInSet){
  400.                                     $spc_class_category1 $spc_class->getClassCategory1();
  401.                                     $class_cat_tmp = [];
  402.                                     if($spc_class_category1){
  403.                                         $class_cat_tmp['class_category1_id'] =  $spc_class_category1->getId();
  404.                                     }
  405.                                     $spc_class_category2 $spc_class->getClassCategory2();
  406.                                     if($spc_class_category2){
  407.                                         $class_cat_tmp['class_category2_id'] =  $spc_class_category2->getId();
  408.                                     }
  409.                                     $mItem['set_product_class'][$productInSet->getId()] = $class_cat_tmp;
  410.                                     $class_cat_tmp['product_class_id'] = $spc;
  411.                                     $mItem['set_product_class'][$productInSet->getId()] = $class_cat_tmp;
  412.                                 }
  413.                             }
  414.                             $mItem['set_product_class']['class_list'] = $setProductClass;
  415.                             $mItem['remarks'] = $cart_item['remarks'];
  416.                             $productClass $this->productClassRepository->find($cart_item['product_class_id']);
  417.                             if($productClass){
  418.                                 $product_class_category1 $productClass->getClassCategory1();
  419.                                 if($product_class_category1){
  420.                                     $mItem['class_category1_id'] =  $product_class_category1->getId();
  421.                                 }
  422.                                 $product_class_category2 $productClass->getClassCategory2();
  423.                                 if($product_class_category2){
  424.                                     $mItem['class_category2_id'] =  $product_class_category2->getId();
  425.                                 }
  426.                             }
  427.                             $mData[$cart_item['product_class_id']] = $mItem;
  428.                         }
  429.                     }
  430.                 }
  431.                 // 明細の正規化
  432.                 $Carts $this->cartService->getCarts();
  433.                 foreach ($Carts as $Cart) {
  434.                     $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  435.                     // 復旧不可のエラーが発生した場合は追加した明細を削除.
  436.                     if ($result->hasError()) {
  437.                         foreach ($data as $item){
  438.                             foreach ($item as $cart_item){
  439.                                 if(!empty($cart_item['quantity'])){
  440.                                     $this->cartService->removeProduct($cart_item['product_class_id']);
  441.                                 }
  442.                             }
  443.                         }
  444.                         foreach ($result->getErrors() as $error) {
  445.                             $errorMessages[] = $error->getMessage();
  446.                         }
  447.                     }
  448.                     foreach ($result->getWarning() as $warning) {
  449.                         $errorMessages[] = $warning->getMessage();
  450.                     }
  451.                 }
  452.                 $this->cartService->save();
  453.                 if(empty($errorMessages)){
  454.                     if($temporaryOrder){
  455.                         $this->session->set('matomeItems'$mData);
  456.                         $this->session->set('refresh'false);
  457.                         return $this->redirectToRoute('shopping_temporary');
  458.                     }
  459.                     else
  460.                         return $this->redirectToRoute('shopping');
  461.                 }
  462.             }
  463.         }
  464.         //<<<
  465.         return [
  466.             'matomeForm' => $matomeForm->createView(),  //まとめ購入用
  467.             'ProductInSets' => $ProductInSets,          //まとめ購入用
  468.             'subtitle' => $this->getPageTitle($searchData),
  469.             'pagination' => $pagination,
  470.             'search_form' => $searchForm->createView(),
  471.             'disp_number_form' => $dispNumberForm->createView(),
  472.             'order_by_form' => $orderByForm->createView(),
  473.             'forms' => $forms,
  474.             'Category' => $Category,
  475.             'School' => $School,
  476.             'product_type' => isset($searchData['product_type']) ? $searchData['product_type'] : null,
  477.             'matomeItems' => $this->session->get('matomeItems'),
  478.             'back' => $back,
  479.             'FilterSchool' => $request->get('s') ? $this->schoolRepository->find($request->get('s')) : null
  480.         ];
  481.     }
  482.     /**
  483.      * 商品詳細画面.
  484.      *
  485.      * @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"})
  486.      * @Template("Product/detail.twig")
  487.      *
  488.      * @param Request $request
  489.      * @param Product $Product
  490.      *
  491.      * @return array
  492.      */
  493.     public function detail(Request $request$id)
  494.     {
  495.         $Product $this->productRepository->findWithSortedClassCategories($id);
  496.         if (!$this->checkVisibility($Product)) {
  497.             throw new NotFoundHttpException();
  498.         }
  499.         $builder $this->formFactory->createNamedBuilder(
  500.             '',
  501.             AddCartType::class,
  502.             null,
  503.             [
  504.                 'product' => $Product,
  505.                 'id_add_product_id' => false,
  506.             ]
  507.         );
  508.         $event = new EventArgs(
  509.             [
  510.                 'builder' => $builder,
  511.                 'Product' => $Product,
  512.             ],
  513.             $request
  514.         );
  515.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE);
  516.         $is_favorite false;
  517.         if ($this->isGranted('ROLE_USER')) {
  518.             $Customer $this->getUser();
  519.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  520.         }
  521.         $Place = [
  522.             1=>'肩幅',
  523.             2=>'袖丈',
  524.             3=>'裄丈',
  525.             4=>'総丈',
  526.             5=>'首回り',
  527.             11=>'バスト',
  528.             12=>'ウェスト',
  529.             13=>'ヒップ',
  530.             21=>'股下',
  531.             22=>'スカート丈',
  532.             31=>'身長',
  533.             32=>'体重',
  534.         ];
  535.         $RecommendSize = [];
  536.         $xValue 0;
  537.         $yValue 0;
  538.         $Recommend $Product->getRecommend();
  539.         if(!$Recommend) {
  540.             //学校ID->オススメサイズを取得する
  541.             $Recommend $this->productSchoolRepository->getRecommend($Product);
  542.         }
  543.         if($Recommend) {
  544.             $Recommend->getRecommendXplace();
  545.             $xKey 'getDr'.sprintf('%02d'$Recommend->getRecommendXplace());
  546.             $yKey 'getDr'.sprintf('%02d'$Recommend->getRecommendYplace());
  547.             $Customer $this->getUser();
  548.             $xValue 0;
  549.             $yValue 0;
  550.             if(method_exists($Customer,$xKey)) $xValue =$Customer->$xKey();
  551.             if(method_exists($Customer,$yKey)) $yValue =$Customer->$yKey();
  552.             $RecommendX $this->recommendXRepository->searchOne($Recommend$xValue);
  553.             $RecommendY $this->recommendYRepository->searchOne($Recommend$yValue);
  554.             if($RecommendX && $RecommendY)
  555.                 $RecommendSize $this->recommendSizeRepository->searchOne($Recommend,$RecommendX[0],$RecommendY[0]);
  556.         }
  557.         $ProductInSet = [];
  558.         if($Product->getProductType() == 'set'){
  559.             $pis_all $this->setProductRepository->findOneBy(['set_product_id'=>$Product->getSetProductId()])->getSetProductProduct();
  560.             foreach($pis_all as $pis)
  561.                 if(!in_array($pis->getProduct(), $ProductInSet))
  562.                     array_push($ProductInSet$pis->getProduct());
  563.         }
  564.         return [
  565.             'title' => $this->title,
  566.             'subtitle' => $Product->getName(),
  567.             'form' => $builder->getForm()->createView(),
  568.             'Product' => $Product,
  569.             'is_favorite' => $is_favorite,
  570.             'RecommendSize' => $RecommendSize,
  571.             'Place' => $Place,
  572.             'x' => $xValue,
  573.             'y' => $yValue,
  574.             'ProductInSet' => $ProductInSet,
  575.             'SetProduct' => $Product->getProductType() == 'set' $this->setProductRepository->findOneBy(['set_product_id'=>$Product->getSetProductId()]) : null
  576.         ];
  577.     }
  578.     /**
  579.      * お気に入り追加.
  580.      *
  581.      * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"}, methods={"GET", "POST"})
  582.      */
  583.     public function addFavorite(Request $requestProduct $Product)
  584.     {
  585.         $this->checkVisibility($Product);
  586.         $event = new EventArgs(
  587.             [
  588.                 'Product' => $Product,
  589.             ],
  590.             $request
  591.         );
  592.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE);
  593.         if ($this->isGranted('ROLE_USER')) {
  594.             $Customer $this->getUser();
  595.             $this->customerFavoriteProductRepository->addFavorite($Customer$Product);
  596.             $this->session->getFlashBag()->set('product_detail.just_added_favorite'$Product->getId());
  597.             $event = new EventArgs(
  598.                 [
  599.                     'Product' => $Product,
  600.                 ],
  601.                 $request
  602.             );
  603.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
  604.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  605.         } else {
  606.             // 非会員の場合、ログイン画面を表示
  607.             //  ログイン後の画面遷移先を設定
  608.             $this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()], UrlGeneratorInterface::ABSOLUTE_URL));
  609.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  610.             $event = new EventArgs(
  611.                 [
  612.                     'Product' => $Product,
  613.                 ],
  614.                 $request
  615.             );
  616.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
  617.             return $this->redirectToRoute('mypage_login');
  618.         }
  619.     }
  620.     /**
  621.      * カートに追加.
  622.      *
  623.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})
  624.      */
  625.     public function addCart(Request $requestProduct $Product)
  626.     {
  627.         // エラーメッセージの配列
  628.         $errorMessages = [];
  629.         if (!$this->checkVisibility($Product)) {
  630.             throw new NotFoundHttpException();
  631.         }
  632.         $builder $this->formFactory->createNamedBuilder(
  633.             '',
  634.             AddCartType::class,
  635.             null,
  636.             [
  637.                 'product' => $Product,
  638.                 'id_add_product_id' => false,
  639.             ]
  640.         );
  641.         $event = new EventArgs(
  642.             [
  643.                 'builder' => $builder,
  644.                 'Product' => $Product,
  645.             ],
  646.             $request
  647.         );
  648.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE);
  649.         /* @var $form \Symfony\Component\Form\FormInterface */
  650.         $form $builder->getForm();
  651.         $form->handleRequest($request);
  652.         if ($Product->getProductType() != 'set' && !$form->isValid()) {
  653.             throw new NotFoundHttpException();
  654.         }
  655.         $addCartData $form->getData();
  656.         log_info(
  657.             'カート追加処理開始',
  658.             [
  659.                 'product_id' => $Product->getId(),
  660.                 'product_class_id' => $addCartData['product_class_id'],
  661.                 'quantity' => $addCartData['quantity'],
  662.             ]
  663.         );
  664.         // カートへ追加
  665.         $this->cartService->addProduct($addCartData['product_class_id'], $addCartData['quantity'], $request->get('SetProductClass', []), null, isset($addCartData['brother']) ? $addCartData['brother'] : null);
  666.         // 明細の正規化
  667.         $Carts $this->cartService->getCarts();
  668.         foreach ($Carts as $Cart) {
  669.             $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  670.             // 復旧不可のエラーが発生した場合は追加した明細を削除.
  671.             if ($result->hasError()) {
  672.                 $this->cartService->removeProduct($addCartData['product_class_id']);
  673.                 foreach ($result->getErrors() as $error) {
  674.                     $errorMessages[] = $error->getMessage();
  675.                 }
  676.             }
  677.             foreach ($result->getWarning() as $warning) {
  678.                 $errorMessages[] = $warning->getMessage();
  679.             }
  680.         }
  681.         $this->cartService->save();
  682.         log_info(
  683.             'カート追加処理完了',
  684.             [
  685.                 'product_id' => $Product->getId(),
  686.                 'product_class_id' => $addCartData['product_class_id'],
  687.                 'quantity' => $addCartData['quantity'],
  688.             ]
  689.         );
  690.         $event = new EventArgs(
  691.             [
  692.                 'form' => $form,
  693.                 'Product' => $Product,
  694.             ],
  695.             $request
  696.         );
  697.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE);
  698.         if ($event->getResponse() !== null) {
  699.             return $event->getResponse();
  700.         }
  701.         if ($request->isXmlHttpRequest()) {
  702.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  703.             // 初期化
  704.             $done null;
  705.             $messages = [];
  706.             if (empty($errorMessages)) {
  707.                 // エラーが発生していない場合
  708.                 $done true;
  709.                 array_push($messagestrans('front.product.add_cart_complete'));
  710.             } else {
  711.                 // エラーが発生している場合
  712.                 $done false;
  713.                 $messages $errorMessages;
  714.             }
  715.             return $this->json(['done' => $done'messages' => $messages]);
  716.         } else {
  717.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  718.             foreach ($errorMessages as $errorMessage) {
  719.                 $this->addRequestError($errorMessage);
  720.             }
  721.             return $this->redirectToRoute('cart');
  722.         }
  723.     }
  724.     /**
  725.      * ページタイトルの設定
  726.      *
  727.      * @param  array|null $searchData
  728.      *
  729.      * @return str
  730.      */
  731.     protected function getPageTitle($searchData)
  732.     {
  733.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  734.             return trans('front.product.search_result');
  735.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  736.             return $searchData['category_id']->getName();
  737.         } else {
  738.             return trans('front.product.all_products');
  739.         }
  740.     }
  741.     /**
  742.      * 閲覧可能な商品かどうかを判定
  743.      *
  744.      * @param Product $Product
  745.      *
  746.      * @return boolean 閲覧可能な場合はtrue
  747.      */
  748.     protected function checkVisibility(Product $Product)
  749.     {
  750.         $is_admin $this->session->has('_security_admin');
  751.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  752.         if (!$is_admin) {
  753.             // 在庫なし商品の非表示オプションが有効な場合.
  754.             // if ($this->BaseInfo->isOptionNostockHidden()) {
  755.             //     if (!$Product->getStockFind()) {
  756.             //         return false;
  757.             //     }
  758.             // }
  759.             // 公開ステータスでない商品は表示しない.
  760.             if ($Product->getStatus()->getId() !== ProductStatus::DISPLAY_SHOW) {
  761.                 return false;
  762.             }
  763.         }
  764.         return true;
  765.     }
  766.     /**
  767.      * 価格取得.
  768.      *
  769.      * @Route("/products/get_product_price", name="get_product_price", methods={"POST"})
  770.      */
  771.     public function getPriceByProductClass(Request $request)
  772.     {
  773.         $product_class_id $request->get('product_class_id'null);
  774.         $done false;
  775.         if($product_class_id){
  776.             $done true;
  777.             $ProductClass $this->productClassRepository->find($product_class_id);
  778.             $Customer $this->getUser();
  779.             if($Customer->getSchool()->isOnSale() && !empty($ProductClass->getPrice03IncTax())){
  780.                 return $this->json(['done' => $done'price' => $ProductClass->getPrice03IncTax()]);
  781.             }
  782.             else
  783.                 return $this->json(['done' => $done'price' => $ProductClass->getPrice02IncTax()]);
  784.         }
  785.         return $this->json(['done' => false'price' => null]);
  786.     }
  787. }