app/Customize/Controller/CartController.php line 66

Open in your IDE?
  1. <?php
  2. namespace Customize\Controller;
  3. use Eccube\Controller\AbstractController;
  4. use Eccube\Entity\Cart;
  5. use Eccube\Entity\CartItem;
  6. use Eccube\Repository\BaseInfoRepository;
  7. use Eccube\Repository\CartItemRepository;
  8. use Eccube\Service\CartService;
  9. use Eccube\Service\OrderHelper;
  10. use Eccube\Service\PurchaseFlow\PurchaseContext;
  11. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  12. use Plugin\RelatedProduct42\Repository\RelatedProductRepository;
  13. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. class CartController extends AbstractController
  17. {
  18.     /**
  19.      * @var CartItemRepository
  20.      */
  21.     protected $cartItemRepository;
  22.     /**
  23.      * @var CartService
  24.      */
  25.     protected $cartService;
  26.     /**
  27.      * @var PurchaseFlow
  28.      */
  29.     protected $purchaseFlow;
  30.     /**
  31.      * @var BaseInfo
  32.      */
  33.     protected $baseInfo;
  34.     /**
  35.      * @var RelatedProductRepository
  36.      */
  37.     protected $relatedProductRepository;
  38.     public function __construct(
  39.         CartItemRepository $cartItemRepository,
  40.         CartService $cartService,
  41.         PurchaseFlow $purchaseFlow,
  42.         BaseInfoRepository $baseInfoRepository,
  43.         RelatedProductRepository $relatedProductRepository
  44.     ) {
  45.         $this->cartItemRepository $cartItemRepository;
  46.         $this->cartService $cartService;
  47.         $this->purchaseFlow $purchaseFlow;
  48.         $this->baseInfo $baseInfoRepository->get();
  49.         $this->relatedProductRepository $relatedProductRepository;
  50.     }
  51.     /**
  52.      * カート画面.
  53.      *
  54.      * @Route("/cart", name="cart", methods={"GET"})
  55.      * @Template("Cart/index.twig")
  56.      */
  57.     public function index(Request $request)
  58.     {
  59.         // カートを取得して明細の正規化を実行
  60.         $Carts $this->cartService->getCarts();
  61.         $this->execPurchaseFlow($Carts);
  62.         // TODO itemHolderから取得できるように
  63.         $least = [];
  64.         $quantity = [];
  65.         $isDeliveryFree = [];
  66.         $totalPrice 0;
  67.         $totalQuantity 0;
  68.         $product_ids = [];
  69.         foreach ($Carts as $Cart) {
  70.             $quantity[$Cart->getCartKey()] = 0;
  71.             $isDeliveryFree[$Cart->getCartKey()] = false;
  72.             if ($this->baseInfo->getDeliveryFreeQuantity()) {
  73.                 if ($this->baseInfo->getDeliveryFreeQuantity() > $Cart->getQuantity()) {
  74.                     $quantity[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeQuantity() - $Cart->getQuantity();
  75.                 } else {
  76.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  77.                 }
  78.             }
  79.             if ($this->baseInfo->getDeliveryFreeAmount()) {
  80.                 if (!$isDeliveryFree[$Cart->getCartKey()] && $this->baseInfo->getDeliveryFreeAmount() <= $Cart->getTotalPrice()) {
  81.                     $isDeliveryFree[$Cart->getCartKey()] = true;
  82.                 } else {
  83.                     $least[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeAmount() - $Cart->getTotalPrice();
  84.                 }
  85.             }
  86.             $totalPrice += $Cart->getTotalPrice();
  87.             $totalQuantity += $Cart->getQuantity();
  88.             foreach ($Cart->getItems() as $CartItem) {
  89.                 $product_ids[] = $CartItem->getProductClass()->getProduct()->getId();
  90.             }
  91.         }
  92.         // カートが分割された時のセッション情報を削除
  93.         $request->getSession()->remove(OrderHelper::SESSION_CART_DIVIDE_FLAG);
  94.         // 関連商品取得
  95.         $relatedProductQb $this->relatedProductRepository->createQueryBuilder('rp');
  96.         $RelatedProducts $relatedProductQb
  97.             ->select('rp''cp')
  98.             ->leftJoin('rp.ChildProduct''cp')
  99.             ->where($relatedProductQb->expr()->in('rp.Product'':product_ids'))
  100.             // カート内の商品が関連商品に含まれないようにする
  101.             ->andWhere($relatedProductQb->expr()->notIn('rp.ChildProduct'':product_ids'))
  102.             ->setParameter('product_ids'$product_ids)
  103.             ->addOrderBy('rp.id''DESC')
  104.             ->getQuery()
  105.             ->getResult();
  106.         $uniqueChildProductIds = [];
  107.         $filteredRelatedProducts = [];
  108.         // 配列をループしてChildProductが重複してる場合その値を取り除く
  109.         foreach ($RelatedProducts as $relatedProduct) {
  110.             $childProductId $relatedProduct->getChildProduct()->getId();
  111.             if (!in_array($childProductId$uniqueChildProductIds)) {
  112.                 $uniqueChildProductIds[] = $childProductId;
  113.                 $filteredRelatedProducts[] = $relatedProduct;
  114.             }
  115.         }
  116.         return [
  117.             'totalPrice' => $totalPrice,
  118.             'totalQuantity' => $totalQuantity,
  119.             // 空のカートを削除し取得し直す
  120.             'Carts' => $this->cartService->getCarts(true),
  121.             'least' => $least,
  122.             'quantity' => $quantity,
  123.             'is_delivery_free' => $isDeliveryFree,
  124.             'RelatedProducts' => $filteredRelatedProducts,
  125.         ];
  126.     }
  127.     /**
  128.      * @param $Carts
  129.      *
  130.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
  131.      */
  132.     protected function execPurchaseFlow($Carts)
  133.     {
  134.         /** @var PurchaseFlowResult[] $flowResults */
  135.         $flowResults array_map(function ($Cart) {
  136.             $purchaseContext = new PurchaseContext($Cart$this->getUser());
  137.             return $this->purchaseFlow->validate($Cart$purchaseContext);
  138.         }, $Carts);
  139.         // 復旧不可のエラーが発生した場合はカートをクリアして再描画
  140.         $hasError false;
  141.         foreach ($flowResults as $result) {
  142.             if ($result->hasError()) {
  143.                 $hasError true;
  144.                 foreach ($result->getErrors() as $error) {
  145.                     $this->addRequestError($error->getMessage());
  146.                 }
  147.             }
  148.         }
  149.         if ($hasError) {
  150.             $this->cartService->clear();
  151.             return $this->redirectToRoute('cart');
  152.         }
  153.         $this->cartService->save();
  154.         foreach ($flowResults as $index => $result) {
  155.             foreach ($result->getWarning() as $warning) {
  156.                 if ($Carts[$index]->getItems()->count() > 0) {
  157.                     $cart_key $Carts[$index]->getCartKey();
  158.                     $this->addRequestError($warning->getMessage(), "front.cart.${cart_key}");
  159.                 } else {
  160.                     // キーが存在しない場合はグローバルにエラーを表示する
  161.                     $this->addRequestError($warning->getMessage());
  162.                 }
  163.             }
  164.         }
  165.         return null;
  166.     }
  167.     /**
  168.      * カート内の名入れのboolean値をプルダウンに応じて制御するメソッド
  169.      *
  170.      * @Route(
  171.      *     path="/cart/{operation}/{cartItemId}",
  172.      *     name="cart_handle_naire",
  173.      *     methods={"PUT"},
  174.      *     requirements={
  175.      *          "operation": "naire_true|naire_false",
  176.      *          "cartItemId": "\d+"
  177.      *     }
  178.      * )
  179.      */
  180.     public function handleCartNaire($operation$cartItemId)
  181.     {
  182.         log_info('カート名入れ操作開始', ['operation' => $operation'cart_item_id' => $cartItemId]);
  183.         $this->isTokenValid();
  184.         /** @var CartItem $CartItem */
  185.         $CartItem $this->cartItemRepository->find($cartItemId);
  186.         if (is_null($CartItem)) {
  187.             log_info('商品が存在しないため、カート画面へredirect', ['operation' => $operation'cart_item_id' => $cartItemId]);
  188.             return $this->redirectToRoute('cart');
  189.         }
  190.         switch ($operation) {
  191.             case 'naire_true':
  192.                 $CartItem->setNaire(true);
  193.                 break;
  194.             case 'naire_false':
  195.                 $CartItem->setNaire(false);
  196.                 break;
  197.         }
  198.         $this->cartService->refreshCarts();
  199.         // カートを取得して明細の正規化を実行
  200.         $Carts $this->cartService->getCarts();
  201.         $this->execPurchaseFlow($Carts);
  202.         log_info('カート名入れ処理終了', ['operation' => $operation'cart_item_id' => $cartItemId]);
  203.         return $this->redirectToRoute('cart');
  204.     }
  205. }