<?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);
}
}
}