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

查看:33
本文介绍了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 AcmeUserBundleEventListener;
use SymfonyComponentHttpFoundationSessionSession;
use SymfonyComponentSecurityHttpEventInteractiveLoginEvent;
use SymfonyComponentHttpKernelEventGetResponseEvent;
use SymfonyComponentHttpKernelHttpKernelInterface;

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 SymfonyComponentHttpKernelEventGetResponseEvent $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 SymfonyComponentSecurityHttpEventInteractiveLoginEvent $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: AcmeUserBundleEventListenerLanguageListener
        calls:
            - [ setSession, [@session] ]
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

    acme.language.kernel_request_listener:
        class: AcmeUserBundleEventListenerLanguageListener
        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天全站免登陆