2013-07-10 50 views
5

我試圖落實FOSUserBundle活動FOSUserBundle的Symfony2上需要註冊並登錄

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

事件和我的服務

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'} 

但我有問題。當我登錄什麼都沒有發生時,getSubscribedEvents()被調用,但不是onSecurityImplicitLogin(UserEvent $event)

而另一個問題是在寄存器上。在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 

出現以下錯誤,如果我評論這一行我就onRegistrationCompleted(FilterUserResponseEvent $event)

得到了同樣的錯誤編輯

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' } 

回答

7

兩點:

  1. 在服務定義- { name: 'kernel.event_subscriber'}就夠了,沒有事件輸入。這是用戶和聽衆之間的區別。監聽者只能聽到服務定義中的低於eventmethod參數的一個事件。用戶可以監聽多個事件,這些事件通過getSubscribedEvents()的方法定義,因此服務定義中不需要其他參數。第二點,您是針對事件類型(UserEventFilterUserResponseEvent)鍵入提示,但是您從未導入它們,因此PHP假定它們位於相同的命名空間(如錯誤消息中所述)。

    use FOS\UserBundle\Event\UserEvent; 
    use FOS\UserBundle\Event\FilterUserResponseEvent; 
    
+0

謝謝您的回答,但我加 - {名稱: 'kernel.event_listener',事件: 'security.interactive_login'}在我的服務來檢測正常登錄 – Ajouve

+0

是否混合'kernel.event_listener'和'kernel.event_subscriber'標籤有效嗎? –

+1

是的,這是可行的,我用我的新服務編輯我的帖子 – Ajouve