首页 > 解决方案 > 基于用户偏好的区域设置

问题描述

我尝试根据用户设置(即用户实体中的“语言”属性)设置语言环境,但在第一次请求时失败(用户经过身份验证),因为在 FirewallListener 之前调用了 LocaleListener(以及 TranslatorListener)。

我在用户会话期间尝试了这个示例使语言环境“粘滞”,但在第一次请求时,默认语言环境(在配置中)是“fr”,我的用户用“en”定义了他的语言,最后页面以法语显示。

诀窍可能是创建一个侦听器(在 LocaleListener 或 TranslatorListener 之前调用)以从另一个方法获取用户的语言环境,但我找不到要使用的方法。你有什么建议吗?

标签: phpsymfonylocalesymfony4

解决方案


最后,我使用 Compiler Pass 覆盖了 TranslatorListener 定义,现在在 FirewallListener 之后调用。

class OverrideTranslatorListenerCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if ($container->hasDefinition('translator_listener')) {
            $definition = $container->getDefinition('translator_listener');
            $definition->setTags([
                'kernel.event_listener' => [
                    [
                        'event' => KernelEvents::REQUEST,
                        'method' => 'onKernelRequest',
                        'priority' => 2, // 10 before
                    ],
                    [
                        'event' => KernelEvents::FINISH_REQUEST,
                        'method' => 'onKernelFinishRequest',
                        'priority' => 0, // not changed, needed because overridding ALL tags
                    ],
                ],
            ]);
        }
    }
}

还有我的订阅者

class LocaleSubscriber implements EventSubscriberInterface
{
    ...

    /**
     * @var Security
     */
    private $security;

    public function __construct(..., Security $security)
    {
        ...

        $this->security = $security;
    }

    public function onKernelRequest(GetResponseEvent $event): void
    {
        $request = $event->getRequest();
        if (!$event->isMasterRequest()) {
            return;
        }

        if (null !== ($user = $this->security->getUser())) {
            $request->setLocale($user->getLanguage());

            return;
        }

        ...
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest', 4],
        ];
    }

我希望这能有所帮助;)


推荐阅读