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

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