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

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Routing;
  3. use Shopware\Core\Checkout\Cart\CartException;
  4. use Shopware\Core\Framework\Log\Package;
  5. use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
  6. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  7. use Shopware\Core\Framework\Util\Random;
  8. use Shopware\Core\PlatformRequest;
  9. use Shopware\Core\SalesChannelRequest;
  10. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
  11. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
  12. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  13. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  16. #[Package('core')]
  17. class SalesChannelRequestContextResolver implements RequestContextResolverInterface
  18. {
  19.     use RouteScopeCheckTrait;
  20.     /**
  21.      * @internal
  22.      */
  23.     public function __construct(
  24.         private readonly RequestContextResolverInterface $decorated,
  25.         private readonly SalesChannelContextServiceInterface $contextService,
  26.         private readonly EventDispatcherInterface $eventDispatcher,
  27.         private readonly RouteScopeRegistry $routeScopeRegistry
  28.     ) {
  29.     }
  30.     public function resolve(SymfonyRequest $request): void
  31.     {
  32.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID)) {
  33.             $this->decorated->resolve($request);
  34.             return;
  35.         }
  36.         if (!$this->isRequestScoped($requestSalesChannelContextRouteScopeDependant::class)) {
  37.             return;
  38.         }
  39.         if (!$request->headers->has(PlatformRequest::HEADER_CONTEXT_TOKEN)) {
  40.             if ($this->contextTokenRequired($request)) {
  41.                 throw new MissingRequestParameterException(PlatformRequest::HEADER_CONTEXT_TOKEN);
  42.             }
  43.             $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKENRandom::getAlphanumericString(32));
  44.         }
  45.         // Retrieve context for current request
  46.         $usedContextToken = (string) $request->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN);
  47.         $contextServiceParameters = new SalesChannelContextServiceParameters(
  48.             (string) $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID),
  49.             $usedContextToken,
  50.             $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID),
  51.             $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID),
  52.             $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID)
  53.         );
  54.         $context $this->contextService->get($contextServiceParameters);
  55.         // Validate if a customer login is required for the current request
  56.         $this->validateLogin($request$context);
  57.         // Update attributes and headers of the current request
  58.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  59.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  60.         $request->headers->set(PlatformRequest::HEADER_CONTEXT_TOKEN$context->getToken());
  61.         $this->eventDispatcher->dispatch(
  62.             new SalesChannelContextResolvedEvent($context$usedContextToken)
  63.         );
  64.     }
  65.     public function handleSalesChannelContext(Request $requeststring $salesChannelIdstring $contextToken): void
  66.     {
  67.         $language $request->headers->get(PlatformRequest::HEADER_LANGUAGE_ID);
  68.         $currencyId $request->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_CURRENCY_ID);
  69.         $context $this->contextService
  70.             ->get(new SalesChannelContextServiceParameters($salesChannelId$contextToken$language$currencyId));
  71.         $request->attributes->set(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT$context->getContext());
  72.         $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$context);
  73.     }
  74.     protected function getScopeRegistry(): RouteScopeRegistry
  75.     {
  76.         return $this->routeScopeRegistry;
  77.     }
  78.     private function contextTokenRequired(Request $request): bool
  79.     {
  80.         return (bool) $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_TOKEN_REQUIREDfalse);
  81.     }
  82.     private function validateLogin(Request $requestSalesChannelContext $context): void
  83.     {
  84.         if (!$request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED)) {
  85.             return;
  86.         }
  87.         if ($context->getCustomer() === null) {
  88.             throw CartException::customerNotLoggedIn();
  89.         }
  90.         if ($request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED_ALLOW_GUESTfalse) === false && $context->getCustomer()->getGuest()) {
  91.             throw CartException::customerNotLoggedIn();
  92.         }
  93.     }
  94. }