0

我遇到了一个奇怪的问题。

我正在使用 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_DEen_USnull

现在出现了奇怪的行为(我不知道这是一个错误还是什么,但我很困惑):

数据库中存储的值无关紧要,它总是会更新为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事件$localede_DE

4

1 回答 1

1

您的三元 if 语句将始终失败,因为返回值

$this->request->get('_locale')

将会 :

  • de_DE

但从不 === 'de'。因此,如果您在调用后将 $locale 保存在您的实体中

$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';

...下次此语句失败并将其放回“en_US”调用...

$user->setLastLanguage('en_US');

... 到底。只是做一个更好的比较,比如......

 $locale = (strstr($locale,'de') !== false) ? 'de_DE' : 'en_US';

您是否尝试过在冲洗前坚持:

$this->user->setLastLanguage($locale);
$this->em->flush();

应该 ...

 $this->user->setLastLanguage($locale);
 $this->em->persist($this->user);
 $this->em->flush();

...如果您的用户是新创建的并且尚未由学说管理。

于 2013-05-22T13:47:10.080 回答