app/Customize/Controller/CartController.php line 85

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