<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-04-18
* Time: 16:48
*/
namespace App\EventSubscriber;
use App\Entity\SEO\PageMetadata;
use App\Repository\PageMetadataRepository;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class PageMetadataSubscriber implements EventSubscriberInterface
{
private string $defaultCity;
private static array $firewallsRequiredSeo = ['main'];
public function __construct(
protected PageMetadataRepository $seoRepository,
protected FirewallMap $firewallMap,
ParameterBagInterface $parameterBag
)
{
$this->defaultCity = (string)$parameterBag->get('default_city');
}
public function loadPage(ControllerEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
if (!$this->isSeoRequired($request)) {
return;
}
$localizedUri = $request->getRequestUri();
$uri = str_replace('/en', '', $localizedUri);
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
/**
* Сначала ищем тексты в базе по полному совпадению URI.
* Если запись в базе СЕО-текстов не найдена по полному URI и
* страница является постраничным выводом - делаем фолбэк к первой странице.
* Если запись все еще не найдена и открыта страница списка анкет по дефолтному городу,
* ищем тексты для корня сайта.
*/
/**
* Сначала ищем тексты в базе по полному совпадению URI.
* Если запись в базе СЕО-текстов не найдена по полному URI и
* страница является постраничным выводом - делаем фолбэк к первой странице.
* Если запись все еще не найдена и открыта страница списка анкет по дефолтному городу,
* ищем тексты для корня сайта.
*/
$page = $this->seoRepository->ofUri($uri);
if (null !== $page) {
$request->attributes->set(PageMetadata::PAGE_REQUEST_ATTRIBUTE, $page);
} elseif (preg_match('/page\d+\/?$/', $uri, $matches)) {
$uri = str_replace($matches[0], '', $uri);
$fallbackPage = $this->seoRepository->ofUri($uri);
if (null === $page && $uri === "/{$this->defaultCity}/") {
$fallbackPage = $this->seoRepository->ofUri('/');
}
$request->attributes->set(PageMetadata::FALLBACK_REQUEST_ATTRIBUTE, $fallbackPage);
}
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'loadPage',
];
}
private function isSeoRequired(Request $request): bool
{
$firewallConfig = $this->firewallMap->getFirewallConfig($request);
if (!$firewallConfig) {
return true;
}
return in_array($firewallConfig->getName(), self::$firewallsRequiredSeo);
}
}