vendor/shopware/platform/src/Core/Framework/Routing/SalesChannelRequestContextResolver.php line 61

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Routing;
  3. use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
  4. use Shopware\Core\Framework\Routing\Annotation\ContextTokenRequired;
  5. use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
  6. use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
  7. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  8. use Shopware\Core\Framework\Util\Random;
  9. use Shopware\Core\PlatformRequest;
  10. use Shopware\Core\SalesChannelRequest;
  11. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
  12. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  17. class SalesChannelRequestContextResolver implements RequestContextResolverInterface
  18. {
  19.     use RouteScopeCheckTrait;
  20.     /**
  21.      * @var RequestContextResolverInterface
  22.      */
  23.     private $decorated;
  24.     /**
  25.      * @var SalesChannelContextServiceInterface
  26.      */
  27.     private $contextService;
  28.     /**
  29.      * @var EventDispatcherInterface
  30.      */
  31.     private $eventDispatcher;
  32.     /**
  33.      * @var SalesChannelContext[]
  34.      */
  35.     private $cache = [];
  36.     /**
  37.      * @var RouteScopeRegistry
  38.      */
  39.     private $routeScopeRegistry;
  40.     public function __construct(
  41.         RequestContextResolverInterface $decorated,
  42.         SalesChannelContextServiceInterface $contextService,
  43.         EventDispatcherInterface $eventDispatcher,
  44.         RouteScopeRegistry $routeScopeRegistry
  45.     ) {
  46.         $this->decorated $decorated;
  47.         $this->contextService $contextService;
  48.         $this->eventDispatcher $eventDispatcher;
  49.         $this->routeScopeRegistry $routeScopeRegistry;
  50.     }
  51.     public function resolve(SymfonyRequest $request): void
  52.     {
  53.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID)) {
  54.             $this->decorated->resolve($request);
  55.             return;
  56.         }
  57.         if (!$this->isRequestScoped($requestSalesChannelContextRouteScopeDependant::class)) {
  58.             return;
  59.         }
  60.         if (
  61.             $this->contextTokenRequired($request) === true
  62.             && !$request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)
  63.         ) {
  64.             throw new MissingRequestParameterException(PlatformRequest::HEADER_CONTEXT_TOKEN);
  65.         }
  66.         if (
  67.             $this->contextTokenRequired($request) === false
  68.             && !$request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)
  69.         ) {
  70.             $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKENRandom::getAlphanumericString(32));
  71.         }
  72.         $contextToken $request->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN);
  73.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  74.         $language $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID);
  75.         $currencyId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID);
  76.         $domainId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID);
  77.         $cacheKey $salesChannelId $contextToken $language $currencyId $domainId;
  78.         if (!empty($this->cache[$cacheKey])) {
  79.             $context $this->cache[$cacheKey];
  80.         } else {
  81.             $context $this->contextService->get(
  82.                 new SalesChannelContextServiceParameters((string) $salesChannelId, (string) $contextToken$language$currencyId$domainId)
  83.             );
  84.             $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$context->getToken());
  85.         }
  86.         $this->validateLogin($request$context);
  87.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  88.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  89.         $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$context->getToken());
  90.         $this->eventDispatcher->dispatch(
  91.             new SalesChannelContextResolvedEvent($context, (string) $contextToken)
  92.         );
  93.     }
  94.     public function handleSalesChannelContext(Request $requeststring $salesChannelIdstring $contextToken): void
  95.     {
  96.         $language $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID);
  97.         $currencyId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID);
  98.         $context $this->contextService
  99.             ->get(new SalesChannelContextServiceParameters($salesChannelId$contextToken$language$currencyId));
  100.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  101.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  102.     }
  103.     protected function getScopeRegistry(): RouteScopeRegistry
  104.     {
  105.         return $this->routeScopeRegistry;
  106.     }
  107.     private function contextTokenRequired(Request $request): bool
  108.     {
  109.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIRED)) {
  110.             return false;
  111.         }
  112.         /** @var ContextTokenRequired $contextTokenRequiredAnnotation */
  113.         $contextTokenRequiredAnnotation $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIRED);
  114.         return $contextTokenRequiredAnnotation->isRequired();
  115.     }
  116.     private function validateLogin(Request $requestSalesChannelContext $context): void
  117.     {
  118.         /** @var LoginRequired|null $loginRequired */
  119.         $loginRequired $request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED);
  120.         if ($loginRequired === null) {
  121.             return;
  122.         }
  123.         if ($loginRequired->isLoggedIn($context)) {
  124.             return;
  125.         }
  126.         throw new CustomerNotLoggedInException();
  127.     }
  128. }