Время чтения: 5 минут
В одном из предыдущих постов я уже рассказывал о некоторых возможностях Symfony 2, а именно — об организации табличных данных. Сегодня речь пойдет о другом полезном инструменте — о событиях (Events).
В Symfony 2 есть возможность подписываться на существующие события, а также создавать свои. Во встроенном профайлере есть вкладка Events, на которой можно просмотреть все события, использовавшиеся при последнем обращении.
Сегодня я покажу, как работать с событиями, а именно, как подписываться на существующие события.
Будем решать две задачи:
- обновление даты последней авторизации пользователя
- перенаправление пользователя после логина в зависимости от роли
Обновление даты последней авторизации пользователя
Если не применять готовые бандлы (FOSUserBundle, KnpUserBundle, …), следующий пример можно использовать для обновления времени после успешной авторизации пользователя в системе.
После успешной авторизации срабатывает событие security.interactive_login. Для выполнения каких-либо действий после успешного логина пользователя, нужно создать сервис в файле Resources\config\config.yml (xml, php на ваше усмотрение):
… services: acme.listener.login: class: Acme\DemoBundle\Listener\UserLogin arguments: [ @doctrine, @service_container ] tags: - { name: kernel.event_listener, event: security.interactive_login, method: onLogin } …
<?php namespace Acme\DemoBundle\Listener; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Acme\DemoBundle\Entity\User; class UserLogin { protected $doctrine; protected $container; public function __construct(\Doctrine\Bundle\DoctrineBundle\Registry $doctrine, $container ) { $this------->doctrine = $doctrine; $this->container = $container; } public function onLogin(InteractiveLoginEvent $event) { $entityManager = $this->doctrine->getManager(); $user = $this->container->get('security.context')->getToken()->getUser(); // получаем пользователя из сессии $user->setLastLogin(new \DateTime()); //обновляем дату последнего логина в систему //можно выполнять любые действия с залогиненным пользователем $entityManager->flush(); //сохраняем данные } }
Таким образом, мы подписали наш класс для обновления даты последнего логина. Пробуем авторизовать пользователя и смотрим информацию в базе данных.
Перенаправление пользователя после логина в зависимости от роли
Для этого примера нам понадобятся две роли: ROLE_USER, ROLE_ADMIN. Первый тип пользователей должен переходить в корень сайта, а второй — сразу в интерфейс администратора.
Так же, как в первом примере, подпишемся на событие security.interactive_login:
… services: main.listener.login: class: Acme\DemoBundle\Listener\UserLogin arguments: [ @router, @security.context, @event_dispatcher ] tags: - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin } …
Теперь реализуем класс Acme\DemoBundle\Listener\UserLogin.php:
<?php namespace Acme\DemoBundle\Listener; use Symfony\Component\Security\Core\SecurityContext; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Routing\Router; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpKernel\KernelEvents; class UserLogin { protected $router; protected $security; protected $dispatcher; public function __construct(Router $router, SecurityContext $security, EventDispatcher $dispatcher) { $this------->router = $router; $this->security = $security; $this->dispatcher = $dispatcher; } public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $this->dispatcher->addListener(KernelEvents::RESPONSE, array($this,'onKernelResponse')); } public function onKernelResponse(FilterResponseEvent $event) { if ($this->security->isGranted('ROLE_ADMIN')){ $response = new RedirectResponse($this->router->generate('admin')); } else { $response = new RedirectResponse($this->router->generate('index')); } $event->setResponse($response); } }
После того как события сработают, пользователи будут перенаправлены. Более подробную информацию вы сможете найти в официальной документации Symfony 2.
Комментарии