vendor/shopware/core/Framework/Routing/SalesChannelRequestContextResolver.php line 103

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\Feature;
  5. use Shopware\Core\Framework\Routing\Annotation\ContextTokenRequired;
  6. use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
  7. use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
  8. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  9. use Shopware\Core\Framework\Util\Random;
  10. use Shopware\Core\PlatformRequest;
  11. use Shopware\Core\SalesChannelRequest;
  12. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
  13. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
  14. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  15. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  18. class SalesChannelRequestContextResolver implements RequestContextResolverInterface
  19. {
  20.     use RouteScopeCheckTrait;
  21.     /**
  22.      * @var RequestContextResolverInterface
  23.      */
  24.     private $decorated;
  25.     /**
  26.      * @var SalesChannelContextServiceInterface
  27.      */
  28.     private $contextService;
  29.     /**
  30.      * @var EventDispatcherInterface
  31.      */
  32.     private $eventDispatcher;
  33.     /**
  34.      * @var SalesChannelContext[]
  35.      */
  36.     private $cache = [];
  37.     /**
  38.      * @var RouteScopeRegistry
  39.      */
  40.     private $routeScopeRegistry;
  41.     /**
  42.      * @internal
  43.      */
  44.     public function __construct(
  45.         RequestContextResolverInterface $decorated,
  46.         SalesChannelContextServiceInterface $contextService,
  47.         EventDispatcherInterface $eventDispatcher,
  48.         RouteScopeRegistry $routeScopeRegistry
  49.     ) {
  50.         $this->decorated $decorated;
  51.         $this->contextService $contextService;
  52.         $this->eventDispatcher $eventDispatcher;
  53.         $this->routeScopeRegistry $routeScopeRegistry;
  54.     }
  55.     public function resolve(SymfonyRequest $request): void
  56.     {
  57.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID)) {
  58.             $this->decorated->resolve($request);
  59.             return;
  60.         }
  61.         if (!$this->isRequestScoped($requestSalesChannelContextRouteScopeDependant::class)) {
  62.             return;
  63.         }
  64.         if (
  65.             $this->contextTokenRequired($request) === true
  66.             && !$request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)
  67.         ) {
  68.             throw new MissingRequestParameterException(PlatformRequest::HEADER_CONTEXT_TOKEN);
  69.         }
  70.         if (
  71.             $this->contextTokenRequired($request) === false
  72.             && !$request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)
  73.         ) {
  74.             $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKENRandom::getAlphanumericString(32));
  75.         }
  76.         $contextToken $request->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN);
  77.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  78.         $language $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID);
  79.         $currencyId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID);
  80.         $domainId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID);
  81.         $cacheKey $salesChannelId $contextToken $language $currencyId $domainId;
  82.         if (!empty($this->cache[$cacheKey])) {
  83.             $context $this->cache[$cacheKey];
  84.         } else {
  85.             $context $this->contextService->get(
  86.                 new SalesChannelContextServiceParameters((string) $salesChannelId, (string) $contextToken$language$currencyId$domainId)
  87.             );
  88.             $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$context->getToken());
  89.         }
  90.         $this->validateLogin($request$context);
  91.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  92.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  93.         $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$context->getToken());
  94.         $this->eventDispatcher->dispatch(
  95.             new SalesChannelContextResolvedEvent($context, (string) $contextToken)
  96.         );
  97.     }
  98.     public function handleSalesChannelContext(Request $requeststring $salesChannelIdstring $contextToken): void
  99.     {
  100.         $language $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID);
  101.         $currencyId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID);
  102.         $context $this->contextService
  103.             ->get(new SalesChannelContextServiceParameters($salesChannelId$contextToken$language$currencyId));
  104.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  105.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  106.     }
  107.     protected function getScopeRegistry(): RouteScopeRegistry
  108.     {
  109.         return $this->routeScopeRegistry;
  110.     }
  111.     private function contextTokenRequired(Request $request): bool
  112.     {
  113.         if (Feature::isActive('v6.5.0.0')) {
  114.             return $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIREDfalse);
  115.         }
  116.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIRED)) {
  117.             return false;
  118.         }
  119.         /** @var ContextTokenRequired|bool $contextTokenRequiredAnnotation */
  120.         $contextTokenRequiredAnnotation $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIRED);
  121.         if (\is_bool($contextTokenRequiredAnnotation)) {
  122.             return $contextTokenRequiredAnnotation;
  123.         }
  124.         return $contextTokenRequiredAnnotation->isRequired();
  125.     }
  126.     private function validateLogin(Request $requestSalesChannelContext $context): void
  127.     {
  128.         if (Feature::isActive('v6.5.0.0')) {
  129.             if (!$request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED)) {
  130.                 return;
  131.             }
  132.             if ($context->getCustomer() === null) {
  133.                 throw new CustomerNotLoggedInException();
  134.             }
  135.             if ($request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED_ALLOW_GUESTfalse) === false && $context->getCustomer()->getGuest()) {
  136.                 throw new CustomerNotLoggedInException();
  137.             }
  138.             return;
  139.         }
  140.         /** @var LoginRequired|bool|null $loginRequired */
  141.         $loginRequired $request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED);
  142.         if ($loginRequired === null) {
  143.             return;
  144.         }
  145.         if (\is_bool($loginRequired)) {
  146.             if (!$loginRequired) {
  147.                 return;
  148.             }
  149.             if ($context->getCustomer() === null) {
  150.                 throw new CustomerNotLoggedInException();
  151.             }
  152.             if ($request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED_ALLOW_GUESTfalse) === false && $context->getCustomer()->getGuest()) {
  153.                 throw new CustomerNotLoggedInException();
  154.             }
  155.             return;
  156.         }
  157.         if ($loginRequired->isLoggedIn($context)) {
  158.             return;
  159.         }
  160.         throw new CustomerNotLoggedInException();
  161.     }
  162. }