symfony 2根据存储在DB中的用户首选项设置区域设置

use*_*137 6 php locale symfony

我正在尝试根据存储在数据库中的当前用户的首选项设置区域设置.

因此,我们的User类有一个getPreferredLanguage,它返回一个语言环境标识('en','fr_FR'等).

我考虑过以下方法:

  • 注册一个订阅KernelEvents :: REQUEST事件的"locale"侦听器服务.
  • 此服务可以访问安全上下文(通过其构造函数)
  • 此服务的onKernelRequest方法尝试从安全上下文中获取用户,获取用户的首选语言环境,并将其设置为请求的语言环境.

不幸的是,这不起作用.当调用"locale"侦听器服务的onRequestEvent方法时,安全上下文没有令牌.看起来上下文监听器是在一个非常晚的阶段(优先级为0)调用的,并且不可能告诉我的"locale"监听器在安全上下文之前运行.

有谁知道如何修复这种方法,或建议另一种方法?

Emi*_*aos 2

您可能对区域设置侦听器感兴趣,我在此答案中发布了该侦听器:Symfony2 区域设置检测:不考虑会话中的 _locale

编辑:如果用户在个人资料中更改其语言,那没有问题。如果您使用的是 FOSUserBundle (master),您可以挂钩配置文件编辑成功事件。否则,如果您使用的是自制系统,则在您的配置文件控制器中。以下是 FOSUserBundle 的示例:

<?php
namespace Acme\UserBundle\EventListener;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ChangeLanguageListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
                FOSUserEvents::PROFILE_EDIT_SUCCESS => 'onProfileEditSuccess',
        );
    }

    public function onProfileEditSuccess(FormEvent $event)
    {
        $request = $event->getRequest();
        $session = $request->getSession();
        $form = $event->getForm();
        $user = $form->getData();
        $lang = $user->getLanguage();

        $session->set('_locale', $lang);
        $request->setLocale($lang);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在 services.yml 中

services:
    acme.change_language:
        class: Acme\UserBundle\EventListener\ChangeLanguageListener
        tags:
            - { name: kernel.event_subscriber }
Run Code Online (Sandbox Code Playgroud)

对于多个浏览器中的多个会话没有问题,因为每个新会话都需要新的登录。嗯,好吧,更改语言后不会,因为只会更新当前会话。但您可以修改 LanguageListener 以支持这一点。
如果管理员更改语言的情况应该是微不足道的。