custom/plugins/VioRepresentativeLogin/src/Storefront/Subscriber/StorefrontSubscriber.php line 116

Open in your IDE?
  1. <?php /** @noinspection PhpMultipleClassDeclarationsInspection */
  2. declare(strict_types=1);
  3. namespace VioRepresentativeLogin\Storefront\Subscriber;
  4. use JsonException;
  5. use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
  6. use Shopware\Core\Framework\Routing\KernelListenerPriorities;
  7. use Shopware\Core\Framework\Util\Random;
  8. use Shopware\Core\PlatformRequest;
  9. use Shopware\Core\SalesChannelRequest;
  10. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  11. use Shopware\Core\System\SystemConfig\SystemConfigService;
  12. use Shopware\Storefront\Controller\AccountProfileController;
  13. use Shopware\Storefront\Framework\Routing\StorefrontSubscriber as CoreStorefrontSubscriber;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  17. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\Routing\RouterInterface;
  20. use VioRepresentativeLogin\Core\Checkout\Customer\Event\AgentCustomerLogoutEvent;
  21. use VioRepresentativeLogin\Core\Checkout\Customer\Event\AgentLoginEvent;
  22. use VioRepresentativeLogin\Core\Checkout\Customer\Event\AgentLogoutEvent;
  23. use VioRepresentativeLogin\Core\Exception\AgentNotLoggedInException;
  24. use VioRepresentativeLogin\Core\Framework\Routing\Annotation\RepresentativeLoginRequired;
  25. use VioRepresentativeLogin\Core\System\SalesChannel\Context\SalesChannelContextFactory;
  26. use VioRepresentativeLogin\Entity\Agent\AgentEntity;
  27. class StorefrontSubscriber implements EventSubscriberInterface
  28. {
  29.     private RouterInterface $router;
  30.     private CoreStorefrontSubscriber $storefrontSubscriber;
  31.     private SystemConfigService $systemConfigService;
  32.     public function __construct(
  33.         RouterInterface          $router,
  34.         CoreStorefrontSubscriber $storefrontSubscriber,
  35.         SystemConfigService      $systemConfigService
  36.     )
  37.     {
  38.         $this->router $router;
  39.         $this->storefrontSubscriber $storefrontSubscriber;
  40.         $this->systemConfigService $systemConfigService;
  41.     }
  42.     public static function getSubscribedEvents(): array
  43.     {
  44.         return [
  45.             KernelEvents::EXCEPTION => 'agentNotLoggedInHandler',
  46.             AgentLoginEvent::class => 'updateSessionAfterLogin',
  47.             AgentLogoutEvent::class => 'updateSessionAfterLogout',
  48.             AgentCustomerLogoutEvent::class => 'updateSessionAfterCustomerLogout',
  49.             KernelEvents::CONTROLLER => [
  50.                 ['onKernelControllerPreContextResolve'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_CONTEXT_RESOLVE_PRE],
  51.                 ['onKernelControllerPostContextResolve'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_CONTEXT_RESOLVE_POST]
  52.             ]
  53.         ];
  54.     }
  55.     public function onKernelControllerPostContextResolve(ControllerEvent $event): void
  56.     {
  57.         $request $event->getRequest();
  58.         if ($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT)
  59.             && strpos($request->attributes->get('_route'), 'frontend.account') === 0
  60.             && strpos($request->attributes->get('_route'), 'frontend.account.register') === false ) {
  61.             /** @var AccountProfileController $controller */
  62.             $controller $event->getController();
  63.             /** @var SalesChannelContext $salesChannelContext */
  64.             $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  65.             if ($controller
  66.                 && $salesChannelContext->getCustomer() === null
  67.                 && $salesChannelContext->getExtensionOfType(SalesChannelContextFactory::AGENT_KEYAgentEntity::class) !== null) {
  68.                 // redirect to different Route
  69.                 $event->setController(function () use ($salesChannelContext) {
  70.                     return new RedirectResponse($this->router->generate($this->getRedirectRoute($salesChannelContext)));
  71.                 });
  72.             }
  73.         }
  74.     }
  75.     public function onKernelControllerPreContextResolve(ControllerEvent $event): void
  76.     {
  77.         $request $event->getRequest();
  78.         if ($request->attributes->has(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED)) {
  79.             // decorate class
  80.             /** @var LoginRequired $loginRequiredAnnotation */
  81.             $loginRequiredAnnotation $request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED);
  82.             if( $loginRequiredAnnotation instanceof LoginRequired ) {
  83.                 $loginRequiredAnnotationAllowGuests $loginRequiredAnnotation->isAllowGuest();
  84.             }
  85.             else {
  86.                 $loginRequiredAnnotationAllowGuests $request->attributes->get(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED_ALLOW_GUEST);
  87.             }
  88.             $RepresentativeLoginRequired = new RepresentativeLoginRequired(['allowGuest' => $loginRequiredAnnotationAllowGuests]);
  89.             $request->attributes->set(PlatformRequest::ATTRIBUTE_LOGIN_REQUIRED$RepresentativeLoginRequired);
  90.         }
  91.     }
  92.     public function updateSessionAfterCustomerLogout(AgentCustomerLogoutEvent $event): void
  93.     {
  94.         $token $event->getSalesChannelContext()->getToken();
  95.         $this->storefrontSubscriber->updateSession($token);
  96.     }
  97.     public function updateSessionAfterLogin(AgentLoginEvent $event): void
  98.     {
  99.         $token $event->getContextToken();
  100.         $this->storefrontSubscriber->updateSession($token);
  101.     }
  102.     public function updateSessionAfterLogout(): void
  103.     {
  104.         $newToken Random::getAlphanumericString(32);
  105.         $this->storefrontSubscriber->updateSession($newTokentrue);
  106.     }
  107.     /**
  108.      * @throws JsonException
  109.      */
  110.     public function agentNotLoggedInHandler(ExceptionEvent $event): void
  111.     {
  112.         if (!$event->getRequest()->attributes->has(SalesChannelRequest::ATTRIBUTE_IS_SALES_CHANNEL_REQUEST)) {
  113.             return;
  114.         }
  115.         if (!$event->getThrowable() instanceof AgentNotLoggedInException) {
  116.             return;
  117.         }
  118.         $request $event->getRequest();
  119.         /** @noinspection PhpComposerExtensionStubsInspection */
  120.         $parameters = [
  121.             'redirectTo' => $request->attributes->get('_route'),
  122.             'redirectParameters' => json_encode($request->attributes->get('_route_params'), JSON_THROW_ON_ERROR),
  123.         ];
  124.         $redirectResponse = new RedirectResponse($this->router->generate('frontend.account.login.page'$parameters));
  125.         $event->setResponse($redirectResponse);
  126.     }
  127.     private function getRedirectRoute(SalesChannelContext $salesChannelContext): string
  128.     {
  129.         $redirectToCustomerList = (bool)$this->systemConfigService->get('VioRepresentativeLogin.config.redirectToCustomerList'$salesChannelContext->getSalesChannel()->getId());
  130.         if ($redirectToCustomerList) {
  131.             return 'frontend.representative.customer.list.page';
  132.         }
  133.         return 'frontend.representative.agent.home.page';
  134.     }
  135. }