[ Index ]

PHP Cross Reference of phpBB-3.3.7-deutsch

title

Body

[close]

/vendor/symfony/event-dispatcher/DependencyInjection/ -> RegisterListenersPass.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\EventDispatcher\DependencyInjection;
  13  
  14  use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
  15  use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  16  use Symfony\Component\DependencyInjection\ContainerBuilder;
  17  use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  18  use Symfony\Component\DependencyInjection\Reference;
  19  use Symfony\Component\EventDispatcher\EventDispatcher;
  20  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21  
  22  /**
  23   * Compiler pass to register tagged services for an event dispatcher.
  24   */
  25  class RegisterListenersPass implements CompilerPassInterface
  26  {
  27      protected $dispatcherService;
  28      protected $listenerTag;
  29      protected $subscriberTag;
  30  
  31      private $hotPathEvents = [];
  32      private $hotPathTagName;
  33  
  34      /**
  35       * @param string $dispatcherService Service name of the event dispatcher in processed container
  36       * @param string $listenerTag       Tag name used for listener
  37       * @param string $subscriberTag     Tag name used for subscribers
  38       */
  39      public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
  40      {
  41          $this->dispatcherService = $dispatcherService;
  42          $this->listenerTag = $listenerTag;
  43          $this->subscriberTag = $subscriberTag;
  44      }
  45  
  46      public function setHotPathEvents(array $hotPathEvents, $tagName = 'container.hot_path')
  47      {
  48          $this->hotPathEvents = array_flip($hotPathEvents);
  49          $this->hotPathTagName = $tagName;
  50  
  51          return $this;
  52      }
  53  
  54      public function process(ContainerBuilder $container)
  55      {
  56          if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) {
  57              return;
  58          }
  59  
  60          $definition = $container->findDefinition($this->dispatcherService);
  61  
  62          foreach ($container->findTaggedServiceIds($this->listenerTag, true) as $id => $events) {
  63              foreach ($events as $event) {
  64                  $priority = isset($event['priority']) ? $event['priority'] : 0;
  65  
  66                  if (!isset($event['event'])) {
  67                      throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag));
  68                  }
  69  
  70                  if (!isset($event['method'])) {
  71                      $event['method'] = 'on'.preg_replace_callback([
  72                          '/(?<=\b)[a-z]/i',
  73                          '/[^a-z0-9]/i',
  74                      ], function ($matches) { return strtoupper($matches[0]); }, $event['event']);
  75                      $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
  76                  }
  77  
  78                  $definition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]);
  79  
  80                  if (isset($this->hotPathEvents[$event['event']])) {
  81                      $container->getDefinition($id)->addTag($this->hotPathTagName);
  82                  }
  83              }
  84          }
  85  
  86          $extractingDispatcher = new ExtractingEventDispatcher();
  87  
  88          foreach ($container->findTaggedServiceIds($this->subscriberTag, true) as $id => $attributes) {
  89              $def = $container->getDefinition($id);
  90  
  91              // We must assume that the class value has been correctly filled, even if the service is created by a factory
  92              $class = $def->getClass();
  93  
  94              if (!$r = $container->getReflectionClass($class)) {
  95                  throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
  96              }
  97              if (!$r->isSubclassOf(EventSubscriberInterface::class)) {
  98                  throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class));
  99              }
 100              $class = $r->name;
 101  
 102              ExtractingEventDispatcher::$subscriber = $class;
 103              $extractingDispatcher->addSubscriber($extractingDispatcher);
 104              foreach ($extractingDispatcher->listeners as $args) {
 105                  $args[1] = [new ServiceClosureArgument(new Reference($id)), $args[1]];
 106                  $definition->addMethodCall('addListener', $args);
 107  
 108                  if (isset($this->hotPathEvents[$args[0]])) {
 109                      $container->getDefinition($id)->addTag($this->hotPathTagName);
 110                  }
 111              }
 112              $extractingDispatcher->listeners = [];
 113          }
 114      }
 115  }
 116  
 117  /**
 118   * @internal
 119   */
 120  class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface
 121  {
 122      public $listeners = [];
 123  
 124      public static $subscriber;
 125  
 126      public function addListener($eventName, $listener, $priority = 0)
 127      {
 128          $this->listeners[] = [$eventName, $listener[1], $priority];
 129      }
 130  
 131      public static function getSubscribedEvents()
 132      {
 133          $callback = [self::$subscriber, 'getSubscribedEvents'];
 134  
 135          return $callback();
 136      }
 137  }


Generated: Thu Mar 24 21:31:15 2022 Cross-referenced by PHPXref 0.7.1