<?php
namespace App\EventListener;
use App\Service\System\ShortUrlService;
use Sylius\Component\Locale\Provider\LocaleProviderInterface;
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webmozart\Assert\Assert;
final class NonChannelLocaleListener
{
/** @var LocaleProviderInterface */
private $channelBasedLocaleProvider;
/** @var FirewallMap */
private $firewallMap;
/** @var string[] */
private $firewallNames;
/** @var ShortUrlService */
private $shortUrlService;
/**
* @param string[] $firewallNames
*/
public function __construct(
LocaleProviderInterface $channelBasedLocaleProvider,
FirewallMap $firewallMap,
array $firewallNames,
ShortUrlService $shortUrlService
) {
Assert::notEmpty($firewallNames);
Assert::allString($firewallNames);
$this->channelBasedLocaleProvider = $channelBasedLocaleProvider;
$this->firewallMap = $firewallMap;
$this->firewallNames = $firewallNames;
$this->shortUrlService = $shortUrlService;
}
/**
* @throws NotFoundHttpException
*/
public function restrictRequestLocale(GetResponseEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
if ($request->attributes && in_array($request->attributes->get('_route'), ['_wdt', '_profiler', '_profiler_search', '_profiler_search_results'])) {
return;
}
$currentFirewall = $this->firewallMap->getFirewallConfig($request);
if (!$this->isFirewallSupported($currentFirewall)) {
return;
}
$requestLocale = 'ro';
$session = $request->getSession();
if ($session->has('localeCode')) {
$requestLocale = $session->get('localeCode');
}
if (!in_array($requestLocale, $this->channelBasedLocaleProvider->getAvailableLocalesCodes(), true)) {
//try to find if the locale is not a short url cod
if (!$this->shortUrlService->checkIfRequestedParamIsShortUrlCode($requestLocale, $event)) {
$response = new RedirectResponse('/');
$event->setResponse($response);
} else {
$requestLocale = 'ro';
$session->set('localeCode', $requestLocale);
}
}
}
private function isFirewallSupported(?FirewallConfig $firewall = null): bool
{
return
null !== $firewall &&
in_array($firewall->getName(), $this->firewallNames)
;
}
}