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

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