Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony Event Dispatcher

Igor
November 15, 2012

Symfony Event Dispatcher

Igor

November 15, 2012
Tweet

Other Decks in Programming

Transcript

  1. Для чего вообще нужны события? • 1. Расширение классов без

    их непосредственного изменения • 2. Вынесение кода часто-используемых действий. Например, установка значений created_at и updated_at • 3. Создание очередей и сбор данных по ходу исполнения кода
  2. Event Dispatcher Component <?php require_once __DIR__.'/vendor/autoload.php'; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event;

    $dispatcher = new EventDispatcher(); $listener = new AcmeListener(); $dispatcher->addListener( 'foo.action', array($listener, 'onFooAction') );
  3. class AcmeListener { // ... public function onFooAction(Event $event) {

    // ... do something echo $event->getName(); } } $event = new Event(); $dispatcher->dispatch('foo.action', $event); Event Dispatcher Component
  4. События в Symfony services: app.listener.location: class: App\DefaultBundle\Listener\LocationListener tags: - {

    name: kernel.event_listener, event: kernel.controller } - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } - { name: kernel.event_listener, event: security.interactive_login } $listener = new LocationListener(); $dispatcher->addListener('kernel.controller', array($listener, 'onKernelController')); $dispatcher->addListener('kernel.response', array($listener, 'onKernelResponse')); $dispatcher->addListener('security.interactive_login', array($listener, 'onSecurityInteractiveLogin'));
  5. Система баннеров services: app.listener.banner: class: App\BannerBundle\Listener\BannerListener tags: - { name:

    kernel.event_listener, event: kernel.controller } arguments: [@doctrine.orm.entity_manager] class BannerListener { private $em; protected $banners; public function __construct($em) { $this->em = $em; } ... } config.yml: BannerListener.php:
  6. public function onKernelController($event) { if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) { //

    don't do anything if it's not the master request return; } $this->banners = $this->em ->getRepository('AppBannerBundle:Banner')->findByPlaces(); } public function getBanner($place) { return isset($this->banners[$place]) ? $this->banners[$place] : null; } $this->get('app.listener.banner')->getBanner($place); Система баннеров
  7. public function onKernelRequest(GetResponseEvent $event) { if (HttpKernel::MASTER_REQUEST !== $event->getRequestType()) {

    // don't do anything if it's not the master request return; } $context = $this->router->getContext(); $request = $event->getRequest(); if ($request->get('_city')) { $context->setParameter('_city', true); } } Установка параметра для всех ссылок
  8. public function onKernelController(FilterControllerEvent $event) { if (!is_array($controller = $event->getController())) {

    return; } $method = new \ReflectionMethod($controller[0], $controller[1]); foreach ($this->reader->getMethodAnnotations($method) as $annotation) { if ($annotation instanceof MinAccess) { if (!$annotation->execute( $this->security, $this->session, $this->routing) ) { throw new MinAccessException(); } } } } Расширение метода с помощью аннотаций
  9. public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); if ($exception

    instanceof MinAccessException) { $event->setResponse( new RedirectResponse($this->routing->generate('address_edit') )); } } Расширение метода с помощью аннотаций
  10. public function onSecurityInteractiveLogin($event) { $user = $this->securityContext->getToken()->getUser(); $request = $event->getRequest();

    if ($city = $entity->getLocation()) { $url = $this->getCityUrl($city); $this->session->set('_security.target_path', $url); } } Перенаправление после входа
  11. События Doctrine my.listener: class: App\CityBundle\Listener\CityListener tags: - { name: doctrine.event_listener,

    event: prePersist, method: prePersist } class CityListener { public function prePersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); if ($entity instanceof City) { $now = new \DateTime(); $entity->setCreatedAt($now); } } }