vendor/store.shopware.com/zeobvabandonedcart/src/Storefront/Subscriber/PageSubscriber.php line 105

Open in your IDE?
  1. <?php declare(strict_types 1);
  2. namespace Zeobv\AbandonedCart\Storefront\Subscriber;
  3. use Shopware\Storefront\Page\Account\Overview\AccountOverviewPageLoadedEvent;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\RequestStack;
  7. use Shopware\Core\Checkout\Cart\Cart;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  10. use Shopware\Core\Framework\Uuid\Uuid;
  11. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  12. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  13. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  15. use Shopware\Storefront\Page\Checkout\Register\CheckoutRegisterPageLoadedEvent;
  16. use Shopware\Core\Checkout\Cart\Event\AfterLineItemAddedEvent;
  17. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  18. use Shopware\Core\Checkout\Cart\Event\AfterLineItemRemovedEvent;
  19. use Shopware\Core\Checkout\Cart\Event\AfterLineItemQuantityChangedEvent;
  20. use Zeobv\AbandonedCart\Pagelet\AbandonedCartReminder\Account\AbandonedCartReminderAccountPageletLoader;
  21. use Zeobv\AbandonedCart\Pagelet\AbandonedCartReminder\Account\AbandonedCartReminderPagelet;
  22. use Zeobv\AbandonedCart\Service\AbandonedCartService;
  23. use Zeobv\AbandonedCart\Service\CartService;
  24. /**
  25.  * Class PageSubscriber
  26.  *
  27.  * @package Zeobv\AbandonedCart\Subscriber
  28.  */
  29. class PageSubscriber implements EventSubscriberInterface
  30. {
  31.     /**
  32.      * @var EntityRepositoryInterface
  33.      */
  34.     protected $abandonedCartRepository;
  35.     /**
  36.      * @var AbandonedCartService
  37.      */
  38.     protected $abandonedCartService;
  39.     /**
  40.      * @var EntityRepositoryInterface
  41.      */
  42.     protected $salesChannelDomainRepository;
  43.     /**
  44.      * @var Request|null
  45.      */
  46.     protected $currentRequest;
  47.     /**
  48.      * @var CartService
  49.      */
  50.     protected $cartService;
  51.     protected AbandonedCartReminderAccountPageletLoader $abandonedCartReminderAccountPageletLoader;
  52.     /**
  53.      * @param RequestStack                              $requestStack
  54.      * @param EntityRepositoryInterface                 $abandonedCartRepository
  55.      * @param EntityRepositoryInterface                 $salesChannelDomainRepository
  56.      * @param AbandonedCartService                      $abandonedCartService
  57.      * @param CartService                               $cartService
  58.      * @param AbandonedCartReminderAccountPageletLoader $abandonedCartReminderAccountPageletLoader
  59.      */
  60.     public function __construct(
  61.         RequestStack $requestStack,
  62.         EntityRepositoryInterface $abandonedCartRepository,
  63.         EntityRepositoryInterface $salesChannelDomainRepository,
  64.         AbandonedCartService $abandonedCartService,
  65.         CartService $cartService,
  66.         AbandonedCartReminderAccountPageletLoader $abandonedCartReminderAccountPageletLoader
  67.     )
  68.     {
  69.         $this->currentRequest $requestStack->getCurrentRequest();
  70.         $this->abandonedCartRepository $abandonedCartRepository;
  71.         $this->abandonedCartService $abandonedCartService;
  72.         $this->cartService $cartService;
  73.         $this->salesChannelDomainRepository $salesChannelDomainRepository;
  74.         $this->abandonedCartReminderAccountPageletLoader $abandonedCartReminderAccountPageletLoader;
  75.     }
  76.     /**
  77.      * @return array
  78.      */
  79.     public static function getSubscribedEvents(): array
  80.     {
  81.         return [
  82.             AccountOverviewPageLoadedEvent::class => 'onAccountOverviewLoaded',
  83.             AfterLineItemAddedEvent::class => 'onLineItemAdded',
  84.             AfterLineItemQuantityChangedEvent::class => 'onLineItemQtyChanged',
  85.             AfterLineItemRemovedEvent::class => 'onLineItemRemoved',
  86.             OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPageLoaded',
  87.             CheckoutRegisterPageLoadedEvent::class => 'onCheckoutRegisterPageLoaded',
  88.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmPageLoaded',
  89. //            CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoaded',
  90.         ];
  91.     }
  92.     /**
  93.      * @param AccountOverviewPageLoadedEvent $event
  94.      */
  95.     public function onAccountOverviewLoaded(AccountOverviewPageLoadedEvent $event): void
  96.     {
  97.         $event->getPage()->addExtension(
  98.             AbandonedCartReminderPagelet::EXTENSION_NAME,
  99.             $this->abandonedCartReminderAccountPageletLoader->load(
  100.                 $event->getPage()->getCustomer()
  101.             )
  102.         );
  103.     }
  104.     /**
  105.      * @param AfterLineItemAddedEvent $event
  106.      */
  107.     public function onLineItemAdded(AfterLineItemAddedEvent $event): void
  108.     {
  109.         $cart $event->getCart();
  110.         $salesChannelContext $event->getSalesChannelContext();
  111.         if ($this->currentRequest->attributes->get('sw-domain-id')) {
  112.             $this->upsertAbandonedCart($cart$salesChannelContexttrue);
  113.         }
  114.     }
  115.     /**
  116.      * @param AfterLineItemRemovedEvent $event
  117.      */
  118.     public function onLineItemRemoved(AfterLineItemRemovedEvent $event): void
  119.     {
  120.         $cart $event->getCart();
  121.         $salesChannelContext $event->getSalesChannelContext();
  122.         if ($this->currentRequest->attributes->get('sw-domain-id')) {
  123.             $this->upsertAbandonedCart($cart$salesChannelContexttrue);
  124.         }
  125.     }
  126.     /**
  127.      * @param AfterLineItemQuantityChangedEvent $event
  128.      */
  129.     public function onLineItemQtyChanged(AfterLineItemQuantityChangedEvent $event): void
  130.     {
  131.         $cart $event->getCart();
  132.         $salesChannelContext $event->getSalesChannelContext();
  133.         if ($this->currentRequest->attributes->get('sw-domain-id')) {
  134.             $this->upsertAbandonedCart($cart$salesChannelContexttrue);
  135.         }
  136.     }
  137.     /**
  138.      * @param OffcanvasCartPageLoadedEvent $event
  139.      */
  140.     public function onOffcanvasCartPageLoaded(OffcanvasCartPageLoadedEvent $event): void
  141.     {
  142.         $cart $event->getPage()->getCart();
  143.         $this->abandonedCartService->saveCart($cart$event->getSalesChannelContext());
  144.         $this->upsertAbandonedCart($cart$event->getSalesChannelContext());
  145.     }
  146.     /**
  147.      * @param CheckoutConfirmPageLoadedEvent $event
  148.      */
  149.     public function onCheckoutConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void
  150.     {
  151.         $cart $event->getPage()->getCart();
  152.         $this->abandonedCartService->saveCart($cart$event->getSalesChannelContext());
  153.         $this->upsertAbandonedCart($cart$event->getSalesChannelContext());
  154.     }
  155.     /**
  156.      * @param CheckoutRegisterPageLoadedEvent $event
  157.      */
  158.     public function onCheckoutRegisterPageLoaded(CheckoutRegisterPageLoadedEvent $event): void
  159.     {
  160.         $cart $event->getPage()->getCart();
  161.         $this->abandonedCartService->saveCart($cart$event->getSalesChannelContext());
  162.         $this->upsertAbandonedCart($cart$event->getSalesChannelContext());
  163.     }
  164.     /** @deprecated see OrderSubscriber::onOrderWritten()
  165.      * @param CheckoutFinishPageLoadedEvent $event
  166.      */
  167.     public function onCheckoutFinishPageLoaded(CheckoutFinishPageLoadedEvent $event): void
  168.     {
  169.         $orderCustomer $event->getPage()->getOrder()->getOrderCustomer();
  170.         if ($orderCustomer === null) {
  171.             return;
  172.         }
  173.         $criteria = new Criteria();
  174.         $criteria->addFilter(new EqualsFilter('email'$orderCustomer->getEmail()));
  175.         $abandonedCart $this->abandonedCartRepository->search($criteria$event->getContext())->first();
  176.         if (is_null($abandonedCart)) {
  177.             return;
  178.         }
  179.         $this->abandonedCartService->resolveAbandonedCart($abandonedCart$event->getContext());
  180.     }
  181.     /**
  182.      * @param Cart                $cart
  183.      * @param SalesChannelContext $context
  184.      * @param bool                $cartShouldExist
  185.      */
  186.     protected function upsertAbandonedCart(Cart $cartSalesChannelContext $contextbool $cartShouldExist false): void
  187.     {
  188.         $customer $context->getCustomer();
  189.         if (is_null($customer)) {
  190.             return;
  191.         }
  192.         $salesChannelDomainId $this->currentRequest->attributes->get('sw-domain-id');
  193.         if (is_null($salesChannelDomainId)) {
  194.             return;
  195.         }
  196.         $criteria = new Criteria();
  197.         # Get abandoned cart by customer email to avoid abandoned cart duplication.
  198.         $criteria->addFilter(new EqualsFilter('email'$customer->getEmail()));
  199.         $cartResult $this->abandonedCartRepository->search($criteria$context->getContext());
  200.         if ($cartShouldExist && $cartResult->count() <= 0) {
  201.             return;
  202.         }
  203.         $lineItems json_encode($cart->getLineItems()->getElements());
  204.         if ($lineItems === false) {
  205.             return;
  206.         }
  207.         $lineItems json_decode($lineItemstrue);
  208.         if (empty($lineItems)) {
  209.             $id $cartResult->first() ? $cartResult->first()->getId() : null;
  210.             if ($id !== null) {
  211.                 $this->abandonedCartRepository->delete([[
  212.                     'id' => $id
  213.                 ]], $context->getContext());
  214.             }
  215.             return;
  216.         }
  217.         $data = [
  218.             'id' => $cartResult->first() ? $cartResult->first()->getId() : Uuid::randomHex(),
  219.             'cartToken' => $cart->getToken(),
  220.             'lineItems' => $lineItems,
  221.             'currencyId' => $context->getCurrency()->getId(),
  222.             'paymentMethodId' => $context->getPaymentMethod()->getId(),
  223.             'shippingMethodId' => $context->getShippingMethod()->getId(),
  224.             'countryId' => $context->getShippingLocation()->getCountry()->getId(),
  225.             'salesChannelId' => $context->getSalesChannel()->getId(),
  226.             'salesChannelDomainId' => $salesChannelDomainId,
  227.             'customerId' => $customer->getId(),
  228.             'email' => $customer->getEmail(),
  229.         ];
  230.         $this->abandonedCartRepository->upsert([$data], $context->getContext());
  231.     }
  232. }