Я пытаюсь реализовать события на 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(); } }
И мое обслуживание
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()
систему, 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' }
Два момента:
В определении сервиса - { name: 'kernel.event_subscriber'}
достаточно, никакой записи события. Это разница между подписчиком и слушателем. Слушатель может прослушивать только одно событие, определенное значение параметра и параметры method
в определении службы. Абонент может прослушивать несколько событий, определенных через метод getSubscribedEvents()
, поэтому никаких дополнительных параметров в определении службы не требуется.
Во-вторых, вы тип, намекающий на классы событий ( UserEvent
и FilterUserResponseEvent
), но вы их никогда не импортировали, поэтому PHP предполагает их в том же пространстве имен (как указано в сообщении об ошибке).
use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\Event\FilterUserResponseEvent;