Работа с событиями в Symfony 2

Alexey Romanenko

Alexey Romanenko

IT-копирайтер

#Инсайты

#Технологии

22 Май 2013

Время чтения: 5 минут

22 Май 2013

В одном из предыдущих постов я уже рассказывал о некоторых возможностях 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.

Комментарии

Фильтр

Закрыть

Технологии

Индустрии