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_DEは 、 、en_USおよびの 3 つnullです。

今、奇妙な動作が発生します(バグなのか何なのかわかりませんが、混乱しています):

データベースに格納されている値は問題ではなく、常に に更新されen_USます。

ユーザーが初めてページにアクセスし (値null)、ドイツ語でサイトにアクセスした場合 (値de_DE) に更新されen_USますが、プロファイラーのクエリは次のように述べています。

UPDATE `user` SET last_language = 'de_DE' WHERE id = 1

ユーザーがドイツ語 ( )last_language = 'de_DE'のサイトを持っていて訪問すると、 に更新されますが、クエリ プロファイラーは更新クエリがなかったと言っています。は と同じなので、これは理にかなっています。de_DEen_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 に答える