app/Customize/Controller/CartController.php line 102

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. // 追加
  28. use Eccube\Controller\AbstractController;
  29. use Customize\Repository\CategoryRepository;
  30. class CartController extends AbstractController
  31. {
  32.     protected $categoryRepository;
  33.     protected $productClassRepository;
  34.     protected $cartService;
  35.     protected $purchaseFlow;
  36.     protected $baseInfo;
  37.     public function __construct(
  38.         CategoryRepository $categoryRepository,
  39.         ProductClassRepository $productClassRepository,
  40.         CartService $cartService,
  41.         PurchaseFlow $cartPurchaseFlow,
  42.         BaseInfoRepository $baseInfoRepository
  43.     ) {
  44.         $this->categoryRepository $categoryRepository;
  45.         $this->productClassRepository $productClassRepository;
  46.         $this->cartService $cartService;
  47.         $this->purchaseFlow $cartPurchaseFlow;
  48.         $this->baseInfo $baseInfoRepository->get();
  49.     }
  50.     /**
  51.      * カート画面.
  52.      *
  53.      * @Route("/cart", name="cart", methods={"GET"})
  54.      * @Template("Cart/index.twig")
  55.      */
  56.     public function index(Request $request)
  57.     {
  58.         // カートを取得して明細の正規化を実行
  59.         $Carts $this->cartService->getCarts();
  60.         $this->execPurchaseFlow($Carts);
  61.         // TODO itemHolderから取得できるように
  62.         $least = [];
  63.         $quantity = [];
  64.         $isDeliveryFree = [];
  65.         $totalPrice 0;
  66.         $totalQuantity 0;
  67.         foreach ($Carts as $Cart) {
  68.             $quantity[$Cart->getCartKey()] = 0;
  69.             $isDeliveryFree[$Cart->getCartKey()] = false;
  70.             if ($this->baseInfo->getDeliveryFreeQuantity()) {
  71.                 if ($this->baseInfo->getDeliveryFreeQuantity() > $Cart->getQuantity()) {
  72.                     $quantity[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeQuantity() - $Cart->getQuantity();
  73.                 } else {
  74.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  75.                 }
  76.             }
  77.             if ($this->baseInfo->getDeliveryFreeAmount()) {
  78.                 if (!$isDeliveryFree[$Cart->getCartKey()] && $this->baseInfo->getDeliveryFreeAmount() <= $Cart->getTotalPrice()) {
  79.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  80.                 } else {
  81.                     $least[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeAmount() - $Cart->getTotalPrice();
  82.                 }
  83.             }
  84.             $totalPrice += $Cart->getTotalPrice();
  85.             $totalQuantity += $Cart->getQuantity();
  86.         }
  87.         // カートが分割された時のセッション情報を削除
  88.         $request->getSession()->remove(OrderHelper::SESSION_CART_DIVIDE_FLAG);
  89.         // メニュー用カテゴリー一覧
  90.         $Cate1st $this->categoryRepository->findOneBy(['id' => 1]);
  91.         $sortedChildren $Cate1st $Cate1st->getChildren()->toArray() : [];
  92.         usort($sortedChildren, function($a$b) {    // sort_no 昇順でソート
  93.             return $a->getSortNo() <=> $b->getSortNo();
  94.         });
  95.         return [
  96.             'totalPrice' => $totalPrice,
  97.             'totalQuantity' => $totalQuantity,
  98.             // 空のカートを削除し取得し直す
  99.             'Carts' => $this->cartService->getCarts(true),
  100.             'least' => $least,
  101.             'quantity' => $quantity,
  102.             'is_delivery_free' => $isDeliveryFree,
  103.             'sortedChildren' => $sortedChildren,
  104.         ];
  105.     }
  106.     /**
  107.      * @param $Carts
  108.      *
  109.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
  110.      */
  111.     protected function execPurchaseFlow($Carts)
  112.     {
  113.         /** @var PurchaseFlowResult[] $flowResults */
  114.         $flowResults array_map(function ($Cart) {
  115.             $purchaseContext = new PurchaseContext($Cart$this->getUser());
  116.             return $this->purchaseFlow->validate($Cart$purchaseContext);
  117.         }, $Carts);
  118.         // 復旧不可のエラーが発生した場合はカートをクリアして再描画
  119.         $hasError false;
  120.         foreach ($flowResults as $result) {
  121.             if ($result->hasError()) {
  122.                 $hasError true;
  123.                 foreach ($result->getErrors() as $error) {
  124.                     $this->addRequestError($error->getMessage());
  125.                 }
  126.             }
  127.         }
  128.         if ($hasError) {
  129.             $this->cartService->clear();
  130.             return $this->redirectToRoute('cart');
  131.         }
  132.         $this->cartService->save();
  133.         foreach ($flowResults as $index => $result) {
  134.             foreach ($result->getWarning() as $warning) {
  135.                 if ($Carts[$index]->getItems()->count() > 0) {
  136.                     $cart_key $Carts[$index]->getCartKey();
  137.                     $this->addRequestError($warning->getMessage(), "front.cart.${cart_key}");
  138.                 } else {
  139.                     // キーが存在しない場合はグローバルにエラーを表示する
  140.                     $this->addRequestError($warning->getMessage());
  141.                 }
  142.             }
  143.         }
  144.         return null;
  145.     }
  146.     /**
  147.      * カート明細の加算/減算/削除を行う.
  148.      *
  149.      * - 加算
  150.      *      - 明細の個数を1増やす
  151.      * - 減算
  152.      *      - 明細の個数を1減らす
  153.      *      - 個数が0になる場合は、明細を削除する
  154.      * - 削除
  155.      *      - 明細を削除する
  156.      *
  157.      * @Route(
  158.      *     path="/cart/{operation}/{productClassId}",
  159.      *     name="cart_handle_item",
  160.      *     methods={"PUT"},
  161.      *     requirements={
  162.      *          "operation": "up|down|remove",
  163.      *          "productClassId": "\d+"
  164.      *     }
  165.      * )
  166.      */
  167.     public function handleCartItem($operation$productClassId)
  168.     {
  169.         log_info('カート明細操作開始', ['operation' => $operation'product_class_id' => $productClassId]);
  170.         $this->isTokenValid();
  171.         /** @var ProductClass $ProductClass */
  172.         $ProductClass $this->productClassRepository->find($productClassId);
  173.         if (is_null($ProductClass)) {
  174.             log_info('商品が存在しないため、カート画面へredirect', ['operation' => $operation'product_class_id' => $productClassId]);
  175.             return $this->redirectToRoute('cart');
  176.         }
  177.         // 明細の増減・削除
  178.         switch ($operation) {
  179.             case 'up':
  180.                 $this->cartService->addProduct($ProductClass1);
  181.                 break;
  182.             case 'down':
  183.                 $this->cartService->addProduct($ProductClass, -1);
  184.                 break;
  185.             case 'remove':
  186.                 $this->cartService->removeProduct($ProductClass);
  187.                 break;
  188.         }
  189.         // カートを取得して明細の正規化を実行
  190.         $Carts $this->cartService->getCarts();
  191.         $this->execPurchaseFlow($Carts);
  192.         log_info('カート演算処理終了', ['operation' => $operation'product_class_id' => $productClassId]);
  193.         return $this->redirectToRoute('cart');
  194.     }
  195.     /**
  196.      * カートをロック状態に設定し、購入確認画面へ遷移する.
  197.      *
  198.      * @Route("/cart/buystep/{cart_key}", name="cart_buystep", requirements={"cart_key" = "[a-zA-Z0-9]+[_][\x20-\x7E]+"}, methods={"GET"})
  199.      */
  200.     public function buystep(Request $request$cart_key)
  201.     {
  202.         $Carts $this->cartService->getCart();
  203.         if (!is_object($Carts)) {
  204.             return $this->redirectToRoute('cart');
  205.         }
  206.         // FRONT_CART_BUYSTEP_INITIALIZE
  207.         $event = new EventArgs(
  208.             [],
  209.             $request
  210.         );
  211.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_INITIALIZE);
  212.         $this->cartService->setPrimary($cart_key);
  213.         $this->cartService->save();
  214.         // FRONT_CART_BUYSTEP_COMPLETE
  215.         $event = new EventArgs(
  216.             [],
  217.             $request
  218.         );
  219.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_COMPLETE);
  220.         if ($event->hasResponse()) {
  221.             return $event->getResponse();
  222.         }
  223.         return $this->redirectToRoute('shopping');
  224.     }
  225. }