src/EventSubscriber/RedirectToPreferredLocaleSubscriber.php line 63

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\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\HttpKernel\KernelEvents;
  15. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  16. /**
  17. * When visiting the homepage, this listener redirects the user to the most
  18. * appropriate localized version according to the browser settings.
  19. *
  20. * See https://symfony.com/doc/current/components/http_kernel/introduction.html#the-kernel-request-event
  21. *
  22. * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
  23. */
  24. class RedirectToPreferredLocaleSubscriber implements EventSubscriberInterface
  25. {
  26. private $urlGenerator;
  27. private $locales;
  28. private $defaultLocale;
  29. public function __construct(UrlGeneratorInterface $urlGenerator, string $locales, string $defaultLocale = null)
  30. {
  31. $this->urlGenerator = $urlGenerator;
  32. $this->locales = explode('|', trim($locales));
  33. if (empty($this->locales)) {
  34. throw new \UnexpectedValueException('The list of supported locales must not be empty.');
  35. }
  36. $this->defaultLocale = $defaultLocale ?: $this->locales[0];
  37. if (!in_array($this->defaultLocale, $this->locales, true)) {
  38. throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".', $this->defaultLocale, $locales));
  39. }
  40. // Add the default locale at the first position of the array,
  41. // because Symfony\HttpFoundation\Request::getPreferredLanguage
  42. // returns the first element when no an appropriate language is found
  43. array_unshift($this->locales, $this->defaultLocale);
  44. $this->locales = array_unique($this->locales);
  45. }
  46. public static function getSubscribedEvents(): array
  47. {
  48. return [
  49. KernelEvents::REQUEST => 'onKernelRequest',
  50. ];
  51. }
  52. public function onKernelRequest(RequestEvent $event): void
  53. {
  54. $request = $event->getRequest();
  55. // Ignore sub-requests and all URLs but the homepage
  56. if (!$event->isMainRequest() || '/' !== $request->getPathInfo()) {
  57. return;
  58. }
  59. // Ignore requests from referrers with the same HTTP host in order to prevent
  60. // changing language for users who possibly already selected it for this application.
  61. if (0 === mb_stripos($request->headers->get('referer'), $request->getSchemeAndHttpHost())) {
  62. return;
  63. }
  64. $preferredLanguage = $request->getPreferredLanguage($this->locales);
  65. if ($preferredLanguage !== $this->defaultLocale) {
  66. $response = new RedirectResponse($this->urlGenerator->generate('homepage', ['_locale' => $preferredLanguage]));
  67. $event->setResponse($response);
  68. }
  69. }
  70. }