app/Customize/Controller/CustomCartController.php line 119

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