我遇到了一个奇怪的问题。
我正在使用 Doctrine 2.2 和 FOSUserBundle 进行用户管理的 Symfony 2.1 项目。
我添加了一个 RequestListener,因为用户可以更改网站的语言,并且我想跟踪用户最后使用的语言。
因此,我只是向用户实体添加了一个新属性,然后如果已更改,则希望保存新语言。
所以我在请求监听器中这样做:
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) {
return;
}
if ($event->getRequest()->getRequestFormat() !== 'html') {
return;
}
if ($this->context->getToken()->getUser() instanceof \Foo\BarBundle\Entity\User) {
$this->request = $event->getRequest();
$this->user = $this->context->getToken()->getUser();
if ($this->user->getCustomer() instanceof \Foo\BarBundle\Entity\Customer) {
$this->customer = $this->user->getCustomer();
$permission = $this->permissionService->getPermissionSafely($this->customer);
$params = $this->request->get('_route_params');
$language = $this->getLanguage($permission['language']['languages']);
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';
if ($language !== "all" && $this->request->get('_locale') !== $language) {
$params['_locale'] = $language;
$redirect = new RedirectResponse($this->router->generate($this->request->get('_route'), $params));
$event->setResponse($redirect);
}
if ($this->user->getLastLanguage() !== $locale) {
$this->user->setLastLanguage($locale);
$this->em->flush();
}
}
}
}
private function getLanguage($language)
{
if (!isset($language['en'])) {
return 'de';
}
if (!isset($language['de'])) {
return 'en';
}
if ($language['en'] && !($language['de'])) {
return 'en';
} else if (!$language['en'] && $language['de']) {
return 'de';
}
return 'all';
}
重要的是最后一个条件if
。如果当前$locale
与上次使用的不同,我想更新用户对象。所以有三个可能的值de_DE
:en_US
和null
。
现在出现了奇怪的行为(我不知道这是一个错误还是什么,但我很困惑):
数据库中存储的值无关紧要,它总是会更新为en_US
.
如果用户第一次访问该页面 (value null
) 并以德语 (value de_DE
) 访问该站点,它将更新为en_US
,但分析器查询显示:
UPDATE `user` SET last_language = 'de_DE' WHERE id = 1
如果用户拥有last_language = 'de_DE'
并以德语 ( de_DE
) 访问该站点,则它会更新为en_US
,但查询分析器说,没有更新查询。这是有道理的,因为 和$locale
是一样的$this->user->getLastLanguage()
。
什么??
我不知道这里发生了什么。有没有人遇到过类似的问题?这与我正在从安全上下文中修改用户对象这一事实有关吗?
更新:有趣的是,如果我换行
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';
至
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'es_US';
如果持有,它会更新为es_US
事件$locale
de_DE