Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,560 +0,0 @@
1
-<?php
2
-
3
-namespace Illuminate\Events;
4
-
5
-use Exception;
6
-use ReflectionClass;
7
-use Illuminate\Support\Arr;
8
-use Illuminate\Support\Str;
9
-use Illuminate\Container\Container;
10
-use Illuminate\Contracts\Queue\ShouldQueue;
11
-use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
12
-use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
13
-use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
14
-use Illuminate\Contracts\Container\Container as ContainerContract;
15
-
16
-class Dispatcher implements DispatcherContract
17
-{
18
-    /**
19
-     * The IoC container instance.
20
-     *
21
-     * @var \Illuminate\Contracts\Container\Container
22
-     */
23
-    protected $container;
24
-
25
-    /**
26
-     * The registered event listeners.
27
-     *
28
-     * @var array
29
-     */
30
-    protected $listeners = [];
31
-
32
-    /**
33
-     * The wildcard listeners.
34
-     *
35
-     * @var array
36
-     */
37
-    protected $wildcards = [];
38
-
39
-    /**
40
-     * The cached wildcard listeners.
41
-     *
42
-     * @var array
43
-     */
44
-    protected $wildcardsCache = [];
45
-
46
-    /**
47
-     * The queue resolver instance.
48
-     *
49
-     * @var callable
50
-     */
51
-    protected $queueResolver;
52
-
53
-    /**
54
-     * Create a new event dispatcher instance.
55
-     *
56
-     * @param  \Illuminate\Contracts\Container\Container|null  $container
57
-     * @return void
58
-     */
59
-    public function __construct(ContainerContract $container = null)
60
-    {
61
-        $this->container = $container ?: new Container;
62
-    }
63
-
64
-    /**
65
-     * Register an event listener with the dispatcher.
66
-     *
67
-     * @param  string|array  $events
68
-     * @param  mixed  $listener
69
-     * @return void
70
-     */
71
-    public function listen($events, $listener)
72
-    {
73
-        foreach ((array) $events as $event) {
74
-            if (Str::contains($event, '*')) {
75
-                $this->setupWildcardListen($event, $listener);
76
-            } else {
77
-                $this->listeners[$event][] = $this->makeListener($listener);
78
-            }
79
-        }
80
-    }
81
-
82
-    /**
83
-     * Setup a wildcard listener callback.
84
-     *
85
-     * @param  string  $event
86
-     * @param  mixed  $listener
87
-     * @return void
88
-     */
89
-    protected function setupWildcardListen($event, $listener)
90
-    {
91
-        $this->wildcards[$event][] = $this->makeListener($listener, true);
92
-
93
-        $this->wildcardsCache = [];
94
-    }
95
-
96
-    /**
97
-     * Determine if a given event has listeners.
98
-     *
99
-     * @param  string  $eventName
100
-     * @return bool
101
-     */
102
-    public function hasListeners($eventName)
103
-    {
104
-        return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]);
105
-    }
106
-
107
-    /**
108
-     * Register an event and payload to be fired later.
109
-     *
110
-     * @param  string  $event
111
-     * @param  array  $payload
112
-     * @return void
113
-     */
114
-    public function push($event, $payload = [])
115
-    {
116
-        $this->listen($event.'_pushed', function () use ($event, $payload) {
117
-            $this->dispatch($event, $payload);
118
-        });
119
-    }
120
-
121
-    /**
122
-     * Flush a set of pushed events.
123
-     *
124
-     * @param  string  $event
125
-     * @return void
126
-     */
127
-    public function flush($event)
128
-    {
129
-        $this->dispatch($event.'_pushed');
130
-    }
131
-
132
-    /**
133
-     * Register an event subscriber with the dispatcher.
134
-     *
135
-     * @param  object|string  $subscriber
136
-     * @return void
137
-     */
138
-    public function subscribe($subscriber)
139
-    {
140
-        $subscriber = $this->resolveSubscriber($subscriber);
141
-
142
-        $subscriber->subscribe($this);
143
-    }
144
-
145
-    /**
146
-     * Resolve the subscriber instance.
147
-     *
148
-     * @param  object|string  $subscriber
149
-     * @return mixed
150
-     */
151
-    protected function resolveSubscriber($subscriber)
152
-    {
153
-        if (is_string($subscriber)) {
154
-            return $this->container->make($subscriber);
155
-        }
156
-
157
-        return $subscriber;
158
-    }
159
-
160
-    /**
161
-     * Fire an event until the first non-null response is returned.
162
-     *
163
-     * @param  string|object  $event
164
-     * @param  mixed  $payload
165
-     * @return array|null
166
-     */
167
-    public function until($event, $payload = [])
168
-    {
169
-        return $this->dispatch($event, $payload, true);
170
-    }
171
-
172
-    /**
173
-     * Fire an event and call the listeners.
174
-     *
175
-     * @param  string|object  $event
176
-     * @param  mixed  $payload
177
-     * @param  bool  $halt
178
-     * @return array|null
179
-     */
180
-    public function dispatch($event, $payload = [], $halt = false)
181
-    {
182
-        // When the given "event" is actually an object we will assume it is an event
183
-        // object and use the class as the event name and this event itself as the
184
-        // payload to the handler, which makes object based events quite simple.
185
-        [$event, $payload] = $this->parseEventAndPayload(
186
-            $event, $payload
187
-        );
188
-
189
-        if ($this->shouldBroadcast($payload)) {
190
-            $this->broadcastEvent($payload[0]);
191
-        }
192
-
193
-        $responses = [];
194
-
195
-        foreach ($this->getListeners($event) as $listener) {
196
-            $response = $listener($event, $payload);
197
-
198
-            // If a response is returned from the listener and event halting is enabled
199
-            // we will just return this response, and not call the rest of the event
200
-            // listeners. Otherwise we will add the response on the response list.
201
-            if ($halt && ! is_null($response)) {
202
-                return $response;
203
-            }
204
-
205
-            // If a boolean false is returned from a listener, we will stop propagating
206
-            // the event to any further listeners down in the chain, else we keep on
207
-            // looping through the listeners and firing every one in our sequence.
208
-            if ($response === false) {
209
-                break;
210
-            }
211
-
212
-            $responses[] = $response;
213
-        }
214
-
215
-        return $halt ? null : $responses;
216
-    }
217
-
218
-    /**
219
-     * Parse the given event and payload and prepare them for dispatching.
220
-     *
221
-     * @param  mixed  $event
222
-     * @param  mixed  $payload
223
-     * @return array
224
-     */
225
-    protected function parseEventAndPayload($event, $payload)
226
-    {
227
-        if (is_object($event)) {
228
-            [$payload, $event] = [[$event], get_class($event)];
229
-        }
230
-
231
-        return [$event, Arr::wrap($payload)];
232
-    }
233
-
234
-    /**
235
-     * Determine if the payload has a broadcastable event.
236
-     *
237
-     * @param  array  $payload
238
-     * @return bool
239
-     */
240
-    protected function shouldBroadcast(array $payload)
241
-    {
242
-        return isset($payload[0]) &&
243
-               $payload[0] instanceof ShouldBroadcast &&
244
-               $this->broadcastWhen($payload[0]);
245
-    }
246
-
247
-    /**
248
-     * Check if event should be broadcasted by condition.
249
-     *
250
-     * @param  mixed  $event
251
-     * @return bool
252
-     */
253
-    protected function broadcastWhen($event)
254
-    {
255
-        return method_exists($event, 'broadcastWhen')
256
-                ? $event->broadcastWhen() : true;
257
-    }
258
-
259
-    /**
260
-     * Broadcast the given event class.
261
-     *
262
-     * @param  \Illuminate\Contracts\Broadcasting\ShouldBroadcast  $event
263
-     * @return void
264
-     */
265
-    protected function broadcastEvent($event)
266
-    {
267
-        $this->container->make(BroadcastFactory::class)->queue($event);
268
-    }
269
-
270
-    /**
271
-     * Get all of the listeners for a given event name.
272
-     *
273
-     * @param  string  $eventName
274
-     * @return array
275
-     */
276
-    public function getListeners($eventName)
277
-    {
278
-        $listeners = $this->listeners[$eventName] ?? [];
279
-
280
-        $listeners = array_merge(
281
-            $listeners,
282
-            $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName)
283
-        );
284
-
285
-        return class_exists($eventName, false)
286
-                    ? $this->addInterfaceListeners($eventName, $listeners)
287
-                    : $listeners;
288
-    }
289
-
290
-    /**
291
-     * Get the wildcard listeners for the event.
292
-     *
293
-     * @param  string  $eventName
294
-     * @return array
295
-     */
296
-    protected function getWildcardListeners($eventName)
297
-    {
298
-        $wildcards = [];
299
-
300
-        foreach ($this->wildcards as $key => $listeners) {
301
-            if (Str::is($key, $eventName)) {
302
-                $wildcards = array_merge($wildcards, $listeners);
303
-            }
304
-        }
305
-
306
-        return $this->wildcardsCache[$eventName] = $wildcards;
307
-    }
308
-
309
-    /**
310
-     * Add the listeners for the event's interfaces to the given array.
311
-     *
312
-     * @param  string  $eventName
313
-     * @param  array  $listeners
314
-     * @return array
315
-     */
316
-    protected function addInterfaceListeners($eventName, array $listeners = [])
317
-    {
318
-        foreach (class_implements($eventName) as $interface) {
319
-            if (isset($this->listeners[$interface])) {
320
-                foreach ($this->listeners[$interface] as $names) {
321
-                    $listeners = array_merge($listeners, (array) $names);
322
-                }
323
-            }
324
-        }
325
-
326
-        return $listeners;
327
-    }
328
-
329
-    /**
330
-     * Register an event listener with the dispatcher.
331
-     *
332
-     * @param  \Closure|string  $listener
333
-     * @param  bool  $wildcard
334
-     * @return \Closure
335
-     */
336
-    public function makeListener($listener, $wildcard = false)
337
-    {
338
-        if (is_string($listener)) {
339
-            return $this->createClassListener($listener, $wildcard);
340
-        }
341
-
342
-        return function ($event, $payload) use ($listener, $wildcard) {
343
-            if ($wildcard) {
344
-                return $listener($event, $payload);
345
-            }
346
-
347
-            return $listener(...array_values($payload));
348
-        };
349
-    }
350
-
351
-    /**
352
-     * Create a class based listener using the IoC container.
353
-     *
354
-     * @param  string  $listener
355
-     * @param  bool  $wildcard
356
-     * @return \Closure
357
-     */
358
-    public function createClassListener($listener, $wildcard = false)
359
-    {
360
-        return function ($event, $payload) use ($listener, $wildcard) {
361
-            if ($wildcard) {
362
-                return call_user_func($this->createClassCallable($listener), $event, $payload);
363
-            }
364
-
365
-            return call_user_func_array(
366
-                $this->createClassCallable($listener), $payload
367
-            );
368
-        };
369
-    }
370
-
371
-    /**
372
-     * Create the class based event callable.
373
-     *
374
-     * @param  string  $listener
375
-     * @return callable
376
-     */
377
-    protected function createClassCallable($listener)
378
-    {
379
-        [$class, $method] = $this->parseClassCallable($listener);
380
-
381
-        if ($this->handlerShouldBeQueued($class)) {
382
-            return $this->createQueuedHandlerCallable($class, $method);
383
-        }
384
-
385
-        return [$this->container->make($class), $method];
386
-    }
387
-
388
-    /**
389
-     * Parse the class listener into class and method.
390
-     *
391
-     * @param  string  $listener
392
-     * @return array
393
-     */
394
-    protected function parseClassCallable($listener)
395
-    {
396
-        return Str::parseCallback($listener, 'handle');
397
-    }
398
-
399
-    /**
400
-     * Determine if the event handler class should be queued.
401
-     *
402
-     * @param  string  $class
403
-     * @return bool
404
-     */
405
-    protected function handlerShouldBeQueued($class)
406
-    {
407
-        try {
408
-            return (new ReflectionClass($class))->implementsInterface(
409
-                ShouldQueue::class
410
-            );
411
-        } catch (Exception $e) {
412
-            return false;
413
-        }
414
-    }
415
-
416
-    /**
417
-     * Create a callable for putting an event handler on the queue.
418
-     *
419
-     * @param  string  $class
420
-     * @param  string  $method
421
-     * @return \Closure
422
-     */
423
-    protected function createQueuedHandlerCallable($class, $method)
424
-    {
425
-        return function () use ($class, $method) {
426
-            $arguments = array_map(function ($a) {
427
-                return is_object($a) ? clone $a : $a;
428
-            }, func_get_args());
429
-
430
-            if ($this->handlerWantsToBeQueued($class, $arguments)) {
431
-                $this->queueHandler($class, $method, $arguments);
432
-            }
433
-        };
434
-    }
435
-
436
-    /**
437
-     * Determine if the event handler wants to be queued.
438
-     *
439
-     * @param  string  $class
440
-     * @param  array  $arguments
441
-     * @return bool
442
-     */
443
-    protected function handlerWantsToBeQueued($class, $arguments)
444
-    {
445
-        if (method_exists($class, 'shouldQueue')) {
446
-            return $this->container->make($class)->shouldQueue($arguments[0]);
447
-        }
448
-
449
-        return true;
450
-    }
451
-
452
-    /**
453
-     * Queue the handler class.
454
-     *
455
-     * @param  string  $class
456
-     * @param  string  $method
457
-     * @param  array  $arguments
458
-     * @return void
459
-     */
460
-    protected function queueHandler($class, $method, $arguments)
461
-    {
462
-        [$listener, $job] = $this->createListenerAndJob($class, $method, $arguments);
463
-
464
-        $connection = $this->resolveQueue()->connection(
465
-            $listener->connection ?? null
466
-        );
467
-
468
-        $queue = $listener->queue ?? null;
469
-
470
-        isset($listener->delay)
471
-                    ? $connection->laterOn($queue, $listener->delay, $job)
472
-                    : $connection->pushOn($queue, $job);
473
-    }
474
-
475
-    /**
476
-     * Create the listener and job for a queued listener.
477
-     *
478
-     * @param  string  $class
479
-     * @param  string  $method
480
-     * @param  array  $arguments
481
-     * @return array
482
-     */
483
-    protected function createListenerAndJob($class, $method, $arguments)
484
-    {
485
-        $listener = (new ReflectionClass($class))->newInstanceWithoutConstructor();
486
-
487
-        return [$listener, $this->propagateListenerOptions(
488
-            $listener, new CallQueuedListener($class, $method, $arguments)
489
-        )];
490
-    }
491
-
492
-    /**
493
-     * Propagate listener options to the job.
494
-     *
495
-     * @param  mixed  $listener
496
-     * @param  mixed  $job
497
-     * @return mixed
498
-     */
499
-    protected function propagateListenerOptions($listener, $job)
500
-    {
501
-        return tap($job, function ($job) use ($listener) {
502
-            $job->tries = $listener->tries ?? null;
503
-            $job->timeout = $listener->timeout ?? null;
504
-            $job->timeoutAt = method_exists($listener, 'retryUntil')
505
-                                ? $listener->retryUntil() : null;
506
-        });
507
-    }
508
-
509
-    /**
510
-     * Remove a set of listeners from the dispatcher.
511
-     *
512
-     * @param  string  $event
513
-     * @return void
514
-     */
515
-    public function forget($event)
516
-    {
517
-        if (Str::contains($event, '*')) {
518
-            unset($this->wildcards[$event]);
519
-        } else {
520
-            unset($this->listeners[$event]);
521
-        }
522
-    }
523
-
524
-    /**
525
-     * Forget all of the pushed listeners.
526
-     *
527
-     * @return void
528
-     */
529
-    public function forgetPushed()
530
-    {
531
-        foreach ($this->listeners as $key => $value) {
532
-            if (Str::endsWith($key, '_pushed')) {
533
-                $this->forget($key);
534
-            }
535
-        }
536
-    }
537
-
538
-    /**
539
-     * Get the queue implementation from the resolver.
540
-     *
541
-     * @return \Illuminate\Contracts\Queue\Queue
542
-     */
543
-    protected function resolveQueue()
544
-    {
545
-        return call_user_func($this->queueResolver);
546
-    }
547
-
548
-    /**
549
-     * Set the queue resolver implementation.
550
-     *
551
-     * @param  callable  $resolver
552
-     * @return $this
553
-     */
554
-    public function setQueueResolver(callable $resolver)
555
-    {
556
-        $this->queueResolver = $resolver;
557
-
558
-        return $this;
559
-    }
560
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,560 @@
1
+<?php
2
+
3
+namespace Illuminate\Events;
4
+
5
+use Exception;
6
+use ReflectionClass;
7
+use Illuminate\Support\Arr;
8
+use Illuminate\Support\Str;
9
+use Illuminate\Container\Container;
10
+use Illuminate\Contracts\Queue\ShouldQueue;
11
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
12
+use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
13
+use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
14
+use Illuminate\Contracts\Container\Container as ContainerContract;
15
+
16
+class Dispatcher implements DispatcherContract
17
+{
18
+    /**
19
+     * The IoC container instance.
20
+     *
21
+     * @var \Illuminate\Contracts\Container\Container
22
+     */
23
+    protected $container;
24
+
25
+    /**
26
+     * The registered event listeners.
27
+     *
28
+     * @var array
29
+     */
30
+    protected $listeners = [];
31
+
32
+    /**
33
+     * The wildcard listeners.
34
+     *
35
+     * @var array
36
+     */
37
+    protected $wildcards = [];
38
+
39
+    /**
40
+     * The cached wildcard listeners.
41
+     *
42
+     * @var array
43
+     */
44
+    protected $wildcardsCache = [];
45
+
46
+    /**
47
+     * The queue resolver instance.
48
+     *
49
+     * @var callable
50
+     */
51
+    protected $queueResolver;
52
+
53
+    /**
54
+     * Create a new event dispatcher instance.
55
+     *
56
+     * @param  \Illuminate\Contracts\Container\Container|null  $container
57
+     * @return void
58
+     */
59
+    public function __construct(ContainerContract $container = null)
60
+    {
61
+        $this->container = $container ?: new Container;
62
+    }
63
+
64
+    /**
65
+     * Register an event listener with the dispatcher.
66
+     *
67
+     * @param  string|array  $events
68
+     * @param  mixed  $listener
69
+     * @return void
70
+     */
71
+    public function listen($events, $listener)
72
+    {
73
+        foreach ((array) $events as $event) {
74
+            if (Str::contains($event, '*')) {
75
+                $this->setupWildcardListen($event, $listener);
76
+            } else {
77
+                $this->listeners[$event][] = $this->makeListener($listener);
78
+            }
79
+        }
80
+    }
81
+
82
+    /**
83
+     * Setup a wildcard listener callback.
84
+     *
85
+     * @param  string  $event
86
+     * @param  mixed  $listener
87
+     * @return void
88
+     */
89
+    protected function setupWildcardListen($event, $listener)
90
+    {
91
+        $this->wildcards[$event][] = $this->makeListener($listener, true);
92
+
93
+        $this->wildcardsCache = [];
94
+    }
95
+
96
+    /**
97
+     * Determine if a given event has listeners.
98
+     *
99
+     * @param  string  $eventName
100
+     * @return bool
101
+     */
102
+    public function hasListeners($eventName)
103
+    {
104
+        return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]);
105
+    }
106
+
107
+    /**
108
+     * Register an event and payload to be fired later.
109
+     *
110
+     * @param  string  $event
111
+     * @param  array  $payload
112
+     * @return void
113
+     */
114
+    public function push($event, $payload = [])
115
+    {
116
+        $this->listen($event.'_pushed', function () use ($event, $payload) {
117
+            $this->dispatch($event, $payload);
118
+        });
119
+    }
120
+
121
+    /**
122
+     * Flush a set of pushed events.
123
+     *
124
+     * @param  string  $event
125
+     * @return void
126
+     */
127
+    public function flush($event)
128
+    {
129
+        $this->dispatch($event.'_pushed');
130
+    }
131
+
132
+    /**
133
+     * Register an event subscriber with the dispatcher.
134
+     *
135
+     * @param  object|string  $subscriber
136
+     * @return void
137
+     */
138
+    public function subscribe($subscriber)
139
+    {
140
+        $subscriber = $this->resolveSubscriber($subscriber);
141
+
142
+        $subscriber->subscribe($this);
143
+    }
144
+
145
+    /**
146
+     * Resolve the subscriber instance.
147
+     *
148
+     * @param  object|string  $subscriber
149
+     * @return mixed
150
+     */
151
+    protected function resolveSubscriber($subscriber)
152
+    {
153
+        if (is_string($subscriber)) {
154
+            return $this->container->make($subscriber);
155
+        }
156
+
157
+        return $subscriber;
158
+    }
159
+
160
+    /**
161
+     * Fire an event until the first non-null response is returned.
162
+     *
163
+     * @param  string|object  $event
164
+     * @param  mixed  $payload
165
+     * @return array|null
166
+     */
167
+    public function until($event, $payload = [])
168
+    {
169
+        return $this->dispatch($event, $payload, true);
170
+    }
171
+
172
+    /**
173
+     * Fire an event and call the listeners.
174
+     *
175
+     * @param  string|object  $event
176
+     * @param  mixed  $payload
177
+     * @param  bool  $halt
178
+     * @return array|null
179
+     */
180
+    public function dispatch($event, $payload = [], $halt = false)
181
+    {
182
+        // When the given "event" is actually an object we will assume it is an event
183
+        // object and use the class as the event name and this event itself as the
184
+        // payload to the handler, which makes object based events quite simple.
185
+        [$event, $payload] = $this->parseEventAndPayload(
186
+            $event, $payload
187
+        );
188
+
189
+        if ($this->shouldBroadcast($payload)) {
190
+            $this->broadcastEvent($payload[0]);
191
+        }
192
+
193
+        $responses = [];
194
+
195
+        foreach ($this->getListeners($event) as $listener) {
196
+            $response = $listener($event, $payload);
197
+
198
+            // If a response is returned from the listener and event halting is enabled
199
+            // we will just return this response, and not call the rest of the event
200
+            // listeners. Otherwise we will add the response on the response list.
201
+            if ($halt && ! is_null($response)) {
202
+                return $response;
203
+            }
204
+
205
+            // If a boolean false is returned from a listener, we will stop propagating
206
+            // the event to any further listeners down in the chain, else we keep on
207
+            // looping through the listeners and firing every one in our sequence.
208
+            if ($response === false) {
209
+                break;
210
+            }
211
+
212
+            $responses[] = $response;
213
+        }
214
+
215
+        return $halt ? null : $responses;
216
+    }
217
+
218
+    /**
219
+     * Parse the given event and payload and prepare them for dispatching.
220
+     *
221
+     * @param  mixed  $event
222
+     * @param  mixed  $payload
223
+     * @return array
224
+     */
225
+    protected function parseEventAndPayload($event, $payload)
226
+    {
227
+        if (is_object($event)) {
228
+            [$payload, $event] = [[$event], get_class($event)];
229
+        }
230
+
231
+        return [$event, Arr::wrap($payload)];
232
+    }
233
+
234
+    /**
235
+     * Determine if the payload has a broadcastable event.
236
+     *
237
+     * @param  array  $payload
238
+     * @return bool
239
+     */
240
+    protected function shouldBroadcast(array $payload)
241
+    {
242
+        return isset($payload[0]) &&
243
+               $payload[0] instanceof ShouldBroadcast &&
244
+               $this->broadcastWhen($payload[0]);
245
+    }
246
+
247
+    /**
248
+     * Check if event should be broadcasted by condition.
249
+     *
250
+     * @param  mixed  $event
251
+     * @return bool
252
+     */
253
+    protected function broadcastWhen($event)
254
+    {
255
+        return method_exists($event, 'broadcastWhen')
256
+                ? $event->broadcastWhen() : true;
257
+    }
258
+
259
+    /**
260
+     * Broadcast the given event class.
261
+     *
262
+     * @param  \Illuminate\Contracts\Broadcasting\ShouldBroadcast  $event
263
+     * @return void
264
+     */
265
+    protected function broadcastEvent($event)
266
+    {
267
+        $this->container->make(BroadcastFactory::class)->queue($event);
268
+    }
269
+
270
+    /**
271
+     * Get all of the listeners for a given event name.
272
+     *
273
+     * @param  string  $eventName
274
+     * @return array
275
+     */
276
+    public function getListeners($eventName)
277
+    {
278
+        $listeners = $this->listeners[$eventName] ?? [];
279
+
280
+        $listeners = array_merge(
281
+            $listeners,
282
+            $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName)
283
+        );
284
+
285
+        return class_exists($eventName, false)
286
+                    ? $this->addInterfaceListeners($eventName, $listeners)
287
+                    : $listeners;
288
+    }
289
+
290
+    /**
291
+     * Get the wildcard listeners for the event.
292
+     *
293
+     * @param  string  $eventName
294
+     * @return array
295
+     */
296
+    protected function getWildcardListeners($eventName)
297
+    {
298
+        $wildcards = [];
299
+
300
+        foreach ($this->wildcards as $key => $listeners) {
301
+            if (Str::is($key, $eventName)) {
302
+                $wildcards = array_merge($wildcards, $listeners);
303
+            }
304
+        }
305
+
306
+        return $this->wildcardsCache[$eventName] = $wildcards;
307
+    }
308
+
309
+    /**
310
+     * Add the listeners for the event's interfaces to the given array.
311
+     *
312
+     * @param  string  $eventName
313
+     * @param  array  $listeners
314
+     * @return array
315
+     */
316
+    protected function addInterfaceListeners($eventName, array $listeners = [])
317
+    {
318
+        foreach (class_implements($eventName) as $interface) {
319
+            if (isset($this->listeners[$interface])) {
320
+                foreach ($this->listeners[$interface] as $names) {
321
+                    $listeners = array_merge($listeners, (array) $names);
322
+                }
323
+            }
324
+        }
325
+
326
+        return $listeners;
327
+    }
328
+
329
+    /**
330
+     * Register an event listener with the dispatcher.
331
+     *
332
+     * @param  \Closure|string  $listener
333
+     * @param  bool  $wildcard
334
+     * @return \Closure
335
+     */
336
+    public function makeListener($listener, $wildcard = false)
337
+    {
338
+        if (is_string($listener)) {
339
+            return $this->createClassListener($listener, $wildcard);
340
+        }
341
+
342
+        return function ($event, $payload) use ($listener, $wildcard) {
343
+            if ($wildcard) {
344
+                return $listener($event, $payload);
345
+            }
346
+
347
+            return $listener(...array_values($payload));
348
+        };
349
+    }
350
+
351
+    /**
352
+     * Create a class based listener using the IoC container.
353
+     *
354
+     * @param  string  $listener
355
+     * @param  bool  $wildcard
356
+     * @return \Closure
357
+     */
358
+    public function createClassListener($listener, $wildcard = false)
359
+    {
360
+        return function ($event, $payload) use ($listener, $wildcard) {
361
+            if ($wildcard) {
362
+                return call_user_func($this->createClassCallable($listener), $event, $payload);
363
+            }
364
+
365
+            return call_user_func_array(
366
+                $this->createClassCallable($listener), $payload
367
+            );
368
+        };
369
+    }
370
+
371
+    /**
372
+     * Create the class based event callable.
373
+     *
374
+     * @param  string  $listener
375
+     * @return callable
376
+     */
377
+    protected function createClassCallable($listener)
378
+    {
379
+        [$class, $method] = $this->parseClassCallable($listener);
380
+
381
+        if ($this->handlerShouldBeQueued($class)) {
382
+            return $this->createQueuedHandlerCallable($class, $method);
383
+        }
384
+
385
+        return [$this->container->make($class), $method];
386
+    }
387
+
388
+    /**
389
+     * Parse the class listener into class and method.
390
+     *
391
+     * @param  string  $listener
392
+     * @return array
393
+     */
394
+    protected function parseClassCallable($listener)
395
+    {
396
+        return Str::parseCallback($listener, 'handle');
397
+    }
398
+
399
+    /**
400
+     * Determine if the event handler class should be queued.
401
+     *
402
+     * @param  string  $class
403
+     * @return bool
404
+     */
405
+    protected function handlerShouldBeQueued($class)
406
+    {
407
+        try {
408
+            return (new ReflectionClass($class))->implementsInterface(
409
+                ShouldQueue::class
410
+            );
411
+        } catch (Exception $e) {
412
+            return false;
413
+        }
414
+    }
415
+
416
+    /**
417
+     * Create a callable for putting an event handler on the queue.
418
+     *
419
+     * @param  string  $class
420
+     * @param  string  $method
421
+     * @return \Closure
422
+     */
423
+    protected function createQueuedHandlerCallable($class, $method)
424
+    {
425
+        return function () use ($class, $method) {
426
+            $arguments = array_map(function ($a) {
427
+                return is_object($a) ? clone $a : $a;
428
+            }, func_get_args());
429
+
430
+            if ($this->handlerWantsToBeQueued($class, $arguments)) {
431
+                $this->queueHandler($class, $method, $arguments);
432
+            }
433
+        };
434
+    }
435
+
436
+    /**
437
+     * Determine if the event handler wants to be queued.
438
+     *
439
+     * @param  string  $class
440
+     * @param  array  $arguments
441
+     * @return bool
442
+     */
443
+    protected function handlerWantsToBeQueued($class, $arguments)
444
+    {
445
+        if (method_exists($class, 'shouldQueue')) {
446
+            return $this->container->make($class)->shouldQueue($arguments[0]);
447
+        }
448
+
449
+        return true;
450
+    }
451
+
452
+    /**
453
+     * Queue the handler class.
454
+     *
455
+     * @param  string  $class
456
+     * @param  string  $method
457
+     * @param  array  $arguments
458
+     * @return void
459
+     */
460
+    protected function queueHandler($class, $method, $arguments)
461
+    {
462
+        [$listener, $job] = $this->createListenerAndJob($class, $method, $arguments);
463
+
464
+        $connection = $this->resolveQueue()->connection(
465
+            $listener->connection ?? null
466
+        );
467
+
468
+        $queue = $listener->queue ?? null;
469
+
470
+        isset($listener->delay)
471
+                    ? $connection->laterOn($queue, $listener->delay, $job)
472
+                    : $connection->pushOn($queue, $job);
473
+    }
474
+
475
+    /**
476
+     * Create the listener and job for a queued listener.
477
+     *
478
+     * @param  string  $class
479
+     * @param  string  $method
480
+     * @param  array  $arguments
481
+     * @return array
482
+     */
483
+    protected function createListenerAndJob($class, $method, $arguments)
484
+    {
485
+        $listener = (new ReflectionClass($class))->newInstanceWithoutConstructor();
486
+
487
+        return [$listener, $this->propagateListenerOptions(
488
+            $listener, new CallQueuedListener($class, $method, $arguments)
489
+        )];
490
+    }
491
+
492
+    /**
493
+     * Propagate listener options to the job.
494
+     *
495
+     * @param  mixed  $listener
496
+     * @param  mixed  $job
497
+     * @return mixed
498
+     */
499
+    protected function propagateListenerOptions($listener, $job)
500
+    {
501
+        return tap($job, function ($job) use ($listener) {
502
+            $job->tries = $listener->tries ?? null;
503
+            $job->timeout = $listener->timeout ?? null;
504
+            $job->timeoutAt = method_exists($listener, 'retryUntil')
505
+                                ? $listener->retryUntil() : null;
506
+        });
507
+    }
508
+
509
+    /**
510
+     * Remove a set of listeners from the dispatcher.
511
+     *
512
+     * @param  string  $event
513
+     * @return void
514
+     */
515
+    public function forget($event)
516
+    {
517
+        if (Str::contains($event, '*')) {
518
+            unset($this->wildcards[$event]);
519
+        } else {
520
+            unset($this->listeners[$event]);
521
+        }
522
+    }
523
+
524
+    /**
525
+     * Forget all of the pushed listeners.
526
+     *
527
+     * @return void
528
+     */
529
+    public function forgetPushed()
530
+    {
531
+        foreach ($this->listeners as $key => $value) {
532
+            if (Str::endsWith($key, '_pushed')) {
533
+                $this->forget($key);
534
+            }
535
+        }
536
+    }
537
+
538
+    /**
539
+     * Get the queue implementation from the resolver.
540
+     *
541
+     * @return \Illuminate\Contracts\Queue\Queue
542
+     */
543
+    protected function resolveQueue()
544
+    {
545
+        return call_user_func($this->queueResolver);
546
+    }
547
+
548
+    /**
549
+     * Set the queue resolver implementation.
550
+     *
551
+     * @param  callable  $resolver
552
+     * @return $this
553
+     */
554
+    public function setQueueResolver(callable $resolver)
555
+    {
556
+        $this->queueResolver = $resolver;
557
+
558
+        return $this;
559
+    }
560
+}