Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / symfony / event-dispatcher / DependencyInjection / RegisterListenersPass.php
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 = array();
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(array(
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', array($event['event'], array(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] = array(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('container.hot_path');
110                 }
111             }
112             $extractingDispatcher->listeners = array();
113         }
114     }
115 }
116
117 /**
118  * @internal
119  */
120 class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface
121 {
122     public $listeners = array();
123
124     public static $subscriber;
125
126     public function addListener($eventName, $listener, $priority = 0)
127     {
128         $this->listeners[] = array($eventName, $listener[1], $priority);
129     }
130
131     public static function getSubscribedEvents()
132     {
133         $callback = array(self::$subscriber, 'getSubscribedEvents');
134
135         return $callback();
136     }
137 }