<?php declare(strict_types=1);namespace Nxs\NxsCoreFixes\Communication\Subscriber;use Shopware\Core\Checkout\Cart\Cart;use Shopware\Core\Checkout\Cart\LineItem\LineItem;use Shopware\Core\Checkout\Cart\SalesChannel\CartService;use Shopware\Core\Checkout\Promotion\Cart\Error\PromotionNotFoundError;use Shopware\Core\Checkout\Promotion\Cart\Extension\CartExtension;use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;use Shopware\Storefront\Page\PageLoadedEvent;use Symfony\Component\EventDispatcher\EventSubscriberInterface;class CartSubscriber implements EventSubscriberInterface{ /** * @var $cartService */ private $cartService; public function __construct(CartService $cartService) { $this->cartService = $cartService; } public static function getSubscribedEvents() { return [ OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPageLoaded', CheckoutCartPageLoadedEvent::class => 'onCartPageLoaded', CheckoutConfirmPageLoadedEvent::class => 'onConfirmPageLoaded' ]; } public function onOffcanvasCartPageLoaded(OffcanvasCartPageLoadedEvent $event) { $page = $event->getPage(); $lineItems = $page->getCart()->getLineItems(); $promotions = 0; foreach ($lineItems as $lineItem) { if($lineItem->getType() === LineItem::PROMOTION_LINE_ITEM_TYPE) { $promotions++; } } $productCount = count($lineItems) - $promotions; $page->assign(['promotionCount' => $promotions, 'productCount' => $productCount]); } /** * @param CheckoutCartPageLoadedEvent $event */ public function onCartPageLoaded(CheckoutCartPageLoadedEvent $event):void { $this->removeUnmatchingPromotionCode($event); } /** * @param CheckoutConfirmPageLoadedEvent $event */ public function onConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void { $this->removeUnmatchingPromotionCode($event); } private function getExtension(Cart $cart): CartExtension { if (!$cart->hasExtension(CartExtension::KEY)) { $cart->addExtension(CartExtension::KEY, new CartExtension()); } /** @var CartExtension $extension */ $extension = $cart->getExtension(CartExtension::KEY); return $extension; } /** * @param PageLoadedEvent $event */ private function removeUnmatchingPromotionCode(PageLoadedEvent $event): void { $page = $event->getPage(); $salesChannelContext = $event->getSalesChannelContext(); /** @var Cart $cart */ $cart = $page->getCart(); $errorFound = false; $errors = $cart->getErrors(); foreach ($errors as $error) { if ($error instanceof PromotionNotFoundError) { $code = $error->getCode(); $extension = $this->getExtension($cart); $extension->removeCode($code); $errors->remove($error->getId()); $cart->addExtension(CartExtension::KEY, $extension); $errorFound = true; } } if($errorFound) { $cart->setErrors($errors); $this->cartService->setCart($cart); $this->cartService->recalculate($cart, $salesChannelContext); $page->setCart($cart); } }}