7

Symfony2 ログイン イベント リスナーを追加しようとしています。目標は、ユーザーがログに記録されている場合はデータベースに格納されたロケールをリクエストごとに設定し、ユーザーがログに記録されていないデフォルトのロケールにフォールバックすることです。私は FOSUserBundle を使用しており、security.interactive_login イベントを機能させようとしています。次のようなインターネット上で多くのコードを見つけます: http://dev.dbl-a.com/symfony-2-0/how-to-add-a-symfony2-login-event-listener/

FOSUserBundle の独自の子バンドルと、services.yml でのこの実装があります。

my_user.security.interactive_login_listener:
        class: My\UserBundle\EventListener\UserListener
        arguments: [@security.context, @doctrine]
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

my_user.security.kernel_request_listener:
        class: My\UserBundle\EventListener\UserListener
        arguments: [@security.context, @doctrine]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: setLocaleForUnauthenticatedUser }

問題は、ログに記録されている場合でも、security.interactive_login イベントがトリガーされないことです。それどころか、私の setLocaleForUnauthenticatedUser は常にトリガーされます。私が見つけたすべてのコード サンプルは流暢に動作するようですが、私のアプリの何が問題なのですか?

4

2 に答える 2

1

実際には問題はありませんが、ログイン後に何らかのリダイレクトがあるため、プロファイラーはインタラクティブログインリスナーをトリガーする実際のリクエストを表示しません。

use Symfony\Component\Security\Http\Event\InteractiveLoginEvent,
    Symfony\Component\Security\Http\Event\FilterControllerEvent,
    Symfony\Component\HttpKernel\Event\GetResponseEvent,
    Symfony\Component\HttpKernel\HttpKernelInterface;
use FOS\UserBundle\Entity\User as BaseUser;

class LocaleListener {

    protected $container;
    protected $availableLocales;

    public function __construct(\Symfony\Component\DependencyInjection\Container $container, $availableLocales) {
        $this->container = $container;
        $this->availableLocales = $availableLocales;
    }

    public function onKernelRequest(GetResponseEvent $event) {
        $request = $event->getRequest();
        $locale = $request->getPreferredLanguage($this->availableLocales);
        $session = $request->getSession();

        $token = $this->container->get('security.context')->getToken();
        if( is_object( $token ) ) {
            $user = $token->getUser();
            if ($user instanceof BaseUser) {
                $locale = $user->getLocale();
            }
        }

        $session = $this->container->get('session');
        $session->set('_locale', $locale);
        $request->setLocale($locale);
    }
 }

services.yml で:

user.locales.kernel_request_listener:
        class: Acme\UserBundle\EventListener\LocaleListener
        arguments: [ @service_container, [ 'en', 'fr', 'ru' ] ]
        tags: [{ name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }]
于 2013-01-06T15:51:16.873 に答える
0

ここで同じ問題。しかし問題は、イベントがトリガーされないことではありません。問題は、リダイレクト後にリクエストのロケールが失われることです。このリンクの助けを借りて:

symfony 2.1 でロケールを変更する

(そしてこれに基づいて)

私はそれを解決する方法を考え出しました。UserListener で:

class UserListener
{
    private $session;

    public function setSession($session) {
        $this->session = $session;
    }    

    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());
            }
        }
    }

    public function setLocaleForAuthenticatedUser(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if ($locale = $user->getLocale()) {
//            $event->getRequest()->setLocale($user->getLocale());
            $this->session->set('_locale', $locale);
        }
    }
}

services.yml では、次のように宣言する必要があります。

your_listener_name:
    class: ...\UserBundle\EventListener\UserListener
    calls:
        - [ setSession, ['@session'] ]
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

お役に立てれば。

于 2012-12-30T03:20:08.500 に答える