src/EventSubscriber/DefaultLocaleSubscriber.php line 162

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace App\EventSubscriber;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpKernel\Event\RequestEvent;
  13. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  14. use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\HttpFoundation\RequestStack;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\Routing\RequestContextAwareInterface;
  19. use App\Admin\Entity\StdLanguages;
  20. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  21. use Symfony\Component\HttpFoundation\Cookie;
  22. use Doctrine\ORM\EntityManagerInterface;
  23. /**
  24.  * When visiting the homepage, this listener redirects the user to the most
  25.  * appropriate localized version according to the browser settings.
  26.  *
  27.  * See https://symfony.com/doc/current/components/http_kernel.html#the-kernel-request-event
  28.  *
  29.  * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
  30.  */
  31. class DefaultLocaleSubscriber implements EventSubscriberInterface
  32. {
  33.     private $availablelocales = array();
  34.     private $defaultlocale null;
  35.     private $router;
  36.     private $requeststack;
  37.     private $mainrequest;
  38.     /**
  39.      * @var EntityManagerInterface
  40.      */
  41.     private $entitymanager;
  42.     public function __construct(EntityManagerInterface $entityManagerRequestStack $requestStackRequestContextAwareInterface $router null)
  43.     {
  44.         $this->requeststack $requestStack;
  45.         $this->mainrequest $requestStack->getMainRequest();
  46.         $this->router $router;
  47.         $this->entitymanager $entityManager;
  48.     }
  49.     
  50.     public static function getSubscribedEvents(): array
  51.     {
  52.         return [
  53.             KernelEvents::REQUEST => ['onKernelRequest'17],
  54.             KernelEvents::FINISH_REQUEST => ['onKernelFinishRequest'1],
  55.             KernelEvents::RESPONSE => ['onKernelResponse'],
  56.         ];
  57.     }
  58.     
  59.     public function onKernelRequest(RequestEvent $event): void
  60.     {
  61.         $request $event->getRequest();
  62.         
  63.         if (in_array($request->attributes->get('_route'),['liip_imagine_filter''_profiler''_wdt']))
  64.             return; // Ignore liip imagine and profiler requests
  65.         $this->loadLanguages();
  66.         
  67.         $request->setDefaultLocale($this->defaultlocale);
  68.         
  69.         // Find the first non-null locale from various sources
  70.         $locale $this->urlLocale($request);
  71.         
  72.         // Check if session exists before using it
  73.         if ($locale === null && $request->hasSession()) {
  74.             $session $request->getSession();
  75.             if ($session->isStarted()) {
  76.                 $locale $this->sessionLocale($session);
  77.             }
  78.         }
  79.         
  80.         if ($locale === null) {
  81.             $locale $this->cookieLocale($request);
  82.         }
  83.         if ($locale === null) {
  84.             $locale $this->browserLocale($request);
  85.         }
  86.         if ($locale === null) {
  87.             $locale $this->defaultlocale;
  88.         }
  89.           
  90.         // Only set the session if it exists and is started
  91.         if ($request->hasSession()) {
  92.             $session $request->getSession();
  93.             if ($session->isStarted()) {
  94.                 $session->set("locale"$locale);
  95.             }
  96.         }
  97.         
  98.         $request->setLocale($locale);
  99.         $this->setRouterContext($request);
  100.         $this->locale $locale;
  101.         
  102.         if (!($this->mainrequest->attributes->get('webpackEntries'))) {
  103.             $this->mainrequest->attributes->set('webpackEntries', []);
  104.         }
  105.     }
  106.     
  107.     public function onKernelFinishRequest(FinishRequestEvent $event)
  108.     {
  109.         if (null !== $parentRequest $this->requeststack->getParentRequest()) {
  110.             $this->setRouterContext($parentRequest);
  111.         }
  112.     }
  113.     public function onKernelResponse(ResponseEvent $event)
  114.     {
  115.         // Use a single condition to check for profiler routes
  116.         if (in_array($event->getRequest()->attributes->get('_route'), ['liip_imagine_filter''_profiler''_wdt']) ||
  117.             strpos($event->getRequest()->getRequestURI(), '_wdt') !== false || 
  118.             strpos($event->getRequest()->getRequestURI(), '_profiler') !== false) {
  119.             return; // Ignore profiler and liip imagine requests
  120.         }
  121.         
  122.         if (sizeof($this->availablelocales) > && \in_array($event->getRequest()->getLocale(), $this->availablelocales))
  123.             $event->getResponse()->headers->setCookie(Cookie::create('locale'$event->getRequest()->getLocale(), time() + (365 24 60 60),getenv("COOKIE_PATH"),getenv("COOKIE_DOMAIN")));
  124.     }
  125.     private function setRouterContext(Request $request)
  126.     {
  127.         if (null !== $this->router) {
  128.             $this->router->getContext()->setParameter('_locale'$request->getLocale());
  129.         }
  130.     }
  131.     private function urlLocale($request)
  132.     {
  133.         if (\in_array(\strtolower($request->query->get('_locale','')),$this->availablelocales))
  134.         {
  135.             return \strtolower($request->query->get('_locale'));
  136.         }
  137.         list($null$segment) = \explode('/'$request->getRequestURI());
  138.         if (\in_array(\strtolower($segment),$this->availablelocales))
  139.         {
  140.             return \strtolower($segment);
  141.         }
  142.         return null;
  143.     }
  144.     private function sessionLocale(SessionInterface $session)
  145.     {
  146.         if($session->get("locale")){
  147.            return $session->get("locale");
  148.         }
  149.         return null;
  150.     }
  151.     private function cookieLocale($request)
  152.     {
  153.         return \in_array(\strtolower($request->cookies->get('locale','')),$this->availablelocales) ? $request->cookies->get('locale','') : null;
  154.     }
  155.     private function browserLocale($request)
  156.     {
  157.         $http_accept $request->server->get('HTTP_ACCEPT_LANGUAGE','');
  158.         $locale null;
  159.         $locales = []; // Initialize $locales array to avoid undefined variable
  160.         
  161.         if(\strlen($http_accept) > 1)
  162.         {
  163.             # Split possible languages into array
  164.             $x \explode(",",$http_accept);
  165.             foreach ($x as $val)
  166.             {
  167.                 #check for q-value and create associative array. No q-value means 1 by rule
  168.                 if(\preg_match("/(.*);q=([0-1]{0,1}\.\d{0,4})/i",$val,$matches))
  169.                     $locales[$matches[1]] = (float)$matches[2];
  170.                 else
  171.                     $locales[$val] = 1.0;
  172.             }
  173.             #return default language (highest q-value)
  174.             $qval 0.0;
  175.             foreach ($locales as $langAndCountry => $q)
  176.             {
  177.                 $langAndCountry \str_replace"_""-"$langAndCountry );
  178.                 $arr \explode("-"$langAndCountry);
  179.                 $lang $arr[0];
  180.                 if ($q $qval)
  181.                 {
  182.                     if (\in_array(\strtolower($langAndCountry),$this->availablelocales))
  183.                     {
  184.                         $qval = (float)$q;
  185.                         $locale \strtolower($langAndCountry);
  186.                     }
  187.                     else if (\in_array(\strtolower($lang),$this->availablelocales))
  188.                     {
  189.                         $qval = (float)$q;
  190.                         $locale \strtolower($lang);
  191.                     }
  192.                 }
  193.             }
  194.         }
  195.         
  196.         return $locale;
  197.     }
  198.     private function loadLanguages()
  199.     {
  200.         if (is_null($this->defaultlocale))
  201.         {
  202.             if ($languages $this->entitymanager->getRepository(StdLanguages::class)->findBy(['isActive' => 1,'isPublic' => 1]))
  203.             {
  204.                 foreach ($languages as $language)
  205.                 {
  206.                     $this->availablelocales[] = $language->getLanguageCode();
  207.                     $language->getIsDefault() && $this->defaultlocale $language->getLanguageCode();
  208.                 }
  209.             }
  210.     
  211.             if (is_null($this->defaultlocale)) {
  212.                 throw new \UnexpectedValueException('The default locale is not defined in the database.');
  213.             }
  214.     
  215.             if (empty($this->availablelocales)) {
  216.                 throw new \UnexpectedValueException('The list of supported locales must not be empty.');
  217.             }        
  218.             
  219.             $this->defaultlocale $this->defaultlocale ?: $this->availablelocales[0];
  220.             
  221.             if (!\in_array($this->defaultlocale$this->availablelocalestrue)) {
  222.                 throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".'$this->defaultlocaleimplode(', '$this->availablelocales)));
  223.             }
  224.         }
  225.     }
  226. }