Symfony2语言环境检测:在会话中不考虑_locale [英] Symfony2 locale detection: not considering _locale in session

查看:57
本文介绍了Symfony2语言环境检测:在会话中不考虑_locale的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个LocaleListener,它检测用户的首选语言(考虑Accept-Language标头)并将其存储在会话中,以避免每次请求都对其进行检查.我已经开发了以下代码来完成此任务:

I'm trying to implement a LocaleListener that detects user's preferred language (considering Accept-Language header) and stores it in session to avoid checking it every request. I've developed the code below to accomplish this:

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);
    }
}

代码正在运行,首选语言存储在会话中,但是symfony并未考虑存储在会话中的语言环境来翻译字符串.就我而言,我的首选语言是"pt_BR",当我逃脱时:

The code is working, the preferred language is being stored in session, but symfony isn't considering the locale stored in session to translate strings. In my case, my preferred language was 'pt_BR' and when I escape:

{{ app.request.locale }}

symfony正在转义为"en". symfony是否不应该考虑存储在session('_ locale')中的值来定义请求区域设置?这是正确的行为吗?我该怎么办?

symfony is escaping 'en'. Shouldn't symfony be considering the value stored in session('_locale') to define request locale? Is this a correct behavior? How can I accomplish that?

推荐答案

这是一个有效的语言侦听器.第二种方法是将语言更改为用户选择的用户首选项.如果您的用户无法定义其语言,则可以忽略此方法.

Here is a working language listener. the second method is to change the language to the users preferences, which the user chooses. You can omit this method, if your user haven't the facility to define 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);
        }
    }
}

在您的services.yml中:

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 }

哦,您必须在config.yml中定义一个未定义的fallback_language才能使它工作.

Oh, and you have to define an undefined fallback_language in config.yml to get it work.

framework:
    translator:      { fallback: "undefined" }
    default_locale:  "en"

这篇关于Symfony2语言环境检测:在会话中不考虑_locale的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆