app/Customize/Controller/CartController.php line 85

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\Event\EccubeEvents;
  17. use Eccube\Event\EventArgs;
  18. use Eccube\Repository\BaseInfoRepository;
  19. use Eccube\Repository\ProductClassRepository;
  20. use Eccube\Repository\ProductRepository;
  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. use Symfony\Component\HttpFoundation\JsonResponse;
  30. class CartController extends AbstractController
  31. {
  32.     /**
  33.      * @var ProductClassRepository
  34.      */
  35.     protected $productClassRepository;
  36.     protected $productRepository;
  37.     /**
  38.      * @var CartService
  39.      */
  40.     protected $cartService;
  41.     /**
  42.      * @var PurchaseFlow
  43.      */
  44.     protected $purchaseFlow;
  45.     /**
  46.      * @var BaseInfo
  47.      */
  48.     protected $baseInfo;
  49.     /**
  50.      * CartController constructor.
  51.      *
  52.      * @param ProductClassRepository $productClassRepository
  53.      * @param CartService $cartService
  54.      * @param PurchaseFlow $cartPurchaseFlow
  55.      * @param BaseInfoRepository $baseInfoRepository
  56.      */
  57.     public function __construct(
  58.         ProductClassRepository $productClassRepository,
  59.         ProductRepository $productRepository,
  60.         CartService $cartService,
  61.         PurchaseFlow $cartPurchaseFlow,
  62.         BaseInfoRepository $baseInfoRepository
  63.     ) {
  64.         $this->productClassRepository $productClassRepository;
  65.         $this->productRepository $productRepository;
  66.         $this->cartService $cartService;
  67.         $this->purchaseFlow $cartPurchaseFlow;
  68.         $this->baseInfo $baseInfoRepository->get();
  69.     }
  70.     /**
  71.      * カート画面.
  72.      *
  73.      * @Route("/cart", name="cart", methods={"GET"})
  74.      * @Template("Cart/index.twig")
  75.      */
  76.     public function index(Request $request)
  77.     {
  78.         // カートを取得して明細の正規化を実行
  79.         $Carts $this->cartService->getCarts();
  80.         $this->execPurchaseFlow($Carts);
  81.         // TODO itemHolderから取得できるように
  82.         $least = [];
  83.         $quantity = [];
  84.         $isDeliveryFree = [];
  85.         $totalPrice 0;
  86.         $totalQuantity 0;
  87.         $is_construction_only true;
  88.         $loanProducts = [];
  89.         foreach ($Carts as $Cart) {
  90.             $quantity[$Cart->getCartKey()] = 0;
  91.             $isDeliveryFree[$Cart->getCartKey()] = false;
  92.             if ($this->baseInfo->getDeliveryFreeQuantity()) {
  93.                 if ($this->baseInfo->getDeliveryFreeQuantity() > $Cart->getQuantity()) {
  94.                     $quantity[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeQuantity() - $Cart->getQuantity();
  95.                 } else {
  96.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  97.                 }
  98.             }
  99.             if ($this->baseInfo->getDeliveryFreeAmount()) {
  100.                 if (!$isDeliveryFree[$Cart->getCartKey()] && $this->baseInfo->getDeliveryFreeAmount() <= $Cart->getTotalPrice()) {
  101.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  102.                 } else {
  103.                     $least[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeAmount() - $Cart->getTotalPrice();
  104.                 }
  105.             }
  106.             $totalPrice += $Cart->getTotalPrice();
  107.             $totalQuantity += $Cart->getQuantity();
  108.             // 工事のみ判断
  109.             foreach ($Cart->getCartItems() as $CartItem) {
  110.                 if ($CartItem->getProductClass()->getProduct()->getId() != 1289) {
  111.                     $is_construction_only false;
  112.                 }
  113.                 $product $CartItem->getProductClass()->getProduct();
  114.                 $categories $product->getProductCategories();
  115.                 $isLoan false
  116.                 foreach ($categories as $category) {
  117.                     if ($category->getCategory()->getId() == 118) {
  118.                         $isLoan true
  119.                         break;
  120.                     }
  121.                 }
  122.                 if ($isLoan) {
  123.                     $loanProducts[] = $product
  124.                 }
  125.             }
  126.         }
  127.         // カートが分割された時のセッション情報を削除
  128.         $request->getSession()->remove(OrderHelper::SESSION_CART_DIVIDE_FLAG);
  129.         return [
  130.             'totalPrice' => $totalPrice,
  131.             'totalQuantity' => $totalQuantity,
  132.             // 空のカートを削除し取得し直す
  133.             'Carts' => $this->cartService->getCarts(true),
  134.             'least' => $least,
  135.             'quantity' => $quantity,
  136.             'is_delivery_free' => $isDeliveryFree,
  137.             'is_construction_only' => $is_construction_only,
  138.             'loanProducts' => $loanProducts,
  139.         ];
  140.     }
  141.     /**
  142.      * @param $Carts
  143.      *
  144.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
  145.      */
  146.     protected function execPurchaseFlow($Carts)
  147.     {
  148.         /** @var PurchaseFlowResult[] $flowResults */
  149.         $flowResults array_map(function ($Cart) {
  150.             $purchaseContext = new PurchaseContext($Cart$this->getUser());
  151.             return $this->purchaseFlow->validate($Cart$purchaseContext);
  152.         }, $Carts);
  153.         // 復旧不可のエラーが発生した場合はカートをクリアして再描画
  154.         $hasError false;
  155.         foreach ($flowResults as $result) {
  156.             if ($result->hasError()) {
  157.                 $hasError true;
  158.                 foreach ($result->getErrors() as $error) {
  159.                     $this->addRequestError($error->getMessage());
  160.                 }
  161.             }
  162.         }
  163.         if ($hasError) {
  164.             $this->cartService->clear();
  165.             return $this->redirectToRoute('cart');
  166.         }
  167.         $this->cartService->save();
  168.         foreach ($flowResults as $index => $result) {
  169.             foreach ($result->getWarning() as $warning) {
  170.                 if ($Carts[$index]->getItems()->count() > 0) {
  171.                     $cart_key $Carts[$index]->getCartKey();
  172.                     $this->addRequestError($warning->getMessage(), "front.cart.${cart_key}");
  173.                 } else {
  174.                     // キーが存在しない場合はグローバルにエラーを表示する
  175.                     $this->addRequestError($warning->getMessage());
  176.                 }
  177.             }
  178.         }
  179.         return null;
  180.     }
  181.     /**
  182.      * カート明細の加算/減算/削除を行う.
  183.      *
  184.      * - 加算
  185.      *      - 明細の個数を1増やす
  186.      * - 減算
  187.      *      - 明細の個数を1減らす
  188.      *      - 個数が0になる場合は、明細を削除する
  189.      * - 削除
  190.      *      - 明細を削除する
  191.      *
  192.      * @Route(
  193.      *     path="/cart/{operation}/{productClassId}",
  194.      *     name="cart_handle_item",
  195.      *     methods={"PUT"},
  196.      *     requirements={
  197.      *          "operation": "up|down|remove",
  198.      *          "productClassId": "\d+"
  199.      *     }
  200.      * )
  201.      */
  202.     public function handleCartItem($operation$productClassId)
  203.     {
  204.         // 工事費用データを削除
  205.         $Product $this->productRepository->find(1289);
  206.         $Carts $this->cartService->getCarts();
  207.         foreach ($Carts as $Cart) {
  208.             foreach ($Cart->getCartItems() as $CartItem) {
  209.                 if ($CartItem->getProductClass()->getProduct() == $Product) {
  210.                     $this->cartService->removeProduct($CartItem->getProductClass());
  211.                 }
  212.             }
  213.         }
  214.         
  215.         log_info('カート明細操作開始', ['operation' => $operation'product_class_id' => $productClassId]);
  216.         $this->isTokenValid();
  217.         /** @var ProductClass $ProductClass */
  218.         $ProductClass $this->productClassRepository->find($productClassId);
  219.         if (is_null($ProductClass)) {
  220.             log_info('商品が存在しないため、カート画面へredirect', ['operation' => $operation'product_class_id' => $productClassId]);
  221.             return $this->redirectToRoute('cart');
  222.         }
  223.         // 明細の増減・削除
  224.         switch ($operation) {
  225.             case 'up':
  226.                 $this->cartService->addProduct($ProductClass1);
  227.                 break;
  228.             case 'down':
  229.                 $this->cartService->addProduct($ProductClass, -1);
  230.                 break;
  231.             case 'remove':
  232.                 $this->cartService->removeProduct($ProductClass);
  233.                 break;
  234.         }
  235.         // カートを取得して明細の正規化を実行
  236.         $Carts $this->cartService->getCarts();
  237.         $this->execPurchaseFlow($Carts);
  238.         log_info('カート演算処理終了', ['operation' => $operation'product_class_id' => $productClassId]);
  239.         return $this->redirectToRoute('cart');
  240.     }
  241.     /**
  242.      * カートをロック状態に設定し、購入確認画面へ遷移する.
  243.      *
  244.      * @Route("/cart/buystep/{cart_key}", name="cart_buystep", requirements={"cart_key" = "[a-zA-Z0-9]+[_][\x20-\x7E]+"}, methods={"GET"})
  245.      */
  246.     public function buystep(Request $request$cart_key)
  247.     {
  248.         $Carts $this->cartService->getCart();
  249.         if (!is_object($Carts)) {
  250.             return $this->redirectToRoute('cart');
  251.         }
  252.         // FRONT_CART_BUYSTEP_INITIALIZE
  253.         $event = new EventArgs(
  254.             [],
  255.             $request
  256.         );
  257.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_INITIALIZE);
  258.         $this->cartService->setPrimary($cart_key);
  259.         $this->cartService->save();
  260.         // FRONT_CART_BUYSTEP_COMPLETE
  261.         $event = new EventArgs(
  262.             [],
  263.             $request
  264.         );
  265.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_CART_BUYSTEP_COMPLETE);
  266.         if ($event->hasResponse()) {
  267.             return $event->getResponse();
  268.         }
  269.         return $this->redirectToRoute('shopping');
  270.     }
  271.      /**
  272.      * カート明細の加算/減算/削除を行う.
  273.      *
  274.      * - 加算
  275.      *      - 明細の個数を1増やす
  276.      * - 減算
  277.      *      - 明細の個数を1減らす
  278.      *      - 個数が0になる場合は、明細を削除する
  279.      * - 削除
  280.      *      - 明細を削除する
  281.      *
  282.      * @Route(
  283.      *     path="/cart/{operation}/{productClassId}",
  284.      *     name="cart_handle_remove_item",
  285.      *     methods={"PUT"},
  286.      *     requirements={
  287.      *          "operation": "remove",
  288.      *          "productClassId": "\d+"
  289.      *     }
  290.      * )
  291.      */
  292.     public function handleRemove(Request $request$operation ,$productClassId) {
  293.         $result false;
  294.         if ($operation === 'remove') {
  295.             $result $this->cartService->removeProduct($productClassId);
  296.         }
  297.         if ($request->isXmlHttpRequest()) {
  298.             return new JsonResponse([
  299.                 'success' => $result,
  300.                 'message' => $result '商品が正常に削除されました。' '削除に失敗しました。',
  301.             ]);
  302.         }
  303.         return $this->redirectToRoute('cart');
  304.     }
  305. }