custom/plugins/WbfkOffer/src/Subscriber/CartModeToggle.php line 41

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Wbfk\Offer\Subscriber;
  4. use Shopware\Core\Checkout\Cart\Event\CartChangedEvent;
  5. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  6. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  7. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Symfony\Component\HttpFoundation\RequestStack;
  10. use Wbfk\Offer\Core\Checkout\Cart\Custom\CartMode;
  11. use Wbfk\Offer\Storefront\Controller\CartModeChangeRoute;
  12. class CartModeToggle implements EventSubscriberInterface
  13. {
  14.     public function __construct(
  15.         private readonly RequestStack $requestStack,
  16.         private readonly CartModeChangeRoute $cartModeChangeRoute
  17.     ) {
  18.     }
  19.     public static function getSubscribedEvents(): array
  20.     {
  21.         return [
  22.             CartChangedEvent::class => 'setCartModeToRedirectParameters',
  23.             OffcanvasCartPageLoadedEvent::class => 'toggleCartModeOnOffcanvasCart',
  24.             CheckoutCartPageLoadedEvent::class => 'toggleCartModeBasedOnRequestSource',
  25.         ];
  26.     }
  27.     /**
  28.      * From the product detail page, when a user adds a product to cart, the cart should be in cart mode,
  29.      * but if the user adds a product to offer, the cart should be in offer mode.
  30.      * Switch to modes based on the request parameter cartMode
  31.      *
  32.      * @param OffcanvasCartPageLoadedEvent $event
  33.      * @return void
  34.      */
  35.     public function toggleCartModeOnOffcanvasCart(OffcanvasCartPageLoadedEvent $event): void
  36.     {
  37.         $requestedCartMode $this->requestStack->getCurrentRequest()?->get('cartMode'null);
  38.         if (!$requestedCartMode) {
  39.             return;
  40.         }
  41.         $cart $event->getPage()->getCart();
  42.         /** @var ?CartMode $cartMode */
  43.         $cartMode $cart->getExtension('cartMode');
  44.         $currentCartMode $cartMode?->getSelectedCartMode();
  45.         if ($currentCartMode === $requestedCartMode) {
  46.             return;
  47.         }
  48.         $requestDataBag = new RequestDataBag(['cartMode' => $requestedCartMode]);
  49.         $cartResponse $this->cartModeChangeRoute->change($requestDataBag$event->getPage()->getCart(), $event->getSalesChannelContext());
  50.         $event->getPage()->setCart($cartResponse->getCart());
  51.     }
  52.     /**
  53.      *  When a user visits checkout/cart, checkout/confirm cart should be in cart mode
  54.      *  and visiting checkout/offer cart should be in offer mode
  55.      *  This method will switch the cart mode based on the request source
  56.      *
  57.      * @param CheckoutCartPageLoadedEvent $event
  58.      * @return void
  59.      */
  60.     public function toggleCartModeBasedOnRequestSource(CheckoutCartPageLoadedEvent $event): void
  61.     {
  62.         $currentRoute $event->getRequest()->attributes->get('_route');
  63.         if (!in_array($currentRoute, ['frontend.checkout.cart.page''frontend.checkout.confirm.page''frontend.wbfk-offer.checkout.offer.page'])) {
  64.             return;
  65.         }
  66.         $expectedCartMode $currentRoute === 'frontend.wbfk-offer.checkout.offer.page' 'offer' 'cart';
  67.         /** @var ?CartMode $cartMode */
  68.         $cartMode $event->getPage()->getCart()->getExtension('cartMode');
  69.         if ($cartMode?->getSelectedCartMode() === $expectedCartMode) {
  70.             return;
  71.         }
  72.         $requestDataBag = new RequestDataBag(['cartMode' => $expectedCartMode]);
  73.         $cartResponse $this->cartModeChangeRoute->change($requestDataBag$event->getPage()->getCart(), $event->getSalesChannelContext());
  74.         $event->getPage()->setCart($cartResponse->getCart());
  75.     }
  76.     /**
  77.      *  From PDP add to cart/ add to offer button is handled by js plugin.
  78.      *  During adding to cart/ add to offer, offcanvas redirect is set by the plugin, and we will have to extend the plugin to set the cart mode.
  79.      *  To avoid extending the plugin, we pass cartMode as part of add to cart form data.
  80.      *  Then force the cart mode to be part of redirect parameters.
  81.      *  Check: custom/plugins/WbfkThemeMMedientechnik/src/Resources/views/storefront/component/buy-widget/buy-widget-form.html.twig
  82.      *
  83.      * @param CartChangedEvent $event
  84.      * @return void
  85.      */
  86.     public function setCartModeToRedirectParameters(CartChangedEvent $event): void
  87.     {
  88.         $currentRequest $this->requestStack->getCurrentRequest();
  89.         if (!$currentRequest || !$currentRequest->get('cartMode')) {
  90.             return;
  91.         }
  92.         $params $currentRequest->get('redirectParameters');
  93.         if (is_string($params)) {
  94.             $params json_decode($paramstrue);
  95.         }
  96.         if (empty($params)) {
  97.             $params = [];
  98.         }
  99.         $requestedCartMode $currentRequest->get('cartMode');
  100.         $cart $event->getCart();
  101.         /** @var ?CartMode $cartMode */
  102.         $cartMode $cart->getExtension('cartMode');
  103.         if ($cartMode?->getSelectedCartMode() === $requestedCartMode) {
  104.             return;
  105.         }
  106.         $params['cartMode'] = $requestedCartMode;
  107.         $currentRequest->attributes->set('redirectParameters'json_encode($params));
  108.     }
  109. }