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

Symfony Event Dispatcher

Avatar for Igor Igor
November 15, 2012

Symfony Event Dispatcher

Avatar for Igor

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