app/Plugin/Cecplgbase/Controller/ProductController.php line 174

Open in your IDE?
  1. <?php
  2. namespace Plugin\Cecplgbase\Controller;
  3. use Eccube\Controller\ProductController as ParentProductController;
  4. use Eccube\Repository\PageRepository;
  5. use Eccube\Entity\BaseInfo;
  6. use Eccube\Entity\Master\ProductStatus;
  7. use Eccube\Entity\Product;
  8. use Eccube\Entity\ProductClass;
  9. use Eccube\Entity\ClassName;
  10. use Eccube\Event\EccubeEvents;
  11. use Eccube\Event\EventArgs;
  12. use Eccube\Form\Type\AddCartType;
  13. use Eccube\Form\Type\Master\ProductListMaxType;
  14. use Eccube\Form\Type\Master\ProductListOrderByType;
  15. use Eccube\Form\Type\SearchProductType;
  16. use Eccube\Repository\BaseInfoRepository;
  17. use Eccube\Repository\CustomerFavoriteProductRepository;
  18. use Eccube\Repository\Master\ProductListMaxRepository;
  19. use Eccube\Repository\ProductRepository;
  20. use Eccube\Repository\ClassNameRepository;
  21. use Eccube\Repository\ClassCategoryRepository;
  22. use Eccube\Service\CartService;
  23. use Eccube\Service\PurchaseFlow\PurchaseContext;
  24. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  25. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  26. use Knp\Component\Pager\Paginator;
  27. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  28. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  31. use Symfony\Component\Routing\Annotation\Route;
  32. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  33. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  34. use Plugin\Cecplgbase\Repository\ConfigRepository;
  35. class ProductController extends ParentProductController
  36. {
  37.     /**
  38.      * @var PurchaseFlow
  39.      */
  40.     protected $purchaseFlow;
  41.     /**
  42.      * @var CustomerFavoriteProductRepository
  43.      */
  44.     protected $customerFavoriteProductRepository;
  45.     /**
  46.      * @var CartService
  47.      */
  48.     protected $cartService;
  49.     /**
  50.      * @var ProductRepository
  51.      */
  52.     protected $productRepository;
  53.     /**
  54.      * @var BaseInfo
  55.      */
  56.     protected $BaseInfo;
  57.     /**
  58.      * @var AuthenticationUtils
  59.      */
  60.     protected $helper;
  61.     /**
  62.      * @var ProductListMaxRepository
  63.      */
  64.     protected $productListMaxRepository;
  65.     /**
  66.      * @var PageRepository
  67.      */
  68.     protected $pageRepository;
  69.     /**
  70.      * @var ClassNameRepository
  71.      */
  72.     protected $classNameRepository;
  73.     /**
  74.      * @var ClassCategoryRepository
  75.      */
  76.     protected $classCategoryRepository;
  77.     /**
  78.      * @var ConfigRepository
  79.      */
  80.     protected $configRepository;
  81.     private $title '';
  82.     /**
  83.      * ProductController constructor.
  84.      *
  85.      * @param PurchaseFlow $cartPurchaseFlow
  86.      * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
  87.      * @param CartService $cartService
  88.      * @param ProductRepository $productRepository
  89.      * @param BaseInfoRepository $baseInfoRepository
  90.      * @param AuthenticationUtils $helper
  91.      * @param ProductListMaxRepository $productListMaxRepository
  92.      * @param PageRepository $pageRepository
  93.      * @param ClassNameRepository $classNameRepository
  94.      * @param ClassCategoryRepository $classCategoryRepository
  95.      * @param ConfigRepository $configRepository
  96.      */
  97.     public function __construct(
  98.         PurchaseFlow $cartPurchaseFlow,
  99.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  100.         CartService $cartService,
  101.         ProductRepository $productRepository,
  102.         BaseInfoRepository $baseInfoRepository,
  103.         AuthenticationUtils $helper,
  104.         ProductListMaxRepository $productListMaxRepository,
  105.         PageRepository $pageRepository,
  106.         ClassNameRepository $classNameRepository,
  107.         ClassCategoryRepository $classCategoryRepository,
  108.         ConfigRepository $configRepository
  109.     ) {
  110.         $this->purchaseFlow $cartPurchaseFlow;
  111.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  112.         $this->cartService $cartService;
  113.         $this->productRepository $productRepository;
  114.         $this->BaseInfo $baseInfoRepository->get();
  115.         $this->helper $helper;
  116.         $this->productListMaxRepository $productListMaxRepository;
  117.         $this->pageRepository $pageRepository;
  118.         $this->classNameRepository $classNameRepository;
  119.         $this->classCategoryRepository $classCategoryRepository;
  120.         $this->configRepository $configRepository->get();
  121.     }
  122.      /**
  123.      * 商品一覧画面.
  124.      *
  125.      * @Route("/products/list", name="product_list")
  126.      * @Template("Product/list.twig")
  127.      */
  128.     public function index(Request $requestPaginator $paginator)
  129.     {
  130.         $arrRet parent::index($request$paginator);
  131.         //タグの情報を作成
  132.         $search_form=$arrRet['search_form'];
  133.         $arrVars $search_form->vars;
  134.         $arrValues $arrVars['value'];
  135.         $arrRet['Tag'] = $arrValues['tag_id'];
  136.         return $arrRet;
  137.     }
  138.     /**
  139.      * 商品詳細画面.
  140.      *
  141.      * @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"})
  142.      * @Template("Product/detail.twig")
  143.      * @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"})
  144.      *
  145.      * @param Request $request
  146.      * @param Product $Product
  147.      *
  148.      * @return array
  149.      */
  150.     public function detail(Request $requestProduct $Product)
  151.     {
  152.         //親のdetailで作成される変数を用意する。titleとsub_titleは使わない
  153.         $arrRarent parent::detail($request,$Product);
  154.         $form $arrRarent['form'];
  155.         $Product $arrRarent['Product'];
  156.         $is_favorite $arrRarent['is_favorite'];
  157.         // 規格名1/2から組み合わせを生成し, DBから取得した商品規格とマージする.
  158.         // Cecplgbase/Resource/template/sample_classcategory_table.twigのコードを商品詳細ページで使うための変数作成
  159.         if(isset($form['classcategory_id1'])){
  160.             $ClassName1 $this->classNameRepository->findOneBy(['name'=>$Product->getClassName1()]);
  161.             $ClassName2 $this->classNameRepository->findOneBy(['name'=>$Product->getClassName2()]);
  162.             $ProductClasses $Product->getProductClasses();
  163.             $ProductClasses $this->mergeProductClasses(
  164.                 $this->createProductClasses($ClassName1$ClassName2),
  165.                 $ProductClasses);
  166.         }
  167.         //ページのタイトル変更用
  168.         $Page $this->pageRepository
  169.         ->findOneBy([
  170.             'id' => 3,
  171.         ]);
  172.         if(!empty($Product->getAuthor())) $Page->setAuthor($Product->getAuthor());
  173.         if(!empty($Product->getDescription())) $Page->setDescription($Product->getDescription());
  174.         if(!empty($Product->getKeyword())) $Page->setKeyword($Product->getKeyword());
  175.         if(!empty($Product->getMetaRobots())) $Page->setMetaRobots($Product->getMetaRobots());
  176.         if(!empty($Product->getMetaTags())) $Page->setMetaTags($Product->getMetaTags());
  177.         if(!empty($Product->getTitle())){
  178.             $subtitle=$Product->getTitle();
  179.         }
  180.         else{
  181.             $subtitle=$Product->getName();
  182.         }
  183.         //「関連カテゴリ」表示で、親カテを重複して表示させない
  184.         $arrTemp=array();
  185.         foreach($Product->getProductCategories() as $ProductCategory){
  186.             if($ProductCategory->getCategory()->getParent()){
  187.                 $arrTemp[]=$ProductCategory->getCategory()->getParent()->getId();
  188.             };
  189.         }
  190.         foreach($Product->getProductCategories() as $key=>$value){
  191.             if(in_array($value['category_id'],$arrTemp)){
  192.                 unset($Product->getProductCategories()[$key]);
  193.             }
  194.         }
  195.         return [
  196.             'Page' => $Page,
  197.             'subtitle' => $subtitle,
  198.             'form' => $form,
  199.             'Product' => $Product,
  200.             'is_favorite' => $is_favorite,
  201.             'ProductClasses' => $ProductClasses??NULL
  202.         ];// オリジナルはここで'title' => $this->titleで空の値をパスしてますが、そのラインを削除して、他ページと同様、ページ管理の値がtitleに入るようにしてます。
  203.     }
  204.     /**
  205.      * カートに追加.
  206.      *
  207.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})
  208.      */
  209.     public function addCart(Request $requestProduct $Product)
  210.     {
  211.         // エラーメッセージの配列
  212.         $errorMessages = [];
  213.         if (!$this->checkVisibility($Product)) {
  214.             throw new NotFoundHttpException();
  215.         }
  216.         $builder $this->formFactory->createNamedBuilder(
  217.             '',
  218.             AddCartType::class,
  219.             null,
  220.             [
  221.                 'product' => $Product,
  222.                 'id_add_product_id' => false,
  223.             ]
  224.         );
  225.         $event = new EventArgs(
  226.             [
  227.                 'builder' => $builder,
  228.                 'Product' => $Product,
  229.             ],
  230.             $request
  231.         );
  232.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  233.         /* @var $form \Symfony\Component\Form\FormInterface */
  234.         $form $builder->getForm();
  235.         $form->handleRequest($request);
  236.         if (!$form->isValid()) {
  237.             throw new NotFoundHttpException();
  238.         }
  239.         $addCartData $form->getData();
  240.         log_info(
  241.             'カート追加処理開始',
  242.             [
  243.                 'product_id' => $Product->getId(),
  244.                 'product_class_id' => $addCartData['product_class_id'],
  245.                 'quantity' => $addCartData['quantity'],
  246.             ]
  247.         );
  248.         // カートへ追加, シンプル規格ここを編集 by toguchi 2022-09-03
  249.         if($this->configRepository->getSimpleClassOn() && count($Product->getSimpleClassNames())>){
  250.             $SimpleClass = [];
  251.             foreach($Product->getSimpleClassNames() as $SimpleClassName){
  252.                 $SimpleClass[$SimpleClassName->getId()] = $form->get('simple_class_'.$SimpleClassName->getId())->getData();
  253.             }
  254.             $this->cartService->addProduct($addCartData['product_class_id'], $addCartData['quantity'], $SimpleClass);
  255.         }
  256.         else{
  257.             $this->cartService->addProduct($addCartData['product_class_id'], $addCartData['quantity']);
  258.         }
  259.         // 明細の正規化
  260.         $Carts $this->cartService->getCarts();
  261.         foreach ($Carts as $Cart) {
  262.             $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  263.             // 復旧不可のエラーが発生した場合は追加した明細を削除.
  264.             if ($result->hasError()) {
  265.                 $this->cartService->removeProduct($addCartData['product_class_id']);
  266.                 foreach ($result->getErrors() as $error) {
  267.                     $errorMessages[] = $error->getMessage();
  268.                 }
  269.             }
  270.             foreach ($result->getWarning() as $warning) {
  271.                 $errorMessages[] = $warning->getMessage();
  272.             }
  273.         }
  274.         $this->cartService->save();
  275.         log_info(
  276.             'カート追加処理完了',
  277.             [
  278.                 'product_id' => $Product->getId(),
  279.                 'product_class_id' => $addCartData['product_class_id'],
  280.                 'quantity' => $addCartData['quantity'],
  281.             ]
  282.         );
  283.         $event = new EventArgs(
  284.             [
  285.                 'form' => $form,
  286.                 'Product' => $Product,
  287.             ],
  288.             $request
  289.         );
  290.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  291.         if ($event->getResponse() !== null) {
  292.             return $event->getResponse();
  293.         }
  294.         if ($request->isXmlHttpRequest()) {
  295.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  296.             // 初期化
  297.             $done null;
  298.             $messages = [];
  299.             if (empty($errorMessages)) {
  300.                 // エラーが発生していない場合
  301.                 $done true;
  302.                 array_push($messagestrans('front.product.add_cart_complete'));
  303.             } else {
  304.                 // エラーが発生している場合
  305.                 $done false;
  306.                 $messages $errorMessages;
  307.             }
  308.             return $this->json(['done' => $done'messages' => $messages]);
  309.         } else {
  310.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  311.             foreach ($errorMessages as $errorMessage) {
  312.                 $this->addRequestError($errorMessage);
  313.             }
  314.             return $this->redirectToRoute('cart');
  315.         }
  316.     }
  317.     /**
  318.      * ページタイトルの設定
  319.      *
  320.      * @param  null|array $searchData
  321.      *
  322.      * @return str
  323.      */
  324.     protected function getPageTitle($searchData)
  325.     {
  326.         //タグの情報を追加して、検索結果のタイトルを変更
  327.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  328.             return '「'.$searchData['name'].'」の'.trans('front.product.search_result');
  329.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  330.             return $searchData['category_id']->getName();
  331.         } elseif (isset($searchData['tag_id']) && $searchData['tag_id']) {
  332.             return $searchData['tag_id']->getName();
  333.         } else {
  334.             return trans('front.product.all_products');
  335.         }
  336.     }
  337.     /**
  338.      * 規格名1/2から, 商品規格の組み合わせを生成する. copied from src/Eccube/Controller/Admin/Product/ProductClassController.php
  339.      *
  340.      * @param ClassName $ClassName1
  341.      * @param ClassName|null $ClassName2
  342.      *
  343.      * @return array|ProductClass[]
  344.      */
  345.     protected function createProductClasses(ClassName $ClassName1ClassName $ClassName2 null)
  346.     {
  347.         $ProductClasses = [];
  348.         $ClassCategories1 $this->classCategoryRepository->findBy(['ClassName' => $ClassName1], ['sort_no' => 'DESC']);
  349.         $ClassCategories2 = [];
  350.         if ($ClassName2) {
  351.             $ClassCategories2 $this->classCategoryRepository->findBy(['ClassName' => $ClassName2],['sort_no' => 'DESC']);
  352.         }
  353.         foreach ($ClassCategories1 as $ClassCategory1) {
  354.             // 規格1のみ
  355.             if (!$ClassName2) {
  356.                 $ProductClass = new ProductClass();
  357.                 $ProductClass->setClassCategory1($ClassCategory1);
  358.                 $ProductClasses[] = $ProductClass;
  359.                 continue;
  360.             }
  361.             // 規格1/2
  362.             foreach ($ClassCategories2 as $ClassCategory2) {
  363.                 $ProductClass = new ProductClass();
  364.                 $ProductClass->setClassCategory1($ClassCategory1);
  365.                 $ProductClass->setClassCategory2($ClassCategory2);
  366.                 $ProductClasses[] = $ProductClass;
  367.             }
  368.         }
  369.         return $ProductClasses;
  370.     }
  371.     /**
  372.      * 商品規格の配列をマージする. copied from src/Eccube/Controller/Admin/Product/ProductClassController.php
  373.      *
  374.      * @param $ProductClassesForMatrix
  375.      * @param $ProductClasses
  376.      *
  377.      * @return array|ProductClass[]
  378.      */
  379.     protected function mergeProductClasses($ProductClassesForMatrix$ProductClasses)
  380.     {
  381.         $mergedProductClasses = [];
  382.         foreach ($ProductClassesForMatrix as $pcfm) {
  383.             foreach ($ProductClasses as $pc) {
  384.                 if ($pcfm->getClassCategory1()->getId() === $pc->getClassCategory1()->getId()) {
  385.                     $cc2fm $pcfm->getClassCategory2();
  386.                     $cc2 $pc->getClassCategory2();
  387.                     if (null === $cc2fm && null === $cc2) {
  388.                         $mergedProductClasses[] = $pc;
  389.                         continue 2;
  390.                     }
  391.                     if ($cc2fm && $cc2 && $cc2fm->getId() === $cc2->getId()) {
  392.                         $mergedProductClasses[] = $pc;
  393.                         continue 2;
  394.                     }
  395.                 }
  396.             }
  397.             $mergedProductClasses[] = $pcfm;
  398.         }
  399.         return $mergedProductClasses;
  400.     }
  401. }