custom/plugins/NewsletterSendinblue/src/Subscriber/NewsletterRecipientSubscriber.php line 267

Open in your IDE?
  1. <?php
  2. namespace NewsletterSendinblue\Subscriber;
  3. use NewsletterSendinblue\Service\Cart\CartEventProducer;
  4. use NewsletterSendinblue\Service\Cart\SendinblueCartProcessorService;
  5. use NewsletterSendinblue\Service\ConfigService;
  6. use NewsletterSendinblue\Service\Customer\CustomerProducer;
  7. use NewsletterSendinblue\Service\NewsletterRecipient\NewsletterRecipientProducer;
  8. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  9. use Shopware\Core\Checkout\Customer\CustomerEntity;
  10. use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
  11. use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
  12. use Shopware\Core\Checkout\Customer\Event\GuestCustomerRegisterEvent;
  13. use Shopware\Core\Content\MailTemplate\Service\Event\MailBeforeValidateEvent;
  14. use Shopware\Core\Content\Newsletter\Event\NewsletterConfirmEvent;
  15. use Shopware\Core\Content\Newsletter\Event\NewsletterRegisterEvent;
  16. use Shopware\Core\Framework\Api\Context\SalesChannelApiSource;
  17. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  19. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  20. use Shopware\Core\Framework\Context;
  21. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  22. use Shopware\Core\System\SystemConfig\SystemConfigService;
  23. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  24. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  25. use Symfony\Component\HttpFoundation\RequestStack;
  26. class NewsletterRecipientSubscriber implements EventSubscriberInterface
  27. {
  28.     /**
  29.      * @var NewsletterRecipientProducer
  30.      */
  31.     private $newsletterRecipientProducer;
  32.     /**
  33.      * @var CustomerProducer
  34.      */
  35.     private $customerProducer;
  36.     /**
  37.      * @var ConfigService
  38.      */
  39.     private $configService;
  40.     /**
  41.      * @var SystemConfigService
  42.      */
  43.     private $systemConfigService;
  44.     /**
  45.      * @var EntityRepositoryInterface
  46.      */
  47.     private $mailTemplateRepository;
  48.     /**
  49.      * @var EntityRepositoryInterface
  50.      */
  51.     private $customerRepository;
  52.     /**
  53.      * @var RequestStack;
  54.      */
  55.     private $requestStack;
  56.     /**
  57.      * @var SendinblueCartProcessorService
  58.      */
  59.     private $cartProcessorService;
  60.     /**
  61.      * @var CartEventProducer
  62.      */
  63.     private $cartEventProducer;
  64.     /**
  65.      * @var CartService
  66.      */
  67.     private $cartService;
  68.     /**
  69.      * @param NewsletterRecipientProducer $newsletterRecipientProducer
  70.      * @param CustomerProducer $customerProducer
  71.      * @param ConfigService $configService
  72.      * @param SystemConfigService $systemConfigService
  73.      * @param EntityRepositoryInterface $mailTemplateRepository
  74.      * @param EntityRepositoryInterface $customerRepository
  75.      * @param RequestStack $requestStack
  76.      * @param SendinblueCartProcessorService $cartProcessorService
  77.      * @param CartEventProducer $cartEventProducer
  78.      * @param CartService $cartService
  79.      */
  80.     public function __construct(
  81.         NewsletterRecipientProducer    $newsletterRecipientProducer,
  82.         CustomerProducer               $customerProducer,
  83.         ConfigService                  $configService,
  84.         SystemConfigService            $systemConfigService,
  85.         EntityRepositoryInterface      $mailTemplateRepository,
  86.         EntityRepositoryInterface      $customerRepository,
  87.         RequestStack                   $requestStack,
  88.         SendinblueCartProcessorService $cartProcessorService,
  89.         CartEventProducer              $cartEventProducer,
  90.         CartService                    $cartService
  91.     )
  92.     {
  93.         $this->newsletterRecipientProducer $newsletterRecipientProducer;
  94.         $this->customerProducer $customerProducer;
  95.         $this->configService $configService;
  96.         $this->systemConfigService $systemConfigService;
  97.         $this->mailTemplateRepository $mailTemplateRepository;
  98.         $this->customerRepository $customerRepository;
  99.         $this->requestStack $requestStack;
  100.         $this->cartProcessorService $cartProcessorService;
  101.         $this->cartEventProducer $cartEventProducer;
  102.         $this->cartService $cartService;
  103.     }
  104.     /**
  105.      * @return array
  106.      */
  107.     public static function getSubscribedEvents(): array
  108.     {
  109.         return [
  110.             NewsletterConfirmEvent::class => 'onNewsletterConfirmEvent',
  111.             NewsletterRegisterEvent::class => 'onNewsletterRegisterEvent',
  112.             EntityWrittenContainerEvent::class => 'onEntityWrittenContainerEvent',
  113.             MailBeforeValidateEvent::class => 'onMailBeforeValidateEvent',
  114.             CustomerRegisterEvent::class => 'onCustomerRegisterEvent',
  115.             GuestCustomerRegisterEvent::class => 'onCustomerRegisterEvent',
  116.             CustomerLoginEvent::class => 'onCustomerLoginEvent',
  117.         ];
  118.     }
  119.     /**
  120.      * @param CustomerLoginEvent $event
  121.      * @return void
  122.      */
  123.     public function onCustomerLoginEvent(CustomerLoginEvent $event)
  124.     {
  125.         if (method_exists($event'getSalesChannelContext') && $event->getSalesChannelContext() instanceof SalesChannelContext) {
  126.             $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  127.         } else if (method_exists($event'getContext') && $event->getContext() instanceof SalesChannelContext) {
  128.             $salesChannelId $event->getContext()->getSalesChannelId();
  129.         } else {
  130.             return;
  131.         }
  132.         $this->configService->setSalesChannelId($salesChannelId);
  133.         if ($this->configService->isAbandonedCartTrackingEnabled()) {
  134.             $this->cartProcessorService->setShouldCollectData(true);
  135.         }
  136.     }
  137.     /**
  138.      * @param CustomerRegisterEvent $event
  139.      */
  140.     public function onCustomerRegisterEvent(CustomerRegisterEvent $event): void
  141.     {
  142.         $this->configService->setSalesChannelId($event->getSalesChannelId());
  143.         if ($this->configService->isFullCustomerSyncEnabled()) {
  144.             $customer $event->getCustomer();
  145.             $this->customerRepository->update([[
  146.                 'id' => $customer->getId(),
  147.                 'customFields' => [
  148.                     CustomerProducer::FULL_SYNC_CUSTOMER_REGISTERED => true
  149.                 ]
  150.             ]], $event->getContext());
  151.             $this->customerProducer->confirmContact($customer$event->getContext(), $event->getSalesChannelId());
  152.         }
  153.         if ($this->configService->isAbandonedCartTrackingEnabled()) {
  154.             $salesChannelContext $event->getSalesChannelContext();
  155.             $cart $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  156.             if ($cart->getLineItems()->count() > 0) {
  157.                 $this->cartEventProducer->processCart($cart$salesChannelContext);
  158.             }
  159.         }
  160.     }
  161.     /**
  162.      * @param NewsletterConfirmEvent $event
  163.      */
  164.     public function onNewsletterConfirmEvent(NewsletterConfirmEvent $event): void
  165.     {
  166.         $this->newsletterRecipientProducer->confirmContact($event->getNewsletterRecipient(), $event->getContext(), $event->getSalesChannelId());
  167.         $this->updateCoreConfigDoubleOptIn();
  168.     }
  169.     /**
  170.      * @param NewsletterRegisterEvent $event
  171.      */
  172.     public function onNewsletterRegisterEvent(NewsletterRegisterEvent $event): void
  173.     {
  174.         $this->configService->setSalesChannelId($event->getSalesChannelId());
  175.         if ($this->configService->getSubscriptionMailing()) {
  176.             $this->newsletterRecipientProducer->confirmContact($event->getNewsletterRecipient(), $event->getContext(), $event->getSalesChannelId());
  177.             $this->updateCoreConfigDoubleOptIn();
  178.         }
  179.     }
  180.     /**
  181.      * @param EntityWrittenContainerEvent $event
  182.      */
  183.     public function onEntityWrittenContainerEvent(EntityWrittenContainerEvent $event): void
  184.     {
  185.         foreach ($event->getEvents()->getElements() as $eventElement) {
  186.             if ($eventElement->getName() === 'newsletter_recipient.written') {
  187.                 foreach ($eventElement->getWriteResults() as $writeResult) {
  188.                     if ($writeResult->getOperation() === 'update') {
  189.                         $payload $writeResult->getPayload();
  190.                         $newsletterRecipientId $writeResult->getPrimaryKey();
  191.                         $salesChannelId $payload['salesChannelId'] ?? null;
  192.                         if (empty($salesChannelId)) {
  193.                             if ($event->getContext()->getSource() instanceof SalesChannelApiSource) {
  194.                                 $salesChannelId $event->getContext()->getSource()->getSalesChannelId();
  195.                             }
  196.                         }
  197.                         if (isset($payload['status']) && $payload['status'] == 'optOut') {
  198.                             $this->newsletterRecipientProducer->unsubscribeContact($newsletterRecipientId$event->getContext(), $salesChannelId);
  199.                         } else {
  200.                             $this->newsletterRecipientProducer->updateContact($newsletterRecipientId$event->getContext(), $salesChannelId);
  201.                         }
  202.                     }
  203.                 }
  204.             }
  205.             if ($eventElement->getName() === 'customer.written') {
  206.                 foreach ($eventElement->getWriteResults() as $writeResult) {
  207.                     if ($writeResult->getOperation() === 'update') {
  208.                         $payload $writeResult->getPayload();
  209.                         // Skip if customer is created - not call updateContact
  210.                         if (array_key_exists('customFields'$payload)
  211.                             && array_key_exists(CustomerProducer::FULL_SYNC_CUSTOMER_REGISTERED$payload['customFields'])
  212.                             && count($payload['customFields']) == 1
  213.                         ) {
  214.                             continue;
  215.                         }
  216.                         if (array_key_exists('lastLogin'$payload)
  217.                             || array_key_exists('remoteAddress'$payload)
  218.                         ) {
  219.                             continue;
  220.                         }
  221.                         $customerId $writeResult->getPrimaryKey();
  222.                         $salesChannelId $payload['salesChannelId'] ?? null;
  223.                         if (empty($salesChannelId)) {
  224.                             if ($event->getContext()->getSource() instanceof SalesChannelApiSource) {
  225.                                 $salesChannelId $event->getContext()->getSource()->getSalesChannelId();
  226.                             }
  227.                         }
  228.                         $this->customerProducer->updateContact($customerId$event->getContext(), $salesChannelId);
  229.                     }
  230.                 }
  231.             }
  232.         }
  233.     }
  234.     /**
  235.      * @param MailBeforeValidateEvent $event
  236.      */
  237.     public function onMailBeforeValidateEvent(MailBeforeValidateEvent $event): void
  238.     {
  239.         $data $event->getData();
  240.         $templateData $event->getTemplateData();
  241.         $context $event->getContext();
  242.         if (!isset($templateData['newsletterRecipient']) || !isset($data['templateId'])) {
  243.             return;
  244.         }
  245.         if (!$this->isNewsletterMailTemplate($data['templateId'], $context)) {
  246.             return;
  247.         }
  248.         $salesChannelId null;
  249.         if (!empty($data['salesChannelId'])) {
  250.             $salesChannelId $data['salesChannelId'];
  251.         }
  252.         if (empty($salesChannelId) && method_exists($context->getSource(), 'getSalesChannelId')) {
  253.             $salesChannelId $context->getSource()->getSalesChannelId();
  254.         }
  255.         if (!empty($salesChannelId)) {
  256.             $this->configService->setSalesChannelId($salesChannelId);
  257.         }
  258.         if (!$this->configService->getSubscriptionMailing()) {
  259.             return;
  260.         }
  261.         $event->stopPropagation();
  262.     }
  263.     /**
  264.      * @param string $templateId
  265.      * @param Context $context
  266.      * @return bool
  267.      */
  268.     private function isNewsletterMailTemplate(string $templateIdContext $context)
  269.     {
  270.         $criteria = new Criteria([$templateId]);
  271.         $criteria->addAssociation('mailTemplateType');
  272.         $mailTemplate $this->mailTemplateRepository->search($criteria$context)->first();
  273.         if (empty($mailTemplate)) {
  274.             return false;
  275.         }
  276.         return in_array($mailTemplate->getMailTemplateType()->getTechnicalName(), ['newsletterDoubleOptIn''newsletterRegister']);
  277.     }
  278.     /**
  279.      * @return void
  280.      */
  281.     private function updateCoreConfigDoubleOptIn(): void
  282.     {
  283.         if ($this->requestStack
  284.             && $this->requestStack->getCurrentRequest()
  285.             && $this->requestStack->getCurrentRequest()->hasSession()
  286.         ) {
  287.             $session $this->requestStack->getSession();
  288.             if ($session->has('sbCoreDoubleOptIn')) {
  289.                 $this->systemConfigService->set('core.newsletter.doubleOptIn'$session->get('sbCoreDoubleOptIn'));
  290.                 $session->remove('sbCoreDoubleOptIn');
  291.             }
  292.         }
  293.     }
  294. }