change - symfony 4 set locale
Detección de configuración regional de Symfony2: no considerando_locale en la sesión (2)
A partir de Symfony 2.1, la configuración regional no se almacena en la sesión, sino en la solicitud. Qué puedes hacer para resolverlo:
- restaurar la forma antigua de guardar la configuración regional. Puede leer cómo hacer esto en el archivo de actualización
edite LocaleListener para almacenar la configuración regional en la solicitud:
if (!$request->attributes->has(''locale'')) { $request->setLocale(...); }
Estoy tratando de implementar un LocaleListener que detecta el idioma preferido del usuario (considerando el encabezado Accept-Language) y lo almacena en sesión para evitar revisar cada solicitud. Desarrollé el siguiente código para lograr esto:
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);
}
}
El código está funcionando, el idioma preferido se almacena en sesión, pero Symfony no está considerando la configuración regional almacenada en la sesión para traducir cadenas. En mi caso, mi idioma preferido era ''pt_BR'' y cuando escapo:
{{ app.request.locale }}
symfony está escapando ''en''. ¿No debería Symfony considerar el valor almacenado en la sesión (''_ locale'') para definir la configuración regional de la solicitud? ¿Es esto un comportamiento correcto? ¿Cómo puedo lograr eso?
Aquí hay un oyente de lenguaje de trabajo. el segundo método es cambiar el idioma a las preferencias de los usuarios, que el usuario elige. Puede omitir este método, si su usuario no tiene la facilidad de definir su idioma.
<?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);
}
}
}
en su 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 }
Ah, y tienes que definir undefined fallback_language en config.yml para que funcione.
framework:
translator: { fallback: "undefined" }
default_locale: "en"