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

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