如何使用 Symfony 4 更改用户区域设置?

我正在尝试使用 Symfony 从数据库中的“区域设置”字段更改用户区域设置。我阅读了 Symfony 手册(例如如何粘贴会话),但在我的应用程序中没有任何作用。翻译器仍然获得默认语言环境...


我创建了侦听器、订阅者...来动态更改语言环境,但是由于它们是在防火墙侦听器之前加载的,因此我无法更改当前值。


我试图更改优先订阅者,但我丢失了用户实体。我试图在控制器中设置语言环境请求,但我认为为时已晚。


我不想在 URL 中添加语言环境。


这是我的订阅者 - 听众 - 代码:


public function onKernelRequest(RequestEvent $event)

{

   $user = $this->tokenStorage->getToken()->getUser();

   $request = $event->getRequest();

   $request->setLocale($user->getLocale());

}  

在订阅者中,我添加了:


public static function getSubscribedEvents()

{

   return [

     KernelEvents::REQUEST => [['onKernelRequest', 0]],

   ];

}

在这里,我的完整代码:


框架.yml:


default_locale: fr

服务.yml:


parameters:

    locale: 'fr'

    app_locales: fr|en|

翻译.yml:


framework:

    default_locale: '%locale%'

    translator:

        paths:

            - '%kernel.project_dir%/translations'

        fallbacks:

            - '%locale%'

LocaleSubscriber.php:


namespace App\EventSubscriber;


use Symfony\Component\EventDispatcher\EventSubscriberInterface;

use Symfony\Component\HttpKernel\Event\RequestEvent;

use Symfony\Component\HttpKernel\KernelEvents;


class LocaleSubscriber implements EventSubscriberInterface

{

    private $defaultLocale;


    public function __construct($defaultLocale = 'en')

    {

        $this->defaultLocale = $defaultLocale;

    }


    public function onKernelRequest(RequestEvent $event)

    {

        $request = $event->getRequest();

        if (!$request->hasPreviousSession()) {

            return;

        }

        // try to see if the locale has been set as a _locale routing parameter

        if ($locale = $request->attributes->get('_locale')) {

            $request->getSession()->set('_locale', $locale);

        } else {

            // if no explicit locale has been set on this request, use one from the session

            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));

        }

    }

斯蒂芬大帝
浏览 86回答 2
2回答

MYYA

使用 查找防火墙侦听器的优先级debug:event kernel.request。确保您UserLocaleSubscriber在防火墙侦听器之后立即执行。自动装配TranslatorInterface并手动设置翻译器区域设置。// src/EventSubscriber/UserLocaleSubscriber.phpnamespace App\EventSubscriber;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpFoundation\Session\SessionInterface;use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;use Symfony\Component\Security\Http\SecurityEvents;use Symfony\Contracts\Translation\TranslatorInterface;/** * Stores the locale of the user in the session after the * login. This can be used by the LocaleSubscriber afterwards. */class UserLocaleSubscriber implements EventSubscriberInterface{    private $session;    private $translator;    public function __construct(SessionInterface $session, TranslatorInterface $translator)    {        $this->session = $session;        $this->translator = $translator;    }    public function onInteractiveLogin(InteractiveLoginEvent $event)    {        $user = $event->getAuthenticationToken()->getUser();        if (null !== $user->getLocale()) {            $this->translator->setLocale($user->getLocale());        }    }    public static function getSubscribedEvents()    {        return [            SecurityEvents::INTERACTIVE_LOGIN => ['onInteractiveLogin', 7]        ];    }}

墨色风雨

如果没有看到您正在使用的完整代码,很难提供帮助。Symfony 也有它自己的 LocaleListener。确保首先执行您的。    /**     * @return array     */    public static function getSubscribedEvents()    {        return [            // must be registered before (i.e. with a higher priority than) the default Locale listener            KernelEvents::REQUEST => [['onKernelRequest', 20]],        ];    }
打开App,查看更多内容
随时随地看视频慕课网APP