custom/plugins/NetiNextAccessManager/src/Subscriber/Customer.php line 113

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (c) 2020, Net Inventors GmbH
  4.  * @category  Shopware
  5.  * @author    malte
  6.  */
  7. namespace NetInventors\NetiNextAccessManager\Subscriber;
  8. use Doctrine\DBAL\Exception;
  9. use NetInventors\NetiNextAccessManager\Constants\ConfigConstants;
  10. use NetInventors\NetiNextAccessManager\Events\BusinessEvent\CustomerActivateEvent;
  11. use NetInventors\NetiNextAccessManager\Events\BusinessEvent\CustomerDeactivateEvent;
  12. use \NetInventors\NetiNextAccessManager\Events\FlowEvent\CustomerActivateEvent as FlowCustomerActivateEvent;
  13. use \NetInventors\NetiNextAccessManager\Events\FlowEvent\CustomerDeactivateEvent as FlowCustomerDeactivateEvent;
  14. use NetInventors\NetiNextAccessManager\Extension\Content\Customer\Aggregate\CustomerAttribute\CustomerAttributeEntity;
  15. use NetInventors\NetiNextAccessManager\Service\CheckService;
  16. use NetInventors\NetiNextAccessManager\Service\CustomerService;
  17. use NetInventors\NetiNextAccessManager\Service\PluginConfig;
  18. use NetInventors\NetiNextAccessManager\Service\SalesChannelContextRestorer;
  19. use Shopware\Core\Checkout\Customer\CustomerEntity;
  20. use Shopware\Core\Framework\Context;
  21. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  22. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  23. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  24. use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
  25. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Shopware\Core\Checkout\Customer\CustomerEvents;
  28. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  29. use Symfony\Component\HttpFoundation\RequestStack;
  30. use Symfony\Component\HttpKernel\Event\RequestEvent;
  31. use Symfony\Component\HttpKernel\KernelEvents;
  32. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  33. class Customer implements EventSubscriberInterface
  34. {
  35.     private bool $isFirstActivation false;
  36.     private bool $isEventTriggered  false;
  37.     /**
  38.      * @var RequestStack
  39.      */
  40.     private $requestStack;
  41.     /**
  42.      * @var EntityRepositoryInterface
  43.      */
  44.     private $customerRepository;
  45.     /**
  46.      * @var PluginConfig
  47.      */
  48.     private $pluginConfig;
  49.     /**
  50.      * @var CustomerService
  51.      */
  52.     private $customerService;
  53.     /**
  54.      * @var EventDispatcherInterface
  55.      */
  56.     private                                    $eventDispatcher;
  57.     private bool                               $flowsAvailable;
  58.     private SalesChannelContextRestorer        $salesChannelContextRestorer;
  59.     private AbstractSalesChannelContextFactory $salesChannelContextFactory;
  60.     /**
  61.      * Customer constructor.
  62.      *
  63.      * @param RequestStack                $requestStack
  64.      * @param EntityRepositoryInterface   $customerRepository
  65.      * @param PluginConfig                $pluginConfig
  66.      * @param CustomerService             $customerService
  67.      * @param EventDispatcherInterface    $eventDispatcher
  68.      * @param CheckService                $checkService
  69.      * @param SalesChannelContextRestorer $salesChannelContextRestorer
  70.      */
  71.     public function __construct(
  72.         RequestStack                       $requestStack,
  73.         EntityRepositoryInterface          $customerRepository,
  74.         PluginConfig                       $pluginConfig,
  75.         CustomerService                    $customerService,
  76.         EventDispatcherInterface           $eventDispatcher,
  77.         CheckService                       $checkService,
  78.         SalesChannelContextRestorer        $salesChannelContextRestorer,
  79.         AbstractSalesChannelContextFactory $salesChannelContextFactory
  80.     ) {
  81.         $this->requestStack                $requestStack;
  82.         $this->customerRepository          $customerRepository;
  83.         $this->pluginConfig                $pluginConfig;
  84.         $this->customerService             $customerService;
  85.         $this->eventDispatcher             $eventDispatcher;
  86.         $this->flowsAvailable              $checkService->isFlowsAvailable();
  87.         $this->salesChannelContextRestorer $salesChannelContextRestorer;
  88.         $this->salesChannelContextFactory  $salesChannelContextFactory;
  89.     }
  90.     public static function getSubscribedEvents(): array
  91.     {
  92.         return [
  93.             CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'onCustomerWritten',
  94.             KernelEvents::REQUEST                  => 'onKernelRequest',
  95.             CustomerEvents::CUSTOMER_LOADED_EVENT  => 'onCustomerLoaded',
  96.         ];
  97.     }
  98.     public function onCustomerLoaded(EntityLoadedEvent $event): void
  99.     {
  100.         $entities $event->getEntities();
  101.         /** @var CustomerEntity $entity */
  102.         foreach ($entities as $entity) {
  103.             if (null === $entity->getExtension('netiAccessManagerCustomerAttribute')) {
  104.                 $this->customerService->setActiveAttribute($entity->getId(), true$event->getContext());
  105.             }
  106.         }
  107.     }
  108.     /**
  109.      * @throws Exception
  110.      */
  111.     public function onCustomerWritten(EntityWrittenEvent $event): void
  112.     {
  113.         $masterRequest $this->requestStack->getMasterRequest();
  114.         if (null === $masterRequest) {
  115.             return;
  116.         }
  117.         /** @var array|mixed $attribute */
  118.         $attribute $masterRequest->request->get('netiAccessManagerCustomerAttribute');
  119.         if (!
  120.             (
  121.                 \is_array($attribute)
  122.                 && isset($attribute['activated'])
  123.             )
  124.         ) {
  125.             return;
  126.         }
  127.         $customerId $attribute['id'];
  128.         if (!\is_string($customerId)) {
  129.             throw new \UnexpectedValueException('The customer ID is not the expected type of string: '. \gettype($customerId));
  130.         }
  131.         $customer $this->customerRepository->search(new Criteria([ $customerId ]), $event->getContext())->first();
  132.         if (!$customer instanceof CustomerEntity) {
  133.             return;
  134.         }
  135.         $pluginConfig $this->pluginConfig->loadConfigOfSalesChannel($customer->getSalesChannelId());
  136.         if (!$pluginConfig->isActive()) {
  137.             return;
  138.         }
  139.         $isMailSendingOnChangeActivation =
  140.             $pluginConfig->getStatusChangeNotification() === ConfigConstants::STATUS_CHANGE_NOTIFICATION_CHANGE;
  141.         $context                         $event->getContext();
  142.         $customer                        $this->customerService->getCustomerWithSalutation($customerId$context);
  143.         if (!$customer instanceof CustomerEntity) {
  144.             throw new \RuntimeException('Customer was not found by id '$customerId);
  145.         }
  146.         $salesSaleChannelContext $this->salesChannelContextFactory->create(
  147.             '',
  148.             $customer->getSalesChannelId(),
  149.             [ SalesChannelContextService::LANGUAGE_ID => $customer->getLanguageId() ]
  150.         );
  151.         $customerContext         $this->salesChannelContextRestorer->restoreByCustomer(
  152.             $customerId,
  153.             $salesSaleChannelContext
  154.         )->getContext();
  155.         if ($customer->getLanguageId() !== $context->getLanguageId()) {
  156.             $customer $this->customerService->getCustomerWithSalutation($customerId$customerContext);
  157.             if (!$customer instanceof CustomerEntity) {
  158.                 throw new \RuntimeException('Customer was not found by id '$customerId);
  159.             }
  160.         }
  161.         if (
  162.             $attribute['activated']
  163.             && (
  164.                 $this->isFirstActivation
  165.                 || $isMailSendingOnChangeActivation
  166.             )
  167.         ) {
  168.             if (!$this->isEventTriggered) {
  169.                 $this->isEventTriggered true;
  170.                 if ($this->flowsAvailable) {
  171.                     /** @psalm-suppress DeprecatedClass */
  172.                     $this->eventDispatcher->dispatch(new FlowCustomerActivateEvent($customerContext$customer));
  173.                 } else {
  174.                     /** @psalm-suppress DeprecatedClass */
  175.                     $this->eventDispatcher->dispatch(new CustomerActivateEvent($customerContext$customer));
  176.                 }
  177.             }
  178.         } elseif ($attribute['activated'] === false && $isMailSendingOnChangeActivation) {
  179.             if (!$this->isEventTriggered) {
  180.                 $this->isEventTriggered true;
  181.                 if ($this->flowsAvailable) {
  182.                     /** @psalm-suppress DeprecatedClass */
  183.                     $this->eventDispatcher->dispatch(new FlowCustomerDeactivateEvent($customerContext$customer));
  184.                 } else {
  185.                     /** @psalm-suppress DeprecatedClass */
  186.                     $this->eventDispatcher->dispatch(new CustomerDeactivateEvent($customerContext$customer));
  187.                 }
  188.             }
  189.         }
  190.     }
  191.     /**
  192.      * @param RequestEvent $event
  193.      */
  194.     public function onKernelRequest(RequestEvent $event): void
  195.     {
  196.         /** @var array|mixed $attribute */
  197.         $attribute $event->getRequest()->request->get('netiAccessManagerCustomerAttribute');
  198.         if (
  199.             !(
  200.                 \is_array($attribute)
  201.                 && isset($attribute['activated'])
  202.                 && $this->pluginConfig->isActive()
  203.             )
  204.         ) {
  205.             return;
  206.         }
  207.         if (!\is_string($attribute['id'])) {
  208.             throw new \UnexpectedValueException('The customer ID is not the expected type of string: '. \gettype($attribute['id']));
  209.         }
  210.         /** @var CustomerEntity $customer */
  211.         $customer $this->customerRepository->search(new Criteria([$attribute['id']]), Context::createDefaultContext())->first();
  212.         if (!
  213.             (
  214.                 $customer instanceof CustomerEntity
  215.                 && $customer->hasExtension('netiAccessManagerCustomerAttribute')
  216.             )
  217.         ) {
  218.             return;
  219.         }
  220.         /** @var CustomerAttributeEntity $extension */
  221.         $extension $customer->getExtension('netiAccessManagerCustomerAttribute');
  222.         $this->isFirstActivation = (CustomerAttributeEntity::ACTIVATED_BY_SYSTEM === $extension->getActivatedBy());
  223.     }
  224. }