custom/plugins/CrswCleverReachOfficial/src/Subscriber/Automation/CartRecoverySubscriber.php line 161

Open in your IDE?
  1. <?php
  2. namespace Crsw\CleverReachOfficial\Subscriber\Automation;
  3. use Crsw\CleverReachOfficial\Components\Utility\Bootstrap;
  4. use Crsw\CleverReachOfficial\Components\Utility\Initializer;
  5. use Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Contracts\RecoveryEmailStatus;
  6. use Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Interfaces\AutomationRecordService;
  7. use Crsw\CleverReachOfficial\Core\Infrastructure\Exceptions\BaseException;
  8. use Crsw\CleverReachOfficial\Core\Infrastructure\Logger\Logger;
  9. use Crsw\CleverReachOfficial\Entity\Product\Repositories\ProductRepository;
  10. use Crsw\CleverReachOfficial\Service\BusinessLogic\Automation\Entities\RecoveryRecord;
  11. use Crsw\CleverReachOfficial\Service\BusinessLogic\Automation\RecoveryRecordService;
  12. use Crsw\CleverReachOfficial\Service\BusinessLogic\SalesChannel\SalesChannelContextService;
  13. use Shopware\Core\Checkout\Cart\LineItemFactoryRegistry;
  14. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  15. use Shopware\Core\Framework\Context;
  16. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  17. use Shopware\Storefront\Event\StorefrontRenderEvent;
  18. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPage;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  21. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  22. use Symfony\Component\HttpKernel\KernelEvents;
  23. /**
  24.  * Class CartRecoverySubscriber
  25.  *
  26.  * @package Crsw\CleverReachOfficial\Subscriber\Automation
  27.  */
  28. class CartRecoverySubscriber implements EventSubscriberInterface
  29. {
  30.     /**
  31.      * @var RecoveryRecordService
  32.      */
  33.     private $recoveryRecordService;
  34.     /**
  35.      * @var ProductRepository
  36.      */
  37.     private $productRepository;
  38.     /**
  39.      * @var LineItemFactoryRegistry
  40.      */
  41.     private $factory;
  42.     /**
  43.      * @var CartService
  44.      */
  45.     private $cartService;
  46.     /**
  47.      * @var SessionInterface
  48.      */
  49.     private $session;
  50.     /**
  51.      * @var SalesChannelContextService
  52.      */
  53.     private $salesChannelContextService;
  54.     /**
  55.      * @var AutomationRecordService
  56.      */
  57.     private $automationRecordService;
  58.     /**
  59.      * CartRecoverySubscriber constructor.
  60.      *
  61.      * @param Initializer $initializer
  62.      * @param RecoveryRecordService $recoveryRecordService
  63.      * @param ProductRepository $productRepository
  64.      * @param LineItemFactoryRegistry $factory
  65.      * @param CartService $cartService
  66.      * @param SessionInterface $session
  67.      * @param SalesChannelContextService $salesChannelContextService
  68.      */
  69.     public function __construct(
  70.         Initializer $initializer,
  71.         RecoveryRecordService $recoveryRecordService,
  72.         ProductRepository $productRepository,
  73.         LineItemFactoryRegistry $factory,
  74.         CartService $cartService,
  75.         SessionInterface $session,
  76.         SalesChannelContextService $salesChannelContextService,
  77.         AutomationRecordService $automationRecordService
  78.     ) {
  79.         Bootstrap::register();
  80.         $initializer->registerServices();
  81.         $this->recoveryRecordService $recoveryRecordService;
  82.         $this->productRepository $productRepository;
  83.         $this->factory $factory;
  84.         $this->cartService $cartService;
  85.         $this->session $session;
  86.         $this->salesChannelContextService $salesChannelContextService;
  87.         $this->automationRecordService $automationRecordService;
  88.     }
  89.     /**
  90.      * @inheritDoc
  91.      */
  92.     public static function getSubscribedEvents(): array
  93.     {
  94.         return [
  95.             KernelEvents::CONTROLLER => 'onRecover',
  96.             StorefrontRenderEvent::class => 'afterCartUpdate'
  97.         ];
  98.     }
  99.     /**
  100.      * Handles cart recovery.
  101.      *
  102.      * @param ControllerEvent $event
  103.      */
  104.     public function onRecover(ControllerEvent $event): void
  105.     {
  106.         $request $event->getRequest();
  107.         $routeName $request->get('_route');
  108.         if ($routeName !== 'frontend.checkout.confirm.page') {
  109.             return;
  110.         }
  111.         $token $request->get('token');
  112.         $flag $request->get('recover');
  113.         if (empty($token) || empty($flag)) {
  114.             return;
  115.         }
  116.         $crMailing $request->get('crmailing');
  117.         if (!empty($crMailing)) {
  118.             $this->session->set('crMailing'$crMailing);
  119.         }
  120.         try {
  121.             $record $this->recoveryRecordService->findByToken($token);
  122.             if ($record === null) {
  123.                 return;
  124.             }
  125.             /** @var SalesChannelContext $salesChannelContext */
  126.             $salesChannelContext $request->get('sw-sales-channel-context') ?:
  127.                 $this->salesChannelContextService->getSalesChannelContext($request);
  128.             $this->cartService->createNew($salesChannelContext->getToken());
  129.             $lineItems $this->getLineItems($record$salesChannelContext);
  130.             $cart $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  131.             $this->cartService->add($cart$lineItems$salesChannelContext);
  132.             $this->recoverAutomationRecord($record->getEmail());
  133.         } catch (BaseException $e) {
  134.             Logger::logError('Failed to recover basket because: ' $e->getMessage(), 'Integration');
  135.         }
  136.     }
  137.     /**
  138.      * Removes items from cart if they are duplicated.
  139.      *
  140.      * @param StorefrontRenderEvent $event
  141.      */
  142.     public function afterCartUpdate(StorefrontRenderEvent $event): void
  143.     {
  144.         if ($event->getView() !== '@Storefront/storefront/page/checkout/confirm/index.html.twig') {
  145.             return;
  146.         }
  147.         $context $event->getSalesChannelContext();
  148.         /** @var CheckoutConfirmPage $page */
  149.         $page $event->getParameters()['page'];
  150.         $cart $page->getCart();
  151.         try {
  152.             $records $this->recoveryRecordService->find(['email' => $context->getCustomer()->getEmail()]);
  153.             if ($records === []) {
  154.                 return;
  155.             }
  156.             $record $records[0];
  157.             if ($cart->getLineItems()->count() > count($record->getItems())) {
  158.                 $newCart $this->cartService->createNew($context->getToken());
  159.                 $lineItems $this->getLineItems($record$context);
  160.                 $newCart $this->cartService->add($newCart$lineItems$context);
  161.                 $page->setCart($newCart);
  162.                 $this->cartService->setCart($newCart);
  163.             }
  164.         } catch (BaseException $e) {
  165.             Logger::logError('Failed to retrieve recovery record because ' $e->getMessage());
  166.         }
  167.     }
  168.     /**
  169.      * @param string $email
  170.      * @param string $cartId
  171.      *
  172.      * @throws \Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Exceptions\FailedToUpdateAutomationRecordException
  173.      */
  174.     protected function recoverAutomationRecord(string $email): void
  175.     {
  176.         $records $this->automationRecordService->findBy(['email' => $email'status' => RecoveryEmailStatus::SENT]);
  177.         if (!empty($records[0])) {
  178.             $record $records[0];
  179.             $record->setIsRecovered(true);
  180.             $this->automationRecordService->update($record);
  181.         }
  182.     }
  183.     /**
  184.      * @param RecoveryRecord $record
  185.      * @param SalesChannelContext $context
  186.      *
  187.      * @return array
  188.      */
  189.     protected function getLineItems(RecoveryRecord $recordSalesChannelContext $context): array
  190.     {
  191.         $lineItems = [];
  192.         foreach ($record->getItems() as $key => $value) {
  193.             $product $this->productRepository->getProductById($keyContext::createDefaultContext());
  194.             if (!$product) {
  195.                 continue;
  196.             }
  197.             $lineItem $this->factory->create([
  198.                 'type' => 'product',
  199.                 'referencedId' => $product->getId(),
  200.                 'quantity' => $value
  201.             ], $context);
  202.             $lineItems[] = $lineItem;
  203.         }
  204.         return $lineItems;
  205.     }
  206. }