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

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