用户区域设置在第一次请求时不起作用 [英] User locale does not work at first request

查看:109
本文介绍了用户区域设置在第一次请求时不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的网站正在运行主版本的Symfony.到目前为止,我已经能够使用网站上的 LocalListener逻辑 ,由于代码与我的版本不兼容,因此略有差异. (我认为)我只是这样简化了 onKernelRequest 方法:

My website is running Symfony, master version. So far, I was able to use the LocalListener logic from the website, with a slight difference due to code not being compatible with my version. (I think) I only simplified the onKernelRequest method this way:

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

    if ($locale = $request->get('_locale')) {
        $request->getSession()->set('_locale', $locale);
    }
    $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}

这样,我可以使用这些路径和新语言在页面上放置一个简单的语言选择器将在第一个请求时应用. (如果我离开"else"条件,就不会发生)

That way, I could put up a simple language selector on my page, using these paths, and the new language would apply at the first request. (it would not happen if I left the "else" condition)

然后,我想考虑存储在用户帐户中的语言环境,以防用户登录并在其个人资料中指定了语言环境.所以我在功能中添加了这段代码:

Then I wanted to take account of the locale stored in user accounts, in case the user is logged in and has specified a locale in his or her profile. So I added this piece of code in the function :

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

    $token = $this->container->get('security.context')->getToken();
    if (is_object($token)) {
    $user = $token->getUser();
    if (is_object($user)) {
        $userlocale = $user->getLocale();
        if ($userlocale) {
        $request->getSession()->set('_locale', $userlocale);
        $request->setLocale($userlocale);
        return;
        }
    }
}

    if ($locale = $request->get('_locale')) {
        $request->getSession()->set('_locale', $locale);
    }
    $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}

(抱歉缩进不良,不知何故stackoverflow不想正确缩进...)

( sorry for poor indentation, somehow stackoverflow does not want to indent it properly...)

基本上,它将检查用户是否已登录,是否已登录,是否已设置语言环境,如果已设置,则将语言环境设置为用户语言环境.现在可以使用,但是...并非立即生效.每当我登录或在个人资料中更改语言环境时,进入的下一页仍会位于先前设置的语言环境中.只有当我加载新页面时,它才能正确更改其翻译,并在下次请求时保持这种状态.

Basically it checks if a user is logged in, and if there is, if he or she has set a locale, and if they have, sets the locale to the user locale instead. Now this works, but... not instantly. Whenever I log in or change my locale in my profile, the next page I get to is still in the previously set locale. Only when I load a new page does it change its translations properly, and stays that way for the next requests.

这是我的问题:我应该添加一些内容来使这些更改在登录后和配置文件编辑后的请求上发生吗?

So here is my question: is there something I am supposed to add to make this change occur on those post-login and post-profile-edit requests?

推荐答案

非常感谢Elnur,我决定回到我的jms_i18n解决方案(请参阅Elnur的评论),然后发现

Well thanks to Elnur I decided to go back to my jms_i18n solution (see comments in Elnur's answer), and I found this question that helped me build my own solution. So I switched from an EventSubscriber extended class to a simple "unextended" class of my own. Here is the working code:

<?php
//src/myApp/MainBundle/EventListener/LocaleListener.php
namespace myApp\MainBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Cookie;

class LocaleListener
{
  private $container;

  public function __construct(ContainerInterface $container)
  {
    $this->container = $container;
  }

  public function onKernelRequest(GetResponseEvent $event)
  {
    if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
      return;
    }
    $request = $event->getRequest();
    if ($request->getRequestFormat() !== 'html') {
      return;
    }

    $token = $this->container->get('security.context')->getToken();
    if (is_object($token)) {
      $user = $token->getUser();
      if (is_object($user)) {
        $userlocale = $user->getLocale();
        if ($userlocale && $userlocale != $request->get('_locale')) {
          $parmArray = $request->get('_route_params');
          $parmArray['_locale'] = $userlocale;

          $redirectResponse = new RedirectResponse( $this->container->get('router')->generate($request->get('_route'), $parmArray) );
          $redirectResponse->headers->setCookie( new Cookie('b_locale', $userlocale, time() + 2592000) );

          $event->setResponse( $redirectResponse );
        }
      }
    }
  }
}

这是在服务中进行注册的方法:

And here is how to register it in services :

# app/config/config.yml
services:
    myapp_main.locale_listener:
        class: myApp\MainBundle\EventListener\LocaleListener
        arguments: ["@service_container"]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

非常感谢Elnur改变了主意.

Many thanks to Elnur for changing my mind.

这篇关于用户区域设置在第一次请求时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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