5

I'm trying to implement events on FOSUserBundle

<?php
namespace EasyApp\UserBundle\Service;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\Bundle\DoctrineBundle\Registry as Doctrine; 
use EasyApp\UserBundle\Entity\UserLogin;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserBundle;


class LoginManager implements EventSubscriberInterface
{
    /** @var \Symfony\Component\Security\Core\SecurityContext */
    private $securityContext;

    /** @var \Doctrine\ORM\EntityManager */
    private $em;

    /**
     * Constructor
     *
     * @param SecurityContext $securityContext
     * @param Doctrine        $doctrine
     */
    public function __construct(SecurityContext $securityContext, Doctrine $doctrine)
    {
        $this->securityContext = $securityContext;
        $this->em = $doctrine->getEntityManager();
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
                FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onSecurityImplicitLogin',
                FOSUserEvents::REGISTRATION_COMPLETED=> 'onRegistrationCompleted'
        );
    }

    public function onSecurityImplicitLogin(UserEvent $event)
    {
        die;
        $user = $event->getAuthenticationToken()->getUser();
        $request = $event->getRequest();

        if ($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
            // user has just logged in
            $this->saveLogin($request, $user);
        }
    }

    public function onRegistrationCompleted(FilterUserResponseEvent $event){
        $user = $event->getAuthenticationToken()->getUser();
        $request = $event->getRequest();
        saveLogin($request, $user);
    }

    public function saveLogin($request, $user){
        $login = new UserLogin();
        $login->setIp($request->getClientIp());
        $login->setUser($user);

        $this->em->persist($login);
        $this->em->flush();
    }
}

And my service

services:
    user_login_manager:
        class: 'EasyApp\UserBundle\Service\LoginManager'
        arguments: ['@security.context', '@doctrine']
        tags:
            - { name: 'kernel.event_subscriber', event: 'fos_user.security.interactive_login'}
            - { name: 'kernel.event_subscriber', event: 'fos_user.registration.completed'}

But I have problems. When I login nothing happen, the getSubscribedEvents() is called but not onSecurityImplicitLogin(UserEvent $event)

And the other problem is on register. Following error occurs on onSecurityImplicitLogin(UserEvent $event)

Catchable Fatal Error: Argument 1 passed to EasyApp\UserBundle\Service\LoginManager::onSecurityImplicitLogin() must be an instance of EasyApp\UserBundle\Service\UserEvent, instance of FOS\UserBundle\Event\UserEvent given in /Users/antoine/Documents/projects/easyApp/application/src/EasyApp/UserBundle/Service/LoginManager.php line 46

and if I comment this line I got the same error on onRegistrationCompleted(FilterUserResponseEvent $event)

Edit

services:
    user_login_manager:
        class: 'EasyApp\UserBundle\Service\LoginManager'
        arguments: ['@security.context', '@doctrine']
        tags:
            - { name: 'kernel.event_subscriber'}
            - { name: 'kernel.event_listener', event: 'security.interactive_login' }
4

1 に答える 1

7

2 つのポイント:

  1. サービス定義- { name: 'kernel.event_subscriber'}で十分です。イベント エントリはありません。これがサブスクライバーとリスナーの違いです。リスナーは、サービス定義で定義されたトラフeventとパラメーターの 1 つのイベントのみをリッスンできます。methodサブスクライバーは、メソッドを通じて定義された複数のイベントをリッスンできるgetSubscribedEvents()ため、サービス定義に追加のパラメーターは必要ありません。

  2. 2 番目のポイントは、イベント クラス (UserEventおよびFilterUserResponseEvent) に対してタイプ ヒンティングを行っていますが、それらをインポートしたことがないため、PHP はそれらを同じ名前空間にあると見なします (エラー メッセージに示されているように)。

    use FOS\UserBundle\Event\UserEvent;
    use FOS\UserBundle\Event\FilterUserResponseEvent;
    
于 2013-07-10T09:11:16.723 に答える