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:
31: private $container;
32:
33: 34: 35: 36: 37:
38: private $listenerIds = array();
39:
40: 41: 42: 43: 44:
45: private $listeners = array();
46:
47: 48: 49: 50: 51:
52: public function __construct(ContainerInterface $container)
53: {
54: $this->container = $container;
55: }
56:
57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68:
69: public function addListenerService($eventName, $callback, $priority = 0)
70: {
71: if (!is_array($callback) || 2 !== count($callback)) {
72: throw new \InvalidArgumentException('Expected an array("service", "method") argument');
73: }
74:
75: $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
76: }
77:
78: public function removeListener($eventName, $listener)
79: {
80: $this->lazyLoad($eventName);
81:
82: if (isset($this->listenerIds[$eventName])) {
83: foreach ($this->listenerIds[$eventName] as $i => $args) {
84: list($serviceId, $method, $priority) = $args;
85: $key = $serviceId.'.'.$method;
86: if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) {
87: unset($this->listeners[$eventName][$key]);
88: if (empty($this->listeners[$eventName])) {
89: unset($this->listeners[$eventName]);
90: }
91: unset($this->listenerIds[$eventName][$i]);
92: if (empty($this->listenerIds[$eventName])) {
93: unset($this->listenerIds[$eventName]);
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 (bool) count($this->listenerIds) || (bool) 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: