vendor/shopware/core/Checkout/Customer/Subscriber/CustomerTokenSubscriber.php line 63

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Customer\Subscriber;
  3. use Shopware\Core\Checkout\Customer\CustomerEvents;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  7. use Shopware\Core\PlatformRequest;
  8. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextPersister;
  9. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  10. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  11. use Symfony\Component\HttpFoundation\RequestStack;
  12. class CustomerTokenSubscriber implements EventSubscriberInterface
  13. {
  14.     private SalesChannelContextPersister $contextPersister;
  15.     private RequestStack $requestStack;
  16.     public function __construct(
  17.         SalesChannelContextPersister $contextPersister,
  18.         RequestStack $requestStack
  19.     ) {
  20.         $this->contextPersister $contextPersister;
  21.         $this->requestStack $requestStack;
  22.     }
  23.     /**
  24.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  25.      */
  26.     public static function getSubscribedEvents()
  27.     {
  28.         return [
  29.             CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'onCustomerWritten',
  30.             CustomerEvents::CUSTOMER_DELETED_EVENT => 'onCustomerDeleted',
  31.         ];
  32.     }
  33.     public function onCustomerWritten(EntityWrittenEvent $event): void
  34.     {
  35.         foreach ($event->getWriteResults() as $writeResult) {
  36.             if ($writeResult->getOperation() !== EntityWriteResult::OPERATION_UPDATE) {
  37.                 continue;
  38.             }
  39.             $payload $writeResult->getPayload();
  40.             if (!$this->customerCredentialsChanged($payload)) {
  41.                 continue;
  42.             }
  43.             $customerId $payload['id'];
  44.             $newToken $this->invalidateUsingSession($customerId);
  45.             if ($newToken) {
  46.                 $this->contextPersister->revokeAllCustomerTokens($customerId$newToken);
  47.             } else {
  48.                 $this->contextPersister->revokeAllCustomerTokens($customerId);
  49.             }
  50.         }
  51.     }
  52.     public function onCustomerDeleted(EntityDeletedEvent $event): void
  53.     {
  54.         foreach ($event->getIds() as $customerId) {
  55.             $this->contextPersister->revokeAllCustomerTokens($customerId);
  56.         }
  57.     }
  58.     private function customerCredentialsChanged(array $payload): bool
  59.     {
  60.         return isset($payload['password']);
  61.     }
  62.     private function invalidateUsingSession(string $customerId): ?string
  63.     {
  64.         $master $this->requestStack->getMainRequest();
  65.         if (!$master) {
  66.             return null;
  67.         }
  68.         // Is not a storefront request
  69.         if (!$master->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT)) {
  70.             return null;
  71.         }
  72.         /** @var SalesChannelContext $context */
  73.         $context $master->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  74.         // Not loggedin skip
  75.         if ($context->getCustomer() === null) {
  76.             return null;
  77.         }
  78.         // The written customer is not the same as logged-in. We don't modify the user session
  79.         if ($context->getCustomer()->getId() !== $customerId) {
  80.             return null;
  81.         }
  82.         $token $context->getToken();
  83.         $newToken $this->contextPersister->replace($token$context);
  84.         $context->assign([
  85.             'token' => $newToken,
  86.         ]);
  87.         if (!$master->hasSession()) {
  88.             return null;
  89.         }
  90.         $session $master->getSession();
  91.         $session->migrate();
  92.         $session->set('sessionId'$session->getId());
  93.         $session->set(PlatformRequest::HEADER_CONTEXT_TOKEN$newToken);
  94.         $master->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$newToken);
  95.         return $newToken;
  96.     }
  97. }