1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\EventDispatcher;
13:
14: use Symfony\Component\DependencyInjection\ContainerInterface;
15:
16: 17: 18: 19: 20: 21: 22: 23:
24: class ContainerAwareEventDispatcher extends EventDispatcher
25: {
26: 27: 28: 29:
30: private $container;
31:
32: 33: 34: 35:
36: private $listenerIds = array();
37:
38: 39: 40: 41:
42: private $listeners = array();
43:
44: 45: 46: 47: 48:
49: public function __construct(ContainerInterface $container)
50: {
51: $this->container = $container;
52: }
53:
54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65:
66: public function addListenerService($eventName, $callback, $priority = 0)
67: {
68: if (!is_array($callback) || 2 !== count($callback)) {
69: throw new \InvalidArgumentException('Expected an array("service", "method") argument');
70: }
71:
72: $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
73: }
74:
75: public function removeListener($eventName, $listener)
76: {
77: $this->lazyLoad($eventName);
78:
79: if (isset($this->listeners[$eventName])) {
80: foreach ($this->listeners[$eventName] as $key => $l) {
81: foreach ($this->listenerIds[$eventName] as $i => $args) {
82: list($serviceId, $method, $priority) = $args;
83: if ($key === $serviceId.'.'.$method) {
84: if ($listener === array($l, $method)) {
85: unset($this->listeners[$eventName][$key]);
86: if (empty($this->listeners[$eventName])) {
87: unset($this->listeners[$eventName]);
88: }
89: unset($this->listenerIds[$eventName][$i]);
90: if (empty($this->listenerIds[$eventName])) {
91: unset($this->listenerIds[$eventName]);
92: }
93: }
94: }
95: }
96: }
97: }
98:
99: parent::removeListener($eventName, $listener);
100: }
101:
102: 103: 104:
105: public function hasListeners($eventName = null)
106: {
107: if (null === $eventName) {
108: return (Boolean) count($this->listenerIds) || (Boolean) count($this->listeners);
109: }
110:
111: if (isset($this->listenerIds[$eventName])) {
112: return true;
113: }
114:
115: return parent::hasListeners($eventName);
116: }
117:
118: 119: 120:
121: public function getListeners($eventName = null)
122: {
123: if (null === $eventName) {
124: foreach (array_keys($this->listenerIds) as $serviceEventName) {
125: $this->lazyLoad($serviceEventName);
126: }
127: } else {
128: $this->lazyLoad($eventName);
129: }
130:
131: return parent::getListeners($eventName);
132: }
133:
134: 135: 136: 137: 138: 139:
140: public function addSubscriberService($serviceId, $class)
141: {
142: foreach ($class::getSubscribedEvents() as $eventName => $params) {
143: if (is_string($params)) {
144: $this->listenerIds[$eventName][] = array($serviceId, $params, 0);
145: } elseif (is_string($params[0])) {
146: $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0);
147: } else {
148: foreach ($params as $listener) {
149: $this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0);
150: }
151: }
152: }
153: }
154:
155: 156: 157: 158: 159: 160: 161: 162:
163: public function dispatch($eventName, Event $event = null)
164: {
165: $this->lazyLoad($eventName);
166:
167: return parent::dispatch($eventName, $event);
168: }
169:
170: public function getContainer()
171: {
172: return $this->container;
173: }
174:
175: 176: 177: 178: 179: 180: 181: 182:
183: protected function lazyLoad($eventName)
184: {
185: if (isset($this->listenerIds[$eventName])) {
186: foreach ($this->listenerIds[$eventName] as $args) {
187: list($serviceId, $method, $priority) = $args;
188: $listener = $this->container->get($serviceId);
189:
190: $key = $serviceId.'.'.$method;
191: if (!isset($this->listeners[$eventName][$key])) {
192: $this->addListener($eventName, array($listener, $method), $priority);
193: } elseif ($listener !== $this->listeners[$eventName][$key]) {
194: parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method));
195: $this->addListener($eventName, array($listener, $method), $priority);
196: }
197:
198: $this->listeners[$eventName][$key] = $listener;
199: }
200: }
201: }
202: }
203: