custom/plugins/CrswCleverReachOfficial/src/Subscriber/Automation/AutomationSubscriber.php line 223

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\Group\GroupService;
  6. use Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Contracts\RecoveryEmailStatus;
  7. use Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Entities\AutomationRecord;
  8. use Crsw\CleverReachOfficial\Core\BusinessLogic\Multistore\AbandonedCart\Services\AutomationRecordService;
  9. use Crsw\CleverReachOfficial\Core\Infrastructure\Exceptions\BaseException;
  10. use Crsw\CleverReachOfficial\Core\Infrastructure\Logger\Logger;
  11. use Crsw\CleverReachOfficial\Service\BusinessLogic\Automation\AutomationService;
  12. use Crsw\CleverReachOfficial\Service\BusinessLogic\Automation\RecoveryRecordService;
  13. use Crsw\CleverReachOfficial\Service\BusinessLogic\SalesChannel\SalesChannelContextService;
  14. use Shopware\Core\Checkout\Cart\Cart;
  15. use Shopware\Core\Checkout\Cart\Event\CartDeletedEvent;
  16. use Shopware\Core\Checkout\Cart\Event\CartSavedEvent;
  17. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  18. use Shopware\Core\Checkout\Customer\CustomerEntity;
  19. use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
  20. use Shopware\Core\Checkout\Order\OrderEvents;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  22. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  23. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  24. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  25. use Symfony\Component\HttpFoundation\RequestStack;
  26. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  27. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  28. use Symfony\Component\HttpKernel\KernelEvents;
  29. /**
  30.  * Class AutomationSubscriber
  31.  *
  32.  * @package Crsw\CleverReachOfficial\Subscriber\Automation
  33.  */
  34. class AutomationSubscriber implements EventSubscriberInterface
  35. {
  36.     /**
  37.      * @var AutomationService
  38.      */
  39.     private $automationService;
  40.     /**
  41.      * @var GroupService
  42.      */
  43.     private $groupService;
  44.     /**
  45.      * @var AutomationRecordService
  46.      */
  47.     private $automationRecordService;
  48.     /**
  49.      * @var CartService
  50.      */
  51.     private $cartService;
  52.     /**
  53.      * @var RequestStack
  54.      */
  55.     private $requestStack;
  56.     /**
  57.      * @var RecoveryRecordService
  58.      */
  59.     private $recoveryRecordService;
  60.     /**
  61.      * @var ParameterBagInterface
  62.      */
  63.     private $params;
  64.     /**
  65.      * @var SalesChannelContextService
  66.      */
  67.     private $salesChannelContextService;
  68.     /**
  69.      * @var SessionInterface
  70.      */
  71.     private $session;
  72.     /**
  73.      * AutomationSubscriber constructor.
  74.      *
  75.      * @param Initializer $initializer
  76.      * @param AutomationService $automationService
  77.      * @param GroupService $groupService
  78.      * @param AutomationRecordService $automationRecordService
  79.      * @param CartService $cartService
  80.      * @param RequestStack $requestStack
  81.      * @param RecoveryRecordService $recoveryRecordService
  82.      * @param ParameterBagInterface $params
  83.      * @param SalesChannelContextService $salesChannelContextService
  84.      */
  85.     public function __construct(
  86.         Initializer $initializer,
  87.         AutomationService $automationService,
  88.         GroupService $groupService,
  89.         AutomationRecordService $automationRecordService,
  90.         CartService $cartService,
  91.         RequestStack $requestStack,
  92.         RecoveryRecordService $recoveryRecordService,
  93.         ParameterBagInterface $params,
  94.         SalesChannelContextService $salesChannelContextService,
  95.         SessionInterface $session
  96.     ) {
  97.         Bootstrap::register();
  98.         $initializer->registerServices();
  99.         $this->automationService $automationService;
  100.         $this->groupService $groupService;
  101.         $this->automationRecordService $automationRecordService;
  102.         $this->cartService $cartService;
  103.         $this->requestStack $requestStack;
  104.         $this->recoveryRecordService $recoveryRecordService;
  105.         $this->params $params;
  106.         $this->salesChannelContextService $salesChannelContextService;
  107.         $this->session $session;
  108.     }
  109.     /**
  110.      * @inheritDoc
  111.      */
  112.     public static function getSubscribedEvents(): array
  113.     {
  114.         return [
  115.             CartSavedEvent::class => 'onCartCreated',
  116.             CustomerRegisterEvent::class => 'onCustomerRegistered',
  117.             CartDeletedEvent::class => 'onCartDeleted',
  118.             OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderCreated',
  119.             KernelEvents::CONTROLLER => 'onCheckoutRegistration'
  120.         ];
  121.     }
  122.     /**
  123.      * Handles customer registration during checkout.
  124.      *
  125.      * @param ControllerEvent $event
  126.      */
  127.     public function onCheckoutRegistration(ControllerEvent $event): void
  128.     {
  129.         $request $event->getRequest();
  130.         $route $request->get('_route');
  131.         if ($route !== 'frontend.checkout.confirm.page') {
  132.             return;
  133.         }
  134.         /** @var SalesChannelContext $context */
  135.         $context $request->get('sw-sales-channel-context') ?:
  136.             $this->salesChannelContextService->getSalesChannelContext($request);
  137.         $customer $context->getCustomer();
  138.         if (!$customer) {
  139.             return;
  140.         }
  141.         $cartId $context->getToken();
  142.         $cart $this->cartService->getCart($cartId$context);
  143.         if (!$cart || $this->isRecordAlreadyCreated($cartId)) {
  144.             return;
  145.         }
  146.         $storeId $context->getSalesChannel()->getId();
  147.         $this->handleRecordCreated($storeId$cart$customer);
  148.     }
  149.     /**
  150.      * Handles cart created event.
  151.      *
  152.      * @param CartSavedEvent $event
  153.      */
  154.     public function onCartCreated(CartSavedEvent $event): void
  155.     {
  156.         $request $this->requestStack->getCurrentRequest();
  157.         if (!$request) {
  158.             return;
  159.         }
  160.         if (version_compare($this->params->get('kernel.shopware_version'), '6.4.0''lt')) {
  161.             $context $event->getContext();
  162.         } else {
  163.             $context $event->getSalesChannelContext();
  164.         }
  165.         $cart $event->getCart();
  166.         $customer $context->getCustomer();
  167.         if (!$cart || !$customer) {
  168.             return;
  169.         }
  170.         if ($this->isRecordAlreadyCreated($cart->getToken())) {
  171.             $this->refreshScheduleTime($cart);
  172.             return;
  173.         }
  174.         $storeId $context->getSalesChannel()->getId();
  175.         $this->handleRecordCreated($storeId$cart$customer);
  176.     }
  177.     /**
  178.      * Handles customer registered event.
  179.      *
  180.      * @param CustomerRegisterEvent $event
  181.      */
  182.     public function onCustomerRegistered(CustomerRegisterEvent $event): void
  183.     {
  184.         $customer $event->getCustomer();
  185.         $cartId $event->getSalesChannelContext()->getToken();
  186.         $cart $this->cartService->getCart($cartId$event->getSalesChannelContext());
  187.         if (!$cart || $this->isRecordAlreadyCreated($cartId)) {
  188.             return;
  189.         }
  190.         $storeId $event->getSalesChannelId();
  191.         $this->handleRecordCreated($storeId$cart$customer);
  192.     }
  193.     /**
  194.      * Handles cart deleted event.
  195.      *
  196.      * @param CartDeletedEvent $event
  197.      */
  198.     public function onCartDeleted(CartDeletedEvent $event): void
  199.     {
  200.         if (version_compare($this->params->get('kernel.shopware_version'), '6.4.0''lt')) {
  201.             $context $event->getContext();
  202.         } else {
  203.             $context $event->getSalesChannelContext();
  204.         }
  205.         $cartId $context->getToken();
  206.         $customer $context->getCustomer();
  207.         $this->deleteRecord($cartId$customer);
  208.     }
  209.     /**
  210.      * Handles order created event.
  211.      *
  212.      * @param EntityWrittenEvent $event
  213.      */
  214.     public function onOrderCreated(EntityWrittenEvent $event): void
  215.     {
  216.         $request $this->requestStack->getCurrentRequest();
  217.         if (!$request || empty($request->attributes->get('sw-sales-channel-id'))) {
  218.             return;
  219.         }
  220.         /** @var SalesChannelContext $salesChannelContext */
  221.         $salesChannelContext $request->get('sw-sales-channel-context') ?:
  222.             $this->salesChannelContextService->getSalesChannelContext($request);
  223.         $cartId $salesChannelContext->getToken();
  224.         $customer $salesChannelContext->getCustomer();
  225.         $this->deleteRecord($cartId$customer);
  226.     }
  227.     /**
  228.      * @param string $basketId
  229.      * @return mixed
  230.      */
  231.     private function isRecordAlreadyCreated(string $basketId): bool
  232.     {
  233.         return $this->session->get('cr_ac_' $basketIdfalse);
  234.     }
  235.     /**
  236.      * @param string $basketId
  237.      * @param bool $status
  238.      */
  239.     private function setRecordAlreadyCreated(string $basketIdbool $status): void
  240.     {
  241.         $this->session->set('cr_ac_' $basketId$status);
  242.     }
  243.     /**
  244.      * @param string $storeId
  245.      * @param Cart $cart
  246.      * @param CustomerEntity $customer
  247.      */
  248.     private function handleRecordCreated(string $storeIdCart $cartCustomerEntity $customer): void
  249.     {
  250.         try {
  251.             $automation $this->automationService->get($storeId);
  252.             if (!$automation || !$automation->isActive() || $automation->getStatus() !== 'created') {
  253.                 return;
  254.             }
  255.             $oldRecord $this->automationRecordService->findBy(
  256.                 [
  257.                     'automationId' => $automation->getId(),
  258.                     'email' => $customer->getEmail(),
  259.                     'status' => RecoveryEmailStatus::PENDING,
  260.                 ]
  261.             );
  262.             if (!empty($oldRecord)) {
  263.                 $oldRecord[0]->setCartId($cart->getToken());
  264.                 $this->automationRecordService->update($oldRecord[0]);
  265.             } else {
  266.                 $record = new AutomationRecord();
  267.                 $record->setAutomationId($automation->getId());
  268.                 $record->setCartId($cart->getToken());
  269.                 $record->setGroupId($this->groupService->getId());
  270.                 $record->setEmail($customer->getEmail());
  271.                 $this->automationRecordService->create($record);
  272.             }
  273.             $this->setRecordAlreadyCreated($cart->getToken(), true);
  274.         } catch (BaseException $e) {
  275.             Logger::logError('Failed to create cart record because ' $e->getMessage());
  276.         }
  277.     }
  278.     /**
  279.      * @param string|null $cartId
  280.      * @param CustomerEntity|null $customer
  281.      */
  282.     private function deleteRecord(?string $cartId, ?CustomerEntity $customer): void
  283.     {
  284.         if (!$cartId || !$customer) {
  285.             return;
  286.         }
  287.         try {
  288.             $this->automationRecordService->deleteBy(['email' => $customer->getEmail(), 'isRecovered' => false]);
  289.             $this->setRecordAlreadyCreated($cartIdfalse);
  290.             $record $this->recoveryRecordService->find(['email' => $customer->getEmail(), 'token' => $cartId]);
  291.             if ($record && isset($record[0])) {
  292.                 $this->recoveryRecordService->delete($record[0]);
  293.             }
  294.         } catch (BaseException $e) {
  295.             Logger::logError('Failed to delete cart record because ' $e->getMessage());
  296.         }
  297.     }
  298.     /**
  299.      * Refreshes schedule time for given cart.
  300.      *
  301.      * @param Cart $cart
  302.      */
  303.     private function refreshScheduleTime(Cart $cart): void
  304.     {
  305.         try {
  306.             $records $this->automationRecordService->findBy(['cartId' => $cart->getToken()]);
  307.             if (empty($records[0])) {
  308.                 return;
  309.             }
  310.             $this->automationRecordService->refreshScheduleTime($records[0]);
  311.         } catch (BaseException $e) {
  312.             Logger::logError($e->getMessage(), 'Integration');
  313.         }
  314.     }
  315. }