src/Sylius/Bundle/ShopBundle/EventListener/OrderPromotionIntegrityChecker.php line 57

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Sylius package.
  4.  *
  5.  * (c) Paweł Jędrzejewski
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace Sylius\Bundle\ShopBundle\EventListener;
  12. use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
  13. use Sylius\Component\Core\Model\OrderInterface;
  14. use Sylius\Component\Order\SyliusCartEvents;
  15. use Sylius\Component\Promotion\Action\PromotionApplicatorInterface;
  16. use Sylius\Component\Promotion\Checker\Eligibility\PromotionEligibilityCheckerInterface;
  17. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  18. use Symfony\Component\EventDispatcher\GenericEvent;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\Routing\RouterInterface;
  21. use Webmozart\Assert\Assert;
  22. final class OrderPromotionIntegrityChecker
  23. {
  24.     /** @var PromotionEligibilityCheckerInterface */
  25.     private $promotionEligibilityChecker;
  26.     /** @var PromotionApplicatorInterface */
  27.     private $promotionApplicator;
  28.     /** @var EventDispatcherInterface */
  29.     private $eventDispatcher;
  30.     /** @var RouterInterface */
  31.     private $router;
  32.     public function __construct(
  33.         PromotionEligibilityCheckerInterface $promotionEligibilityChecker,
  34.         EventDispatcherInterface $eventDispatcher,
  35.         RouterInterface $router,
  36.         ?PromotionApplicatorInterface $promotionApplicator null
  37.     ) {
  38.         if ($promotionApplicator === null) {
  39.             @trigger_error("You need to supply an promotion applicator in order to work properly. In case you don't provide it, there will be valid cases that will fail due an incorrect recalculation.", \E_USER_DEPRECATED);
  40.         }
  41.         $this->promotionEligibilityChecker $promotionEligibilityChecker;
  42.         $this->eventDispatcher $eventDispatcher;
  43.         $this->router $router;
  44.         $this->promotionApplicator $promotionApplicator;
  45.     }
  46.     public function check(ResourceControllerEvent $event): void
  47.     {
  48.         /** @var OrderInterface $order */
  49.         $order $event->getSubject();
  50.         Assert::isInstanceOf($orderOrderInterface::class);
  51.         // we create a new promotion collection and remove them from cart
  52.         // so we can verify with original conditions (without the price being applied before check)
  53.         $promotions $order->getPromotions()->toArray();
  54.         if ($this->promotionApplicator !== null) {
  55.             foreach ($promotions as $promotion) {
  56.                 $this->promotionApplicator->revert($order$promotion);
  57.                 $order->removePromotion($promotion);
  58.             }
  59.         }
  60.         foreach ($promotions as $promotion) {
  61.             if (!$this->promotionEligibilityChecker->isEligible($order$promotion)) {
  62.                 $event->stop(
  63.                     'sylius.order.promotion_integrity',
  64.                     ResourceControllerEvent::TYPE_ERROR,
  65.                     ['%promotionName%' => $promotion->getName()]
  66.                 );
  67.                 $event->setResponse(new RedirectResponse($this->router->generate('sylius_shop_checkout_complete')));
  68.                 $this->eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($order));
  69.                 break;
  70.             }
  71.             if ($this->promotionApplicator !== null) {
  72.                 $this->promotionApplicator->apply($order$promotion);
  73.             }
  74.         }
  75.     }
  76. }