Symfony2 locale recognition: apart from _locale in a session

I am trying to implement a LocaleListener that defines the user's preferred language (given the Accept-Language header) and stores it in the session so as not to check it for every request. To do this, I developed the code below:

public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; } $preferredLocale = $request->getPreferredLanguage($this->availableLocales); if ($this->container->has('session')) { $session = $this->container->get('session'); if (!$session->has('_locale')) { $session->set('_locale', $preferredLocale); } } else { $request->setLocale($preferredLocale); } } 

The code works, the preferred language is stored in the session, but symfony does not consider the locale stored in the session to translate strings. In my case, my preferred language was "pt_BR", and when I run away:

 {{ app.request.locale }} 

Symfony eludes en. Should symfony examine the value stored in the session ('_ locale') to determine the locale of the request? Is this the right behavior? How can i do this?

+5
source share
2 answers

Here is a working language listener. the second way is to change the language to the user preferences that the user selects. You can omit this method if your user does not have the ability to determine their language.

 <?php namespace Acme\UserBundle\EventListener; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; class LanguageListener { private $session; public function setSession(Session $session) { $this->session = $session; } /** * kernel.request event. If a guest user doesn't have an opened session, locale is equal to * "undefined" as configured by default in parameters.ini. If so, set as a locale the user's * preferred language. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event */ public function setLocaleForUnauthenticatedUser(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; } $request = $event->getRequest(); if ('undefined' == $request->getLocale()) { if ($locale = $request->getSession()->get('_locale')) { $request->setLocale($locale); } else { $request->setLocale($request->getPreferredLanguage()); } } } /** * security.interactive_login event. If a user chose a language in preferences, it would be set, * if not, a locale that was set by setLocaleForUnauthenticatedUser remains. * * @param \Symfony\Component\Security\Http\Event\InteractiveLoginEvent $event */ public function setLocaleForAuthenticatedUser(InteractiveLoginEvent $event) { $user = $event->getAuthenticationToken()->getUser(); if ($lang = $user->getLanguage()) { $this->session->set('_locale', $lang); } } } 

in your services.yml:

 services: acme.language.interactive_login_listener: class: Acme\UserBundle\EventListener\LanguageListener calls: - [ setSession, [@session] ] tags: - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser } acme.language.kernel_request_listener: class: Acme\UserBundle\EventListener\LanguageListener tags: - { name: kernel.event_listener, event: kernel.request, method: setLocaleForUnauthenticatedUser } 

Oh, and you need to define undefined fallback_language in config.yml to make it work.

 framework: translator: { fallback: "undefined" } default_locale: "en" 
+15
source

As in Symfony 2.1, the locale is not saved in the session, but in the request. What you can do to solve it:

  • restore the old way to save the locale. You can read how to do this in the update file.
  • edit the LocaleListener to save the locale in the query:

     if (!$request->attributes->has('locale')) { $request->setLocale(...); } 
+7
source

Source: https://habr.com/ru/post/945327/


All Articles