|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* YAWIK |
|
4
|
|
|
* |
|
5
|
|
|
* @filesource |
|
6
|
|
|
* @license MIT |
|
7
|
|
|
* @copyright 2013 - 2016 Cross Solution <http://cross-solution.de> |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
/** */ |
|
11
|
|
|
namespace Core\Factory\EventManager; |
|
12
|
|
|
|
|
13
|
|
|
use Core\EventManager\EventProviderInterface; |
|
14
|
|
|
use Interop\Container\ContainerInterface; |
|
15
|
|
|
use Interop\Container\Exception\ContainerException; |
|
16
|
|
|
use Zend\EventManager\ListenerAggregateInterface; |
|
17
|
|
|
use Zend\ServiceManager\AbstractFactoryInterface; |
|
18
|
|
|
use Zend\ServiceManager\Exception\ServiceNotCreatedException; |
|
19
|
|
|
use Zend\ServiceManager\Exception\ServiceNotFoundException; |
|
20
|
|
|
use Zend\ServiceManager\ServiceLocatorInterface; |
|
21
|
|
|
use Zend\Stdlib\ArrayUtils; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* Creates event manager instances. |
|
25
|
|
|
* |
|
26
|
|
|
* Optionally configures these instances with options set in array with the key "event_manager" in the main config |
|
27
|
|
|
* array. Also creates listeners which are preconfigured in the options and automatically attaches them. |
|
28
|
|
|
* |
|
29
|
|
|
* The options array: |
|
30
|
|
|
* [ |
|
31
|
|
|
* 'event_manager' => [ |
|
32
|
|
|
* 'Meaningful/Service.Name/Events' => [ |
|
33
|
|
|
* 'service' => string: Service name or class name of the event manager to create. |
|
34
|
|
|
* 'event' => string: Service name or class name of the event class to be used. |
|
35
|
|
|
* 'configure' => bool: Wether or not to configure the service manager through THIS factory. |
|
36
|
|
|
* 'identifiers' => array: list of identifiers for the event manager. |
|
37
|
|
|
* 'listeners' => array: preconfigured listeners which will ONLY be created, when the |
|
38
|
|
|
* event manager is created. (lazy loading) |
|
39
|
|
|
* ] |
|
40
|
|
|
* ] |
|
41
|
|
|
* |
|
42
|
|
|
* The listeners array: |
|
43
|
|
|
* |
|
44
|
|
|
* [ |
|
45
|
|
|
* string:listener => string:event, // creates the listener with the key as name (or class) and attaches it |
|
46
|
|
|
* // to the event manager on the provided event. |
|
47
|
|
|
* |
|
48
|
|
|
* // If you need more options or need to attach to multiple events, you can use following syntax: // |
|
49
|
|
|
* string:listener => [ string|array:event{, string:methodName}{, int:priority}{, bool:lazy }], |
|
50
|
|
|
* // First string item or any array item is used as event(s) |
|
51
|
|
|
* // Any string item (if event is already set) and any following string items set (and override previous) method names |
|
52
|
|
|
* // (the method name is the name of the method to be called upon the listener when the event happens.) |
|
53
|
|
|
* // Any int item set and override previously set priority. |
|
54
|
|
|
* // Any boolean item set and override previously set lazy option. |
|
55
|
|
|
* // (lazy option does provide even more lazy loading. The listener is only created, if |
|
56
|
|
|
* // the event it listens to is actually triggered. (accomplished by \Core\Listener\DeferredListenerAggregate) |
|
57
|
|
|
* |
|
58
|
|
|
* string:aggregate, // Creates an ListenerAggregate and call its attach method with the instance of the event manager |
|
59
|
|
|
* string:aggregate => int:priority // Same as above, but passes the priority value along. |
|
60
|
|
|
* ] |
|
61
|
|
|
* |
|
62
|
|
|
* If you need to attach more than one method or two events with different priorities you can do so using the |
|
63
|
|
|
* verbose style in the listener array: |
|
64
|
|
|
* |
|
65
|
|
|
* [ |
|
66
|
|
|
* string:listener => [ |
|
67
|
|
|
* 'events' => [ |
|
68
|
|
|
* string:eventName, |
|
69
|
|
|
* string:eventName => int:priority, |
|
70
|
|
|
* string:eventName' => string:method, |
|
71
|
|
|
* string:eventName => [ |
|
72
|
|
|
* 'method' => string:method, |
|
73
|
|
|
* 'method' => [ string:method, string:method, ... ], |
|
74
|
|
|
* 'method' => [ string:method => int:priority, string:method' => int:priority ], |
|
75
|
|
|
* 'priority' => int:priority, |
|
76
|
|
|
* ], |
|
77
|
|
|
* ], |
|
78
|
|
|
* 'method' => string:defaultMethod, |
|
79
|
|
|
* 'priority' => int:defaultPriority, |
|
80
|
|
|
* 'lazy' => bool |
|
81
|
|
|
* ], |
|
82
|
|
|
* ] |
|
83
|
|
|
* |
|
84
|
|
|
* Example: |
|
85
|
|
|
* Attach one listener to two methods on one event: |
|
86
|
|
|
* [ |
|
87
|
|
|
* 'Listener' => [ 'events' => [ 'eventName' => [ 'method' => ['method1', 'method2'] ] ] ], |
|
88
|
|
|
* ] |
|
89
|
|
|
* |
|
90
|
|
|
* Use default priority on method1 and different priority on method2: |
|
91
|
|
|
* [ |
|
92
|
|
|
* 'Listener' => [ 'events' => [ 'eventName' => [ 'method' => ['method1', 'method2' => 12] ] ] ], 'priority' => 5 ], |
|
93
|
|
|
* ] |
|
94
|
|
|
* |
|
95
|
|
|
* Attach one listener to two events with different priority: |
|
96
|
|
|
* [ |
|
97
|
|
|
* 'Listener' => [ 'events' => [ 'event1' => 1, 'event2' => 2 ] ], |
|
98
|
|
|
* ] |
|
99
|
|
|
* |
|
100
|
|
|
* Each specific event -> method -> priority triple will be attached searately to the event manager using the |
|
101
|
|
|
* same listener instance. |
|
102
|
|
|
* |
|
103
|
|
|
* |
|
104
|
|
|
* @author Mathias Gelhausen <[email protected]> |
|
105
|
|
|
* @since 0.25 |
|
106
|
|
|
*/ |
|
107
|
|
|
class EventManagerAbstractFactory implements AbstractFactoryInterface |
|
108
|
|
|
{ |
|
109
|
|
|
/** |
|
110
|
|
|
* Create an object |
|
111
|
|
|
* |
|
112
|
|
|
* @param ContainerInterface $container |
|
113
|
|
|
* @param string $requestedName |
|
114
|
|
|
* @param null|array $options |
|
115
|
|
|
* |
|
116
|
|
|
* @return object |
|
117
|
|
|
* @throws ServiceNotFoundException if unable to resolve the service. |
|
118
|
|
|
* @throws ServiceNotCreatedException if an exception is raised when |
|
119
|
|
|
* creating a service. |
|
120
|
|
|
* @throws ContainerException if any other error occurs |
|
121
|
|
|
*/ |
|
122
|
|
View Code Duplication |
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) |
|
|
|
|
|
|
123
|
|
|
{ |
|
124
|
|
|
$config = $this->getConfig($container, $requestedName); |
|
|
|
|
|
|
125
|
|
|
$events = $this->createEventManager($container, $config); |
|
|
|
|
|
|
126
|
|
|
|
|
127
|
|
|
$this->attachListeners($container, $events, $config['listeners']); |
|
|
|
|
|
|
128
|
|
|
return $events; |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
/** |
|
132
|
|
|
* Can the factory create an instance for the service? |
|
133
|
|
|
* |
|
134
|
|
|
* @param ContainerInterface $container |
|
135
|
|
|
* @param string $requestedName |
|
136
|
|
|
* |
|
137
|
|
|
* @return bool |
|
138
|
|
|
*/ |
|
139
|
|
|
public function canCreate(ContainerInterface $container, $requestedName) |
|
|
|
|
|
|
140
|
|
|
{ |
|
141
|
|
|
/* We check, if $requestedName ends with the string '/Events'. |
|
142
|
|
|
* Instead of parsing the string with regular expressions (eg. ~/Events$~), |
|
143
|
|
|
* it's more efficient to just check with strpos, if the reversed string starts |
|
144
|
|
|
* with the reverted '/Events' string. |
|
145
|
|
|
*/ |
|
146
|
|
|
return 0 === strpos(strrev($requestedName), 'stnevE/'); |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
|
|
150
|
|
|
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) |
|
151
|
|
|
{ |
|
152
|
|
|
return $this->canCreate($serviceLocator, $requestedName); |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
/** |
|
156
|
|
|
* Creates an event manager and attaches preconfigured listeners. |
|
157
|
|
|
* |
|
158
|
|
|
* @param ServiceLocatorInterface $serviceLocator |
|
159
|
|
|
* @param string $name |
|
160
|
|
|
* @param string $requestedName |
|
161
|
|
|
* |
|
162
|
|
|
* @return \Zend\EventManager\EventManagerInterface |
|
163
|
|
|
* @throws \UnexpectedValueException |
|
164
|
|
|
*/ |
|
165
|
|
View Code Duplication |
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) |
|
|
|
|
|
|
166
|
|
|
{ |
|
167
|
|
|
$config = $this->getConfig($serviceLocator, $requestedName); |
|
168
|
|
|
$events = $this->createEventManager($serviceLocator, $config); |
|
169
|
|
|
|
|
170
|
|
|
$this->attachListeners($serviceLocator, $events, $config['listeners']); |
|
171
|
|
|
|
|
172
|
|
|
return $events; |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* Gets configuration for an event manager. |
|
177
|
|
|
* |
|
178
|
|
|
* Merges the default config with configuration from the main config, |
|
179
|
|
|
* if a key $name exists in the array under the "event_manager" array in the main config. |
|
180
|
|
|
* |
|
181
|
|
|
* @param ServiceLocatorInterface $services |
|
182
|
|
|
* @param string $name |
|
183
|
|
|
* |
|
184
|
|
|
* @return array |
|
185
|
|
|
*/ |
|
186
|
|
|
protected function getConfig($services, $name) |
|
187
|
|
|
{ |
|
188
|
|
|
$defaults = [ |
|
189
|
|
|
'service' => 'EventManager', |
|
190
|
|
|
'configure' => true, |
|
191
|
|
|
'identifiers' => [ $name ], |
|
192
|
|
|
'event' => '\Zend\EventManager\Event', |
|
193
|
|
|
'listeners' => [], |
|
194
|
|
|
]; |
|
195
|
|
|
|
|
196
|
|
|
$config = $services->get('Config'); |
|
197
|
|
|
$config = isset($config['event_manager'][$name]) ? $config['event_manager'][$name] : []; |
|
198
|
|
|
|
|
199
|
|
|
/* |
|
200
|
|
|
* array_merge does not work, because the default values for 'identifiers' and 'listeners' |
|
201
|
|
|
* are arrays and array_merge breaks the structure. |
|
202
|
|
|
*/ |
|
203
|
|
|
$config = array_replace_recursive($defaults, $config); |
|
204
|
|
|
|
|
205
|
|
|
return $config; |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
/** |
|
209
|
|
|
* Creates an event manager instance. |
|
210
|
|
|
* |
|
211
|
|
|
* Fetches from the service manager or tries to instantiate direct, if no service |
|
212
|
|
|
* exists in the service manager. |
|
213
|
|
|
* |
|
214
|
|
|
* If the key 'configure' in the config array has the value TRUE (default), |
|
215
|
|
|
* the event manager instance will get configured. Which means, the event prototype |
|
216
|
|
|
* will be set (after it is fetched from the service manager or instatiated), |
|
217
|
|
|
* and the shared event manager will be injected. |
|
218
|
|
|
* |
|
219
|
|
|
* @param ServiceLocatorInterface $services |
|
220
|
|
|
* @param array $config |
|
221
|
|
|
* |
|
222
|
|
|
* @return \Zend\EventManager\EventManagerInterface |
|
223
|
|
|
* @throws \UnexpectedValueException if neither a service exists, nor could a class be found. |
|
224
|
|
|
*/ |
|
225
|
|
|
protected function createEventManager($services, $config) |
|
226
|
|
|
{ |
|
227
|
|
|
/* @var \Zend\EventManager\EventManagerInterface|\Core\EventManager\EventProviderInterface $events */ |
|
228
|
|
|
|
|
229
|
|
View Code Duplication |
if ($services->has($config['service'])) { |
|
|
|
|
|
|
230
|
|
|
$events = $services->get($config['service']); |
|
231
|
|
|
|
|
232
|
|
|
} else { |
|
233
|
|
|
if (!class_exists($config['service'], true)) { |
|
234
|
|
|
throw new \UnexpectedValueException(sprintf( |
|
235
|
|
|
'Class or service %s does not exists. Cannot create event manager instance.', $config['service'] |
|
236
|
|
|
)); |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
$events = new $config['service'](); |
|
240
|
|
|
} |
|
241
|
|
|
|
|
242
|
|
|
if (false === $config['configure']) { |
|
243
|
|
|
return $events; |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
$events->setIdentifiers($config['identifiers']); |
|
247
|
|
|
|
|
248
|
|
|
if ($events instanceOf EventProviderInterface || method_exists($events, 'setEventPrototype')) { |
|
249
|
|
|
/* @var \Zend\EventManager\EventInterface $event */ |
|
250
|
|
|
$event = $services->has($config['event']) ? $services->get($config['event']) : new $config['event'](); |
|
251
|
|
|
$events->setEventPrototype($event); |
|
252
|
|
|
} |
|
253
|
|
|
else { |
|
254
|
|
|
$events->setEventClass($config['event']); |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
if ('EventManager' != $config['service'] && method_exists($events, 'setSharedManager') && $services->has('SharedEventManager')) { |
|
258
|
|
|
/* @var \Zend\EventManager\SharedEventManagerInterface $sharedEvents */ |
|
259
|
|
|
$sharedEvents = $services->get('SharedEventManager'); |
|
260
|
|
|
$events->setSharedManager($sharedEvents); |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
return $events; |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
/** |
|
267
|
|
|
* Attaches listeners provided in the config to the event manager instance. |
|
268
|
|
|
* |
|
269
|
|
|
* @param ServiceLocatorInterface $services |
|
270
|
|
|
* @param \Zend\EventManager\EventManagerInterface $eventManager |
|
271
|
|
|
* @param array $listeners |
|
272
|
|
|
* |
|
273
|
|
|
* @throws \UnexpectedValueException if a listener name cannot be fetched as service or be instantiated. |
|
274
|
|
|
*/ |
|
275
|
|
|
protected function attachListeners($services, $eventManager, $listeners) |
|
276
|
|
|
{ |
|
277
|
|
|
$lazyListeners = []; |
|
278
|
|
|
|
|
279
|
|
|
foreach ($listeners as $name => $options) { |
|
280
|
|
|
$options = $this->normalizeListenerOptions($name, $options); |
|
281
|
|
|
|
|
282
|
|
|
if ($options['lazy'] && null !== $options['attach'] ) { |
|
283
|
|
|
foreach ($options['attach'] as $spec) { |
|
284
|
|
|
$lazyListeners[] = [ |
|
285
|
|
|
'service' => $options['service'], |
|
286
|
|
|
'event' => $spec['events'], |
|
287
|
|
|
'method' => $spec['method'], |
|
288
|
|
|
'priority' => $spec['priority'], |
|
289
|
|
|
]; |
|
290
|
|
|
} |
|
291
|
|
|
continue; |
|
292
|
|
|
} |
|
293
|
|
|
|
|
294
|
|
View Code Duplication |
if ($services->has($options['service'])) { |
|
|
|
|
|
|
295
|
|
|
$listener = $services->get($options['service']); |
|
296
|
|
|
|
|
297
|
|
|
} else if (class_exists($options['service'], true)) { |
|
298
|
|
|
$listener = new $options['service'](); |
|
299
|
|
|
|
|
300
|
|
|
} else { |
|
301
|
|
|
throw new \UnexpectedValueException(sprintf( |
|
302
|
|
|
'Class or service %s does not exists. Cannot create listener instance.', $options['service'] |
|
303
|
|
|
)); |
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
if ($listener instanceOf ListenerAggregateInterface) { |
|
307
|
|
|
$listener->attach($eventManager, $options['priority']); |
|
|
|
|
|
|
308
|
|
|
continue; |
|
309
|
|
|
} |
|
310
|
|
|
|
|
311
|
|
|
foreach ($options['attach'] as $spec) { |
|
312
|
|
|
$callback = $spec['method'] ? [ $listener, $spec['method'] ] : $listener; |
|
313
|
|
|
$eventManager->attach($spec['events'], $callback, $spec['priority']); |
|
314
|
|
|
} |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
if (!empty($lazyListeners)) { |
|
318
|
|
|
/* @var \Core\Listener\DeferredListenerAggregate $aggregate */ |
|
319
|
|
|
$aggregate = $services->get('Core/Listener/DeferredListenerAggregate'); |
|
320
|
|
|
$aggregate->setListeners($lazyListeners) |
|
321
|
|
|
->attach($eventManager); |
|
322
|
|
|
} |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
/** |
|
326
|
|
|
* Normalizes the listener configuration. |
|
327
|
|
|
* |
|
328
|
|
|
* Converts the options given in the main config file to an array |
|
329
|
|
|
* containing key => value pairs for easier consumption in |
|
330
|
|
|
* {@link attachListeners()} |
|
331
|
|
|
* |
|
332
|
|
|
* @param int|string $name Service or class name of the listener. (if int, we have config for an aggregate) |
|
333
|
|
|
* @param string|array $options String is either event name or aggregate name (when name is int). |
|
334
|
|
|
* Array are the options from config. [ [event,..], method, priority, lazy] |
|
335
|
|
|
* |
|
336
|
|
|
* @return array |
|
337
|
|
|
*/ |
|
338
|
|
|
protected function normalizeListenerOptions($name, $options) |
|
339
|
|
|
{ |
|
340
|
|
|
|
|
341
|
|
|
/* |
|
|
|
|
|
|
342
|
|
|
* $options is an array with following meta-syntax: |
|
343
|
|
|
* |
|
344
|
|
|
* $options = [ |
|
345
|
|
|
* string:listener => string:event, |
|
346
|
|
|
* string:listener => [ string|array:event{, string:methodName}{, int:priority}{, bool:lazy }], |
|
347
|
|
|
* string:aggregate, // implies integer value as $name |
|
348
|
|
|
* string:aggregate => int:priority, |
|
349
|
|
|
* string:listener => [ |
|
350
|
|
|
* 'events' => [ 'event', 'event' => priority, 'event' => 'method', |
|
351
|
|
|
* 'event' => [ 'method' => method, 'priority' => priority ], |
|
352
|
|
|
* 'event' => [ 'method' => [ 'method', 'method' => priority ], 'priority' => priority ] |
|
353
|
|
|
* ], |
|
354
|
|
|
* 'method' => method, |
|
355
|
|
|
* 'priority' => priority, |
|
356
|
|
|
* 'lazy' => bool |
|
357
|
|
|
* ] |
|
358
|
|
|
*/ |
|
359
|
|
|
|
|
360
|
|
|
$normalized = [ |
|
361
|
|
|
'service' => $name, |
|
362
|
|
|
'attach' => null, |
|
363
|
|
|
'priority' => 0, |
|
364
|
|
|
'lazy' => false, |
|
365
|
|
|
]; |
|
366
|
|
|
|
|
367
|
|
|
if (is_int($name)) { |
|
368
|
|
|
/* $options must be the name of an aggregate service or class. */ |
|
369
|
|
|
$normalized['service'] = $options; |
|
370
|
|
|
return $normalized; |
|
371
|
|
|
|
|
372
|
|
|
} |
|
373
|
|
|
|
|
374
|
|
|
if (is_int($options)) { |
|
375
|
|
|
/* $name must be the name of an aggregate and the priority is passed. */ |
|
376
|
|
|
$normalized['priority'] = $options; |
|
377
|
|
|
return $normalized; |
|
378
|
|
|
|
|
379
|
|
|
} |
|
380
|
|
|
|
|
381
|
|
|
if (is_string($options)) { |
|
382
|
|
|
/* Only an event name is provided in config */ |
|
383
|
|
|
$normalized['attach'] = [ [ 'events' => [ $options ], 'method' => null, 'priority' => 0 ] ]; |
|
384
|
|
|
return $normalized; |
|
385
|
|
|
|
|
386
|
|
|
} |
|
387
|
|
|
|
|
388
|
|
|
if (ArrayUtils::isHashTable($options)) { |
|
389
|
|
|
$normalized['attach'] = $this->normalizeEventsSpec($options); |
|
390
|
|
|
|
|
391
|
|
|
if (isset($options['lazy'])) { |
|
392
|
|
|
$normalized['lazy'] = $options['lazy']; |
|
393
|
|
|
} |
|
394
|
|
|
|
|
395
|
|
|
return $normalized; |
|
396
|
|
|
|
|
397
|
|
|
} |
|
398
|
|
|
|
|
399
|
|
|
$event = $method = null; |
|
400
|
|
|
$priority = 0; |
|
401
|
|
|
$lazy = false; |
|
402
|
|
|
|
|
403
|
|
|
foreach ($options as $opt) { |
|
404
|
|
|
|
|
405
|
|
|
if (is_array($opt)) { |
|
406
|
|
|
/* Must be event names */ |
|
407
|
|
|
$event = $opt; |
|
408
|
|
|
|
|
409
|
|
|
} else if (is_string($opt)) { |
|
410
|
|
|
if (null === $event) { |
|
411
|
|
|
/* first string found is assumed to be the event name */ |
|
412
|
|
|
$event = [ $opt ]; |
|
413
|
|
|
} else { |
|
414
|
|
|
/* second string found must be a method name. */ |
|
415
|
|
|
$method = $opt; |
|
416
|
|
|
} |
|
417
|
|
|
|
|
418
|
|
|
} else if (is_int($opt)) { |
|
419
|
|
|
/* Integer values must be priority */ |
|
420
|
|
|
$priority = $opt; |
|
421
|
|
|
|
|
422
|
|
|
} else if (is_bool($opt)) { |
|
423
|
|
|
/* Lazy option is passed. */ |
|
424
|
|
|
$lazy = $opt; |
|
425
|
|
|
} |
|
426
|
|
|
} |
|
427
|
|
|
|
|
428
|
|
|
$normalized['attach'] = [ [ 'events' => $event, 'method' => $method, 'priority' => $priority ] ]; |
|
429
|
|
|
$normalized['lazy'] = $lazy; |
|
430
|
|
|
|
|
431
|
|
|
return $normalized; |
|
432
|
|
|
} |
|
433
|
|
|
|
|
434
|
|
|
protected function normalizeEventsSpec($options) |
|
435
|
|
|
{ |
|
436
|
|
|
$listenerPriority = isset($options['priority']) ? $options['priority'] : 0; |
|
437
|
|
|
$listenerMethod = isset($options['method']) ? $options['method'] : '__none__'; |
|
438
|
|
|
$events = []; |
|
439
|
|
|
|
|
440
|
|
|
foreach ($options['events'] as $event => $spec) { |
|
441
|
|
|
|
|
442
|
|
|
|
|
443
|
|
|
$eventPriority = isset($spec['priority']) ? $spec['priority'] : $listenerPriority; |
|
444
|
|
|
|
|
445
|
|
|
if (is_int($event)) { |
|
446
|
|
|
$events[$listenerMethod][$eventPriority][] = $spec; |
|
447
|
|
|
|
|
448
|
|
|
} else if (is_int($spec)) { |
|
449
|
|
|
$events[$listenerMethod][$spec][] = $event; |
|
450
|
|
|
|
|
451
|
|
|
} else if (is_string($spec)) { |
|
452
|
|
|
$events[$spec][$eventPriority][] = $event; |
|
453
|
|
|
|
|
454
|
|
|
} else if (is_array($spec)) { |
|
455
|
|
|
if (isset($spec['method'])) { |
|
456
|
|
|
if (!is_array($spec['method'])) { |
|
457
|
|
|
$spec['method'] = [ $spec['method'] ]; |
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
|
foreach ($spec['method'] as $method => $methodPriority) { |
|
461
|
|
|
if (is_int($method)) { |
|
462
|
|
|
$events[$methodPriority][$eventPriority][] = $event; |
|
463
|
|
|
|
|
464
|
|
|
} else if (is_int($methodPriority)) { |
|
465
|
|
|
$events[$method][$methodPriority][] = $event; |
|
466
|
|
|
} |
|
467
|
|
|
} |
|
468
|
|
|
} |
|
469
|
|
|
} |
|
470
|
|
|
} |
|
471
|
|
|
|
|
472
|
|
|
$eventsSpec = []; |
|
473
|
|
|
foreach ($events as $method => $priorities) { |
|
474
|
|
|
foreach ($priorities as $priority => $event) { |
|
475
|
|
|
$eventsSpec[] = [ |
|
476
|
|
|
'events' => $event, |
|
477
|
|
|
'method' => '__none__' == $method ? null : $method, |
|
478
|
|
|
'priority' => $priority, |
|
479
|
|
|
]; |
|
480
|
|
|
} |
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
return $eventsSpec; |
|
484
|
|
|
} |
|
485
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.