我开始使用 symfony 构建我的第一个 Web 应用程序。在这个应用程序中,我获得了具有身份验证和多语言功能的用户管理。在用户数据库表中,每个用户都有一个 lang 列。我通过 _GET 参数以及通过运行的数据库值登录来更改应用程序的默认语言。现在我想通过EventSubscriber中的URL _GET参数切换语言来自动更改数据库中的值。不幸的是,我不知道如何在“onKernelRequest”函数中获取用户实体以将选择的语言保存在数据库中。更改语言的所有逻辑都在以下代码中完成:
<?php
namespace App\EventSubscriber;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LocaleSubscriber implements EventSubscriberInterface
{
private $defaultLocale;
private $allowedLangs;
private $session;
public function __construct(SessionInterface $session, $defaultLocale = 'de')
{
$this->defaultLocale = $defaultLocale;
$this->allowedLangs = ['de', 'en'];
$this->session = $session;
}
public function onInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $event->getAuthenticationToken()->getUser();
if (null !== $user->getLocale()) {
$this->session->set('_locale', $user->getLocale());
}
}
public function onKernelRequest(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);
} elseif(array_key_exists('_locale', $_GET) && array_search($_GET['_locale'], $this->allowedLangs) !== FALSE) {
$request->setLocale($_GET['_locale']);
$request->getSession()->set('_locale', $_GET['_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 (i.e. with a higher priority than) the default Locale listener
SecurityEvents::INTERACTIVE_LOGIN => array(array('onInteractiveLogin', 15)),
KernelEvents::REQUEST => array(array('onKernelRequest', 20)),
);
}
}
Run Code Online (Sandbox Code Playgroud)
预先感谢彼得
首先,我将拆LocaleSubscriber 分类并移动onKernelRequest到onInteractiveLogin单独的侦听器/订阅者 - 每个服务的依赖性更少。
onKernelRequest要在需要注入服务的情况下获取当前用户TokenStorage:
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class LocaleSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $em;
public function __construct(
TokenStorageInterface $tokenStorage,
EntityManagerInterface $em
) {
$this->tokenStorage = $tokenStorage;
$this->em = $em;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
if (!$token = $this->tokenStorage->getToken()) {
return ;
}
if (!$token->isAuthenticated()) {
return ;
}
if (!$user = $token->getUser()) {
return ;
}
$request = $event->getRequest();
// update user
$user->setLocale($locale);
$this->em->flush($user);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这尚未经过测试。
| 归档时间: |
|
| 查看次数: |
8396 次 |
| 最近记录: |