* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use function Symfony\Component\String\u; /** * When visiting the homepage, this listener redirects the user to the most * appropriate localized version according to the browser settings. * * See https://symfony.com/doc/current/components/http_kernel.html#the-kernel-request-event * * @author Oleg Voronkovich */ class RedirectToPreferredLocaleSubscriber implements EventSubscriberInterface { private $urlGenerator; private $locales; private $defaultLocale; public function __construct(UrlGeneratorInterface $urlGenerator, string $locales, string $defaultLocale = null) { $this->urlGenerator = $urlGenerator; $this->locales = explode('|', trim($locales)); if (empty($this->locales)) { throw new \UnexpectedValueException('The list of supported locales must not be empty.'); } $this->defaultLocale = $defaultLocale ?: $this->locales[0]; if (!\in_array($this->defaultLocale, $this->locales, true)) { throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".', $this->defaultLocale, $locales)); } // Add the default locale at the first position of the array, // because Symfony\HttpFoundation\Request::getPreferredLanguage // returns the first element when no an appropriate language is found array_unshift($this->locales, $this->defaultLocale); $this->locales = array_unique($this->locales); } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => 'onKernelRequest', ]; } public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); // Ignore sub-requests and all URLs but the homepage if (!$event->isMasterRequest() || '/' !== $request->getPathInfo()) { return; } // Ignore requests from referrers with the same HTTP host in order to prevent // changing language for users who possibly already selected it for this application. $referrer = $request->headers->get('referer'); if (null !== $referrer && u($referrer)->ignoreCase()->startsWith($request->getSchemeAndHttpHost())) { return; } $preferredLanguage = $request->getPreferredLanguage($this->locales); if ($preferredLanguage !== $this->defaultLocale) { $response = new RedirectResponse($this->urlGenerator->generate('homepage', ['_locale' => $preferredLanguage])); $event->setResponse($response); } } }