|
25 | 25 |
|
26 | 26 | class Dispatcher implements DispatcherContract
|
27 | 27 | {
|
28 |
| - use Macroable, ReflectsClosures; |
| 28 | + use EventHooks, Macroable, ReflectsClosures; |
29 | 29 |
|
30 | 30 | /**
|
31 | 31 | * The IoC container instance.
|
@@ -216,7 +216,7 @@ public function subscribe($subscriber)
|
216 | 216 | protected function resolveSubscriber($subscriber)
|
217 | 217 | {
|
218 | 218 | if (is_string($subscriber)) {
|
219 |
| - return $this->container->make($subscriber); |
| 219 | + return $this->getContainer()->make($subscriber); |
220 | 220 | }
|
221 | 221 |
|
222 | 222 | return $subscriber;
|
@@ -278,32 +278,61 @@ public function dispatch($event, $payload = [], $halt = false)
|
278 | 278 | */
|
279 | 279 | protected function invokeListeners($event, $payload, $halt = false)
|
280 | 280 | {
|
| 281 | + // If a callback throws an EventPropagationException, no further |
| 282 | + // callbacks are run and the event is not dispatched to listeners. |
| 283 | + try { |
| 284 | + if ($this->hasCallbacks(static::HOOK_BEFORE, $event)) { |
| 285 | + $this->invokeCallbacks(static::HOOK_BEFORE, $event, $payload); |
| 286 | + } |
| 287 | + } catch (EventPropagationException) { |
| 288 | + return null; |
| 289 | + } |
| 290 | + |
281 | 291 | if ($this->shouldBroadcast($payload)) {
|
282 | 292 | $this->broadcastEvent($payload[0]);
|
283 | 293 | }
|
284 | 294 |
|
285 | 295 | $responses = [];
|
| 296 | + $failure = false; |
286 | 297 |
|
287 | 298 | foreach ($this->getListeners($event) as $listener) {
|
288 | 299 | $response = $listener($event, $payload);
|
289 | 300 |
|
290 |
| - // If a response is returned from the listener and event halting is enabled |
291 |
| - // we will just return this response, and not call the rest of the event |
292 |
| - // listeners. Otherwise we will add the response on the response list. |
| 301 | + // If a response is returned from the listener and event halting is enabled, we |
| 302 | + // will fire the after callbacks (or the failure callbacks when boolean false is |
| 303 | + // returned, indicating failure), return this response, and not call the rest of |
| 304 | + // the event listeners, otherwise we will add the response to the response list. |
293 | 305 | if ($halt && ! is_null($response)) {
|
| 306 | + $hook = $response === false ? static::HOOK_FAILURE : static::HOOK_AFTER; |
| 307 | + if ($this->hasCallbacks($hook, $event)) { |
| 308 | + $this->invokeCallbacks($hook, $event, $payload); |
| 309 | + } |
| 310 | + |
294 | 311 | return $response;
|
295 | 312 | }
|
296 | 313 |
|
297 |
| - // If a boolean false is returned from a listener, we will stop propagating |
298 |
| - // the event to any further listeners down in the chain, else we keep on |
299 |
| - // looping through the listeners and firing every one in our sequence. |
| 314 | + // If a boolean false is returned from a listener (indicating failure), we will |
| 315 | + // fire the failure callbacks and stop propagating the event to any further |
| 316 | + // listeners down the chain, otherwise we keep on looping through the listeners |
| 317 | + // and firing each one in our sequence. |
300 | 318 | if ($response === false) {
|
| 319 | + if ($this->hasCallbacks(static::HOOK_FAILURE, $event)) { |
| 320 | + $this->invokeCallbacks(static::HOOK_FAILURE, $event, $payload); |
| 321 | + } |
| 322 | + |
| 323 | + $failure = true; |
| 324 | + |
301 | 325 | break;
|
302 | 326 | }
|
303 | 327 |
|
304 | 328 | $responses[] = $response;
|
305 | 329 | }
|
306 | 330 |
|
| 331 | + // If we've fired all listeners without failure, we will fire the after callbacks. |
| 332 | + if (! $failure && $this->hasCallbacks(static::HOOK_AFTER, $event)) { |
| 333 | + $this->invokeCallbacks(static::HOOK_AFTER, $event, $payload); |
| 334 | + } |
| 335 | + |
307 | 336 | return $halt ? null : $responses;
|
308 | 337 | }
|
309 | 338 |
|
@@ -357,7 +386,7 @@ protected function broadcastWhen($event)
|
357 | 386 | */
|
358 | 387 | protected function broadcastEvent($event)
|
359 | 388 | {
|
360 |
| - $this->container->make(BroadcastFactory::class)->queue($event); |
| 389 | + $this->getContainer()->make(BroadcastFactory::class)->queue($event); |
361 | 390 | }
|
362 | 391 |
|
363 | 392 | /**
|
@@ -502,7 +531,7 @@ protected function createClassCallable($listener)
|
502 | 531 | return $this->createQueuedHandlerCallable($class, $method);
|
503 | 532 | }
|
504 | 533 |
|
505 |
| - $listener = $this->container->make($class); |
| 534 | + $listener = $this->getContainer()->make($class); |
506 | 535 |
|
507 | 536 | return $this->handlerShouldBeDispatchedAfterDatabaseTransactions($listener)
|
508 | 537 | ? $this->createCallbackForListenerRunningAfterCommits($listener, $method)
|
@@ -599,7 +628,7 @@ function () use ($listener, $method, $payload) {
|
599 | 628 | */
|
600 | 629 | protected function handlerWantsToBeQueued($class, $arguments)
|
601 | 630 | {
|
602 |
| - $instance = $this->container->make($class); |
| 631 | + $instance = $this->getContainer()->make($class); |
603 | 632 |
|
604 | 633 | if (method_exists($instance, 'shouldQueue')) {
|
605 | 634 | return $instance->shouldQueue($arguments[0]);
|
|
0 commit comments