vendor/shopware/core/Checkout/Promotion/Subscriber/Storefront/StorefrontCartSubscriber.php line 53

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Promotion\Subscriber\Storefront;
  3. use Shopware\Core\Checkout\Cart\Cart;
  4. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  5. use Shopware\Core\Checkout\Cart\Event\LineItemAddedEvent;
  6. use Shopware\Core\Checkout\Cart\Event\LineItemRemovedEvent;
  7. use Shopware\Core\Checkout\Cart\Exception\LineItemNotFoundException;
  8. use Shopware\Core\Checkout\Cart\Exception\LineItemNotRemovableException;
  9. use Shopware\Core\Checkout\Cart\Exception\PayloadKeyNotFoundException;
  10. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  11. use Shopware\Core\Checkout\Promotion\Aggregate\PromotionDiscount\PromotionDiscountEntity;
  12. use Shopware\Core\Checkout\Promotion\Cart\Extension\CartExtension;
  13. use Shopware\Core\Checkout\Promotion\Cart\PromotionProcessor;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\Session\Session;
  16. class StorefrontCartSubscriber implements EventSubscriberInterface
  17. {
  18.     public const SESSION_KEY_PROMOTION_CODES 'cart-promotion-codes';
  19.     /**
  20.      * @var Session
  21.      */
  22.     private $session;
  23.     public function __construct(Session $session)
  24.     {
  25.         $this->session $session;
  26.     }
  27.     public static function getSubscribedEvents(): array
  28.     {
  29.         return [
  30.             LineItemAddedEvent::class => 'onLineItemAdded',
  31.             LineItemRemovedEvent::class => 'onLineItemRemoved',
  32.             CheckoutOrderPlacedEvent::class => 'resetCodes',
  33.         ];
  34.     }
  35.     public function resetCodes(): void
  36.     {
  37.         $this->session->set(self::SESSION_KEY_PROMOTION_CODES, []);
  38.     }
  39.     /**
  40.      * This function is called whenever a new line item has been
  41.      * added to the cart from within the controllers.
  42.      * We verify if we have a placeholder line item for a promotion
  43.      * and add that code to our extension list.
  44.      */
  45.     public function onLineItemAdded(LineItemAddedEvent $event): void
  46.     {
  47.         if ($event->getLineItem()->getType() === PromotionProcessor::LINE_ITEM_TYPE) {
  48.             $code $event->getLineItem()->getReferencedId();
  49.             if ($code !== null && $code !== '') {
  50.                 $this->addCode($code$event->getCart());
  51.             }
  52.         }
  53.     }
  54.     /**
  55.      * This function is called whenever a line item is being removed
  56.      * from the cart from within a controller.
  57.      * We verify if it is a promotion item, and also remove that
  58.      * code from our extension, if existing.
  59.      */
  60.     public function onLineItemRemoved(LineItemRemovedEvent $event): void
  61.     {
  62.         $cart $event->getCart();
  63.         if ($event->getLineItem()->getType() !== PromotionProcessor::LINE_ITEM_TYPE) {
  64.             return;
  65.         }
  66.         $lineItem $event->getLineItem();
  67.         $code $lineItem->getReferencedId();
  68.         if (!empty($code)) {
  69.             // promotion with code
  70.             $this->checkFixedDiscountItems($cart$lineItem);
  71.             $this->removeCode($code$cart);
  72.             return;
  73.         }
  74.         // the user wants to remove an automatic added
  75.         // promotions, so lets do this
  76.         if ($lineItem->hasPayloadValue('promotionId')) {
  77.             $promotionId = (string) $lineItem->getPayloadValue('promotionId');
  78.             $this->blockPromotion($promotionId$cart);
  79.         }
  80.     }
  81.     /**
  82.      * @throws LineItemNotFoundException
  83.      * @throws LineItemNotRemovableException
  84.      * @throws PayloadKeyNotFoundException
  85.      */
  86.     private function checkFixedDiscountItems(Cart $cartLineItem $lineItem): void
  87.     {
  88.         $lineItems $cart->getLineItems()->filterType(PromotionProcessor::LINE_ITEM_TYPE);
  89.         if ($lineItems->count() < 1) {
  90.             return;
  91.         }
  92.         if (!$lineItem->hasPayloadValue('discountType')) {
  93.             return;
  94.         }
  95.         if ($lineItem->getPayloadValue('discountType') !== PromotionDiscountEntity::TYPE_FIXED_UNIT) {
  96.             return;
  97.         }
  98.         if (!$lineItem->hasPayloadValue('discountId')) {
  99.             return;
  100.         }
  101.         $discountId $lineItem->getPayloadValue('discountId');
  102.         $removeThisDiscounts $lineItems->filter(static function (LineItem $lineItem) use ($discountId) {
  103.             return $lineItem->hasPayloadValue('discountId') && $lineItem->getPayloadValue('discountId') === $discountId;
  104.         });
  105.         foreach ($removeThisDiscounts as $discountItem) {
  106.             $cart->remove($discountItem->getId());
  107.         }
  108.     }
  109.     private function addCode(string $codeCart $cart): void
  110.     {
  111.         $extension $this->getExtension($cart);
  112.         $extension->addCode($code);
  113.         $cart->addExtension(CartExtension::KEY$extension);
  114.     }
  115.     private function removeCode(string $codeCart $cart): void
  116.     {
  117.         $extension $this->getExtension($cart);
  118.         $extension->removeCode($code);
  119.         $cart->addExtension(CartExtension::KEY$extension);
  120.     }
  121.     private function blockPromotion(string $idCart $cart): void
  122.     {
  123.         $extension $this->getExtension($cart);
  124.         $extension->blockPromotion($id);
  125.         $cart->addExtension(CartExtension::KEY$extension);
  126.     }
  127.     private function getExtension(Cart $cart): CartExtension
  128.     {
  129.         if (!$cart->hasExtension(CartExtension::KEY)) {
  130.             $cart->addExtension(CartExtension::KEY, new CartExtension());
  131.         }
  132.         /** @var CartExtension $extension */
  133.         $extension $cart->getExtension(CartExtension::KEY);
  134.         return $extension;
  135.     }
  136. }