src/EventSubscriber/PageMetadataSubscriber.php line 34

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by simpson <simpsonwork@gmail.com>
  4.  * Date: 2019-04-18
  5.  * Time: 16:48
  6.  */
  7. namespace App\EventSubscriber;
  8. use App\Entity\SEO\PageMetadata;
  9. use App\Repository\PageMetadataRepository;
  10. use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
  11. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. class PageMetadataSubscriber implements EventSubscriberInterface
  17. {
  18.     private string $defaultCity;
  19.     private static array $firewallsRequiredSeo = ['main'];
  20.     public function __construct(
  21.         protected PageMetadataRepository $seoRepository,
  22.         protected FirewallMap $firewallMap,
  23.         ParameterBagInterface $parameterBag
  24.     )
  25.     {
  26.         $this->defaultCity = (string)$parameterBag->get('default_city');
  27.     }
  28.     public function loadPage(ControllerEvent $event): void
  29.     {
  30.         if (!$event->isMasterRequest()) {
  31.             return;
  32.         }
  33.         $request $event->getRequest();
  34.         if (!$this->isSeoRequired($request)) {
  35.             return;
  36.         }
  37.         $localizedUri $request->getRequestUri();
  38.         $uri str_replace('/en'''$localizedUri);
  39.         if (false !== $pos strpos($uri'?')) {
  40.             $uri substr($uri0$pos);
  41.         }
  42.         /**
  43.          * Сначала ищем тексты в базе по полному совпадению URI.
  44.          * Если запись в базе СЕО-текстов не найдена по полному URI и
  45.          * страница является постраничным выводом - делаем фолбэк к первой странице.
  46.          * Если запись все еще не найдена и открыта страница списка анкет по дефолтному городу,
  47.          * ищем тексты для корня сайта.
  48.          */
  49.         /**
  50.          * Сначала ищем тексты в базе по полному совпадению URI.
  51.          * Если запись в базе СЕО-текстов не найдена по полному URI и
  52.          * страница является постраничным выводом - делаем фолбэк к первой странице.
  53.          * Если запись все еще не найдена и открыта страница списка анкет по дефолтному городу,
  54.          * ищем тексты для корня сайта.
  55.          */
  56.         $page $this->seoRepository->ofUri($uri);
  57.         if (null !== $page) {
  58.             $request->attributes->set(PageMetadata::PAGE_REQUEST_ATTRIBUTE$page);
  59.         } elseif (preg_match('/page\d+\/?$/'$uri$matches)) {
  60.             $uri str_replace($matches[0], ''$uri);
  61.             $fallbackPage $this->seoRepository->ofUri($uri);
  62.             if (null === $page && $uri === "/{$this->defaultCity}/") {
  63.                 $fallbackPage $this->seoRepository->ofUri('/');
  64.             }
  65.             $request->attributes->set(PageMetadata::FALLBACK_REQUEST_ATTRIBUTE$fallbackPage);
  66.         }
  67.     }
  68.     /**
  69.      * @inheritDoc
  70.      */
  71.     public static function getSubscribedEvents()
  72.     {
  73.         return [
  74.             KernelEvents::CONTROLLER => 'loadPage',
  75.         ];
  76.     }
  77.     private function isSeoRequired(Request $request): bool
  78.     {
  79.         $firewallConfig $this->firewallMap->getFirewallConfig($request);
  80.         if (!$firewallConfig) {
  81.             return true;
  82.         }
  83.         return in_array($firewallConfig->getName(), self::$firewallsRequiredSeo);
  84.     }
  85. }