我想在用户发出的每个请求中存储用户使用的最后一个区域设置。我已经在数据库中创建了一个Field,只需要最好的练习方式,而不需要在每个Controller中进行大的修改。
谢谢大家。
答案 0 :(得分:1)
您可以将您的语言环境存储在会话中,并将其与事件侦听器一起使用。并在用户登录时设置会话中的用户区域设置。
-LocaleListener:将语言环境存储在会话
中的会话和用户区域设置中-UserLocaleListener:在用户登录时设置会话
中的用户区域设置<?php
namespace YourApp\YourBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'en')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest17(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest17', 17)),
);
}
}
第二次服务:
<?php
namespace YourApp\YourBundle\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 UserLocaleListener
{
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->getLocale()) {
$event->getRequest()->setLocale($lang);
$this->session->set('_locale', $lang);
}
}
}
services.yml
services:
yourapp_your.locale_listener:
class: YourApp\YourBundle\EventListener\LocaleListener
arguments: ["%kernel.default_locale%"]
tags:
- { name: kernel.event_subscriber }
yourapp_your.locale.interactive_login_listener:
class: YourApp\YourBundle\EventListener\UserLocaleListener
calls:
- [ setSession, [@session] ]
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }
这是使用
答案 1 :(得分:0)
这是我在数据库中保存每个请求的语言环境的实现。 这对我来说是必要的,因为我需要为简报保留语言环境。
LocaleListener:
namespace MyApp\MyBundle\EventListener;
use \Symfony\Component\HttpKernel\Event\GetResponseEvent;
use \Symfony\Component\HttpKernel\KernelEvents;
use \Symfony\Component\EventDispatcher\EventSubscriberInterface;
use \FOS\UserBundle\Model\UserManagerInterface;
use \Symfony\Component\Security\Core\SecurityContext;
use \MyApp\MyBundle\Entity\User;
class LocaleListener implements EventSubscriberInterface
{
private $userManager;
private $securityContext;
private $defaultLocale;
public function __construct(UserManagerInterface $userManager, SecurityContext $securityContext, $defaultLocale = 'en')
{
$this->userManager = $userManager;
$this->securityContext = $securityContext;
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest17(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
$locale = $request->attributes->get('_locale');
if ($locale !== null)
{
$request->getSession()->set('_locale', $locale);
}
else
{
// if no explicit locale has been set on this request, use one from the session
$locale = $request->getSession()->get('_locale', $this->defaultLocale);
$request->setLocale($locale);
}
// save last locale to the user if he is logged in
$user = $this->getUser();
if($user instanceof User)
{
$user->setDefaultLanguage($locale);
$this->userManager->updateUser($user);
}
}
private function getUser()
{
$token = $this->securityContext->getToken();
if($token !== null)
return $this->securityContext->getToken()->getUser();
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest17', 17)),
);
}
}
services.yml:
myApp_myBundle.locale_listener:
class: MyApp\MyBundle\EventListener\LocaleListener
arguments: [@fos_user.user_manager, @security.context, "%kernel.default_locale%"]
tags:
- { name: kernel.event_subscriber }