87 lines
3.1 KiB
PHP
87 lines
3.1 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* 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 <oleg-voronkovich@yandex.ru>
|
|
*/
|
|
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);
|
|
}
|
|
}
|
|
}
|