src/Eccube/Controller/CartController.php line 136

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