src/EventListener/LocaleListener.php line 39

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use App\Application\Service\Session\SessionService;
  4. use App\Entity\System\Customer;
  5. use App\Service\EnvironmentService;
  6. use Doctrine\ORM\NonUniqueResultException;
  7. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpKernel\Event\RequestEvent;
  10. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  11. use Symfony\Contracts\Translation\TranslatorInterface;
  12. class LocaleListener
  13. {
  14.     private TranslatorInterface $translator;
  15.     private TokenStorageInterface $tokenStorage;
  16.     private EnvironmentService $environmentService;
  17.     private SessionService $sessionService;
  18.     private string $defaultLocale;
  19.     private array $locales;
  20.     public function __construct(
  21.         TranslatorInterface $translator,
  22.         TokenStorageInterface $tokenStorage,
  23.         ParameterBagInterface $parameterBag,
  24.         EnvironmentService $environmentService,
  25.         SessionService $sessionService
  26.     ) {
  27.         $this->translator $translator;
  28.         $this->tokenStorage $tokenStorage;
  29.         $this->environmentService $environmentService;
  30.         $this->sessionService $sessionService;
  31.         $this->defaultLocale $parameterBag->get('locale');
  32.         $this->locales $parameterBag->get('locales');
  33.     }
  34.     public function onKernelRequest(RequestEvent $event): void
  35.     {
  36.         if ($this->environmentService->isApi()) {
  37.             return;
  38.         }
  39.         $request $event->getRequest();
  40.         $urlLocale $this->getLocaleFromUrl($request);
  41.         if ($urlLocale) {
  42.             $this->setLocale($urlLocale$request);
  43.             return;
  44.         }
  45.         $browserLocale $this->getLocaleFromBrowser($request);
  46.         if ($browserLocale && str_contains($request->attributes->get('_route'), 'front_api')) {
  47.             $this->setLocale($browserLocale$request);
  48.             return;
  49.         }
  50.         $sessionLocale $request->getSession()->get('lang');
  51.         if (!$sessionLocale) {
  52.             if ($this->tokenStorage->getToken()) {
  53.                 /** @var Customer $user */
  54.                 $user $this->tokenStorage->getToken()->getUser();
  55.                 $userLocale $user->getLanguage()->getIsoCode();
  56.                 $this->setLocale($userLocale$request);
  57.                 return;
  58.             }
  59.             $locale $browserLocale ?: $this->defaultLocale;
  60.             $this->setLocale($locale$request);
  61.             return;
  62.         }
  63.         $this->setLocale($sessionLocale$request);
  64.     }
  65.     /**
  66.      * @throws NonUniqueResultException
  67.      */
  68.     private function setLocale(string $localeRequest $request): void
  69.     {
  70.         $request->setLocale($locale);
  71.         $this->translator->setLocale($locale);
  72.         $this->sessionService->setLocaleParameters($locale);
  73.     }
  74.     private function getLocaleFromBrowser(Request $request): ?string
  75.     {
  76.         if ($request->getLanguages()) {
  77.             return $request->getPreferredLanguage($this->locales);
  78.         }
  79.         return null;
  80.     }
  81.     private function isLocaleSupported(string $locale): bool
  82.     {
  83.         return \in_array($locale$this->localestrue);
  84.     }
  85.     private function getLocaleFromUrl(Request $request): ?string
  86.     {
  87.         $urlArray = \explode('/'$request->getPathInfo());
  88.         if (is_array($urlArray) && isset($urlArray[1]) && $this->isLocaleSupported($urlArray[1])) {
  89.             return $urlArray[1];
  90.         }
  91.         $lang $request->get('lang');
  92.         if ($lang && $this->isLocaleSupported($lang)) {
  93.             return $lang;
  94.         }
  95.         return null;
  96.     }
  97. }