[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |