app/Customize/Controller/CustomCartController.php line 130

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 Eccube\Entity\BaseInfo;
  14. use Eccube\Entity\ProductClass;
  15. use Eccube\Event\EccubeEvents;
  16. use Eccube\Event\EventArgs;
  17. use Eccube\Repository\BaseInfoRepository;
  18. use Eccube\Repository\ProductClassRepository;
  19. use Eccube\Service\CartService;
  20. use Eccube\Service\OrderHelper;
  21. use Eccube\Service\PurchaseFlow\PurchaseContext;
  22. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  23. use Eccube\Service\PurchaseFlow\PurchaseFlowResult;
  24. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\Routing\Annotation\Route;
  27. use Eccube\Controller\AbstractController;
  28. use Customize\Form\Type\CartOptionType;
  29. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  30. use Eccube\Repository\CartItemRepository;
  31. class CustomCartController extends AbstractController
  32. {
  33.     /**
  34.      * @var ProductClassRepository
  35.      */
  36.     protected $productClassRepository;
  37.     /**
  38.      * @var CartItemRepository
  39.      */
  40.     protected $cartItemRepository;
  41.     /**
  42.      * @var CartService
  43.      */
  44.     protected $cartService;
  45.     /**
  46.      * @var PurchaseFlow
  47.      */
  48.     protected $purchaseFlow;
  49.     /**
  50.      * @var BaseInfo
  51.      */
  52.     protected $baseInfo;
  53.     /**
  54.      * CartController constructor.
  55.      *
  56.      * @param ProductClassRepository $productClassRepository
  57.      * @param CartItemRepository $cartItemRepository
  58.      * @param CartService $cartService
  59.      * @param PurchaseFlow $cartPurchaseFlow
  60.      * @param BaseInfoRepository $baseInfoRepository
  61.      */
  62.     public function __construct(
  63.         ProductClassRepository $productClassRepository,
  64.         CartItemRepository $cartItemRepository,
  65.         CartService $cartService,
  66.         PurchaseFlow $cartPurchaseFlow,
  67.         BaseInfoRepository $baseInfoRepository
  68.     ) {
  69.         $this->productClassRepository $productClassRepository;
  70.         $this->cartItemRepository $cartItemRepository;
  71.         $this->cartService $cartService;
  72.         $this->purchaseFlow $cartPurchaseFlow;
  73.         $this->baseInfo $baseInfoRepository->get();
  74.     }
  75.     /**
  76.      * カート画面.
  77.      *
  78.      * @Route("/cart", name="cart", methods={"GET"})
  79.      * @Template("Cart/index.twig")
  80.      */
  81.     public function index(Request $request)
  82.     {
  83.         // カートを取得して明細の正規化を実行
  84.         $Carts $this->cartService->getCarts();
  85.         $this->execPurchaseFlow($Carts);
  86.         // TODO itemHolderから取得できるように
  87.         $least = [];
  88.         $quantity = [];
  89.         $isDeliveryFree = [];
  90.         $totalPrice 0;
  91.         $totalQuantity 0;
  92.         foreach ($Carts as $Cart) {
  93.             $quantity[$Cart->getCartKey()] = 0;
  94.             $isDeliveryFree[$Cart->getCartKey()] = false;
  95.             if ($this->baseInfo->getDeliveryFreeQuantity()) {
  96.                 if ($this->baseInfo->getDeliveryFreeQuantity() > $Cart->getQuantity()) {
  97.                     $quantity[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeQuantity() - $Cart->getQuantity();
  98.                 } else {
  99.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  100.                 }
  101.             }
  102.             if ($this->baseInfo->getDeliveryFreeAmount()) {
  103.                 if (!$isDeliveryFree[$Cart->getCartKey()] && $this->baseInfo->getDeliveryFreeAmount() <= $Cart->getTotalPrice()) {
  104.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  105.                 } else {
  106.                     $least[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeAmount() - $Cart->getTotalPrice();
  107.                 }
  108.             }
  109.             $totalPrice += $Cart->getTotalPrice();
  110.             $totalQuantity += $Cart->getQuantity();
  111.         }
  112.         // カートが分割された時のセッション情報を削除
  113.         $request->getSession()->remove(OrderHelper::SESSION_CART_DIVIDE_FLAG);
  114.         // オプション項目入力フォームを追加
  115.         $builder $this->formFactory->createBuilder( );
  116.         $builder
  117.             ->add(
  118.                 'data',
  119.                 CollectionType::class,
  120.                 [
  121.                     'entry_type' => CartOptionType::class,
  122.                     'entry_options' => [
  123.                         //'product' => $Product,
  124.                         //'id_add_product_id' => false,
  125.                         //'attr' => ['class' => 'oneclass'],
  126.                     ],
  127.                     'allow_add' => true,
  128.                     'allow_delete' => true,
  129.                     'label' => '',
  130.                 ]
  131.                 );
  132.         //$form = $this->createForm(CartOptionType::class);
  133.         //$form->handleRequest($request);
  134.         return [
  135.             'totalPrice' => $totalPrice,
  136.             'totalQuantity' => $totalQuantity,
  137.             // 空のカートを削除し取得し直す
  138.             'Carts' => $this->cartService->getCarts(true),
  139.             'least' => $least,
  140.             'quantity' => $quantity,
  141.             'is_delivery_free' => $isDeliveryFree,
  142.             //'form' => $form->createView(), //cartoption
  143.             'form' => $builder->getForm()->createView(),
  144.         ];
  145.     }
  146.     /**
  147.      * @param $Carts
  148.      *
  149.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
  150.      */
  151.     protected function execPurchaseFlow($Carts)
  152.     {
  153.         /** @var PurchaseFlowResult[] $flowResults */
  154.         $flowResults array_map(function ($Cart) {
  155.             $purchaseContext = new PurchaseContext($Cart$this->getUser());
  156.             return $this->purchaseFlow->validate($Cart$purchaseContext);
  157.         }, $Carts);
  158.         // 復旧不可のエラーが発生した場合はカートをクリアして再描画
  159.         $hasError false;
  160.         foreach ($flowResults as $result) {
  161.             if ($result->hasError()) {
  162.                 $hasError true;
  163.                 foreach ($result->getErrors() as $error) {
  164.                     $this->addRequestError($error->getMessage());
  165.                 }
  166.             }
  167.         }
  168.         if ($hasError) {
  169.             $this->cartService->clear();
  170.             return $this->redirectToRoute('cart');
  171.         }
  172.         $this->cartService->save();
  173.         foreach ($flowResults as $index => $result) {
  174.             foreach ($result->getWarning() as $warning) {
  175.                 if ($Carts[$index]->getItems()->count() > 0) {
  176.                     $cart_key $Carts[$index]->getCartKey();
  177.                     $this->addRequestError($warning->getMessage(), "front.cart.${cart_key}");
  178.                 } else {
  179.                     // キーが存在しない場合はグローバルにエラーを表示する
  180.                     $this->addRequestError($warning->getMessage());
  181.                 }
  182.             }
  183.         }
  184.         return null;
  185.     }
  186.     /**
  187.      * カート明細の加算/減算/削除を行う.
  188.      *
  189.      * - 加算
  190.      *      - 明細の個数を1増やす
  191.      * - 減算
  192.      *      - 明細の個数を1減らす
  193.      *      - 個数が0になる場合は、明細を削除する
  194.      * - 削除
  195.      *      - 明細を削除する
  196.      *
  197.      * @Route(
  198.      *     path="/cart/{operation}/{productClassId}",
  199.      *     name="cart_handle_item",
  200.      *     methods={"PUT"},
  201.      *     requirements={
  202.      *          "operation": "up|down|remove",
  203.      *          "productClassId": "\d+"
  204.      *     }
  205.      * )
  206.      */
  207.     public function handleCartItem($operation$productClassId)
  208.     {
  209.         log_info('カート明細操作開始', ['operation' => $operation'product_class_id' => $productClassId]);
  210.         $this->isTokenValid();
  211.         /** @var ProductClass $ProductClass */
  212.         $ProductClass $this->productClassRepository->find($productClassId);
  213.         // if (is_null($ProductClass)) {
  214.         //     log_info('商品が存在しないため、カート画面へredirect', ['operation' => $operation, 'product_class_id' => $productClassId]);
  215.         //     return $this->redirectToRoute('cart');
  216.         // }
  217.         // 明細の増減・削除
  218.         switch ($operation) {
  219.             case 'up':
  220.                 $this->cartService->addProduct($ProductClass1);
  221.                 break;
  222.             case 'down':
  223.                 $this->cartService->addProduct($ProductClass, -1);
  224.                 break;
  225.             case 'remove':
  226.                 // 削除の場合カート画面からはCartItem.idが渡されている。そのままremoveProductへ渡す。
  227.                 $this->cartService->removeCartItem($productClassId);
  228.                 break;
  229.         }
  230.         // カートを取得して明細の正規化を実行
  231.         $Carts $this->cartService->getCarts();
  232.         $this->execPurchaseFlow($Carts);
  233.         log_info('カート演算処理終了', ['operation' => $operation'product_class_id' => $productClassId]);
  234.         return $this->redirectToRoute('cart');
  235.     }
  236.     /**
  237.      * カートをロック状態に設定し、購入確認画面へ遷移する.
  238.      *
  239.      * @Route("/cart/buystep/{cart_key}", name="cart_buystep", requirements={"cart_key" = "[a-zA-Z0-9]+[_][\x20-\x7E]+"}, methods={"GET"})
  240.      */
  241.     public function buystep(Request $request$cart_key)
  242.     {   
  243.         $Carts $this->cartService->getCart();
  244.         if (!is_object($Carts)) {
  245.             return $this->redirectToRoute('cart');
  246.         }
  247.         // FRONT_CART_BUYSTEP_INITIALIZE
  248.         $event = new EventArgs(
  249.             [],
  250.             $request
  251.         );
  252.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_INITIALIZE);
  253.         $this->cartService->setPrimary($cart_key);
  254.         $this->cartService->save();
  255.         // FRONT_CART_BUYSTEP_COMPLETE
  256.         $event = new EventArgs(
  257.             [],
  258.             $request
  259.         );
  260.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_COMPLETE);
  261.         if ($event->hasResponse()) {
  262.             return $event->getResponse();
  263.         }
  264.         return $this->redirectToRoute('shopping');
  265.     }
  266.     /**
  267.      * カートの商品にオプション情報追加.
  268.      *
  269.      * @Route("/cart/add_option", name="cart_add_option", methods={"POST"})
  270.      */
  271.     public function add_option(Request $request)
  272.     { 
  273.         $form $request->get('form');
  274.         foreach ($form['data'] as $Item) {
  275.             $cartitem $this->cartItemRepository->find($Item['cart_item_id']);
  276.             $cartitem->setEngraving($Item['engraving']);
  277.             if (isset($Item['engraving_font'])) {
  278.                 $cartitem->setEngravingFont($Item['engraving_font']);
  279.             }
  280.             $cartitem->setEngravingText($Item['engraving_text']);
  281.             $cartitem->setStone($Item['stone']);
  282.             $cartitem->setOptionTotalPrice($Item['option_total_price']);
  283.             // DB書き込み
  284.             $entityManager $this->getDoctrine()->getManager();
  285.             $entityManager->persist($cartitem);
  286.             $entityManager->flush();
  287.         }
  288.         // すでにOrderItemが作成されている場合は作り直す
  289.         $Cart $this->entityManager->getRepository(\Eccube\Entity\Cart::class)->findOneBy(array('cart_key' => $form['data'][0]['cart_key']));
  290.         if($Cart) {
  291.             $Order $this->entityManager->getRepository(\Eccube\Entity\Order::class)->findOneBy(array('pre_order_id' => $Cart->getPreOrderId()));
  292.             if($Order) {
  293.                 $OrderItems $this->entityManager->getRepository(\Eccube\Entity\OrderItem::class)->findBy(array('Order' => $Order));
  294.                 if($OrderItems) {
  295.                     $cnt 0;
  296.                     foreach ($OrderItems as $OrderItem) {
  297.                         if ($OrderItem->isProduct()) {
  298.                             // 保存
  299.                             $newOrderItem = clone $OrderItem;
  300.                             // DBから削除
  301.                             $entityManager $this->getDoctrine()->getManager();
  302.                             $entityManager->remove($OrderItem);
  303.                             $entityManager->flush();
  304.                             // オプション情報更新
  305.                             if (array_key_exists('engraving'$form['data'][$cnt])) {
  306.                                 $newOrderItem->setEngraving($form['data'][$cnt]['engraving']);
  307.                             }
  308.                             if (array_key_exists('engraving_font'$form['data'][$cnt])) {
  309.                                 $newOrderItem->setEngravingFont($form['data'][$cnt]['engraving_font']);
  310.                             }
  311.                             if (array_key_exists('engraving_text'$form['data'][$cnt])) {                                
  312.                                 $newOrderItem->setEngravingText($form['data'][$cnt]['engraving_text']);
  313.                             }
  314.                             if (array_key_exists('stone'$form['data'][$cnt])) {                                
  315.                                 $newOrderItem->setStone($form['data'][$cnt]['stone']);
  316.                             }
  317.                             if (array_key_exists('option_total_price'$form['data'][$cnt])) {                                
  318.                                 $newOrderItem->setOptionTotalPrice($form['data'][$cnt]['option_total_price']);
  319.                             }
  320.                             $Order->addOrderItem($newOrderItem);
  321.                             $this->entityManager->persist($newOrderItem);
  322.                             $entityManager->flush();
  323.                             $cnt++;
  324.                         }
  325.                     }
  326.                 }
  327.             }
  328.         }
  329.         
  330.         $cart_key $form['data'][0]['cart_key'];
  331.         return $this->redirectToRoute('cart_buystep',['cart_key' => $cart_key]);
  332.     }
  333. }