custom/static-plugins/LnbRedirect/src/Subscriber/KernelRequestSubscriber.php line 46

Open in your IDE?
  1. <?php
  2. namespace Lnb\Shopware6\LnbRedirect\Subscriber;
  3. use Doctrine\DBAL\Connection;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
  6. use Symfony\Component\HttpFoundation\RedirectResponse;
  7. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  8. use Symfony\Component\HttpKernel\Event\RequestEvent;
  9. use Symfony\Component\HttpKernel\KernelEvents;
  10. class KernelRequestSubscriber implements EventSubscriberInterface
  11. {
  12.     private Connection $connection;
  13.     public function __construct(Connection $connection)
  14.     {
  15.         $this->connection $connection;
  16.     }
  17.     public static function getSubscribedEvents(): array
  18.     {
  19.         return [
  20.             KernelEvents::REQUEST => ['onKernelRequest'35// before RouterListener and after StorefrontSubscriber because we need the session
  21.         ];
  22.     }
  23.     public function onKernelRequest(RequestEvent $event): void
  24.     {
  25.         try {
  26.             if (!$event->getRequest()->getSession() instanceof SessionInterface) {
  27.                 return;
  28.             }
  29.         } catch (SessionNotFoundException $e) { //important to catch this
  30.             return;
  31.         }
  32.         $pathInfo $event->getRequest()->attributes->get('sw-original-request-uri');
  33.         if (!$pathInfo) {
  34.             return;
  35.         }
  36.         $pathInfo substr($pathInfo1);
  37.         $salesChannelId $event->getRequest()->getSession()->get('sw-sales-channel-id');
  38.         if (!$salesChannelId) {
  39.             return;
  40.         }
  41.         if ($this->hasTrailingSlash($pathInfo) || !$this->isSeoUrl($pathInfo$salesChannelId)) {
  42.             return;
  43.         }
  44.         $event->stopPropagation(); //important to stop propagation
  45.         $response = new RedirectResponse($event->getRequest()->getSchemeAndHttpHost() . '/' $pathInfo '/'301); //redirect to absolute url
  46.         $response->send();
  47.     }
  48.     private function hasTrailingSlash(string $pathInfo): bool
  49.     {
  50.         return str_ends_with($pathInfo'/');
  51.     }
  52.     private function isSeoUrl(string $pathInfostring $salesChannelId): bool
  53.     {
  54.         $query "SELECT count(id) as count
  55.         FROM `seo_url`
  56.         WHERE `seo_path_info` = :seo_path_info AND `sales_channel_id` = UNHEX(:sales_channel_id) AND `is_canonical` = '1'";
  57.         try {
  58.             $result $this->connection
  59.                 ->prepare($query)
  60.                 ->executeQuery(['sales_channel_id' => $salesChannelId'seo_path_info' => $pathInfo '/']);
  61.             return $result->fetchOne() > 0;
  62.         } catch (\Exception $e) {
  63.             return false;
  64.         }
  65.     }
  66. }