Skip to content

[12.x] Event Lifecycle Hooks #56150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 40 additions & 11 deletions src/Illuminate/Events/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

class Dispatcher implements DispatcherContract
{
use Macroable, ReflectsClosures;
use EventHooks, Macroable, ReflectsClosures;

/**
* The IoC container instance.
Expand Down Expand Up @@ -216,7 +216,7 @@ public function subscribe($subscriber)
protected function resolveSubscriber($subscriber)
{
if (is_string($subscriber)) {
return $this->container->make($subscriber);
return $this->container()->make($subscriber);
}

return $subscriber;
Expand Down Expand Up @@ -278,32 +278,61 @@ public function dispatch($event, $payload = [], $halt = false)
*/
protected function invokeListeners($event, $payload, $halt = false)
{
// If a callback throws an EventPropagationException, no further
// callbacks are run and the event is not dispatched to listeners.
try {
if ($this->hasCallbacks(static::HOOK_BEFORE, $event, $payload)) {
$this->invokeCallbacks(static::HOOK_BEFORE, $event, $payload);
}
} catch (EventPropagationException) {
return null;
}

if ($this->shouldBroadcast($payload)) {
$this->broadcastEvent($payload[0]);
}

$responses = [];
$failure = false;

foreach ($this->getListeners($event) as $listener) {
$response = $listener($event, $payload);

// If a response is returned from the listener and event halting is enabled
// we will just return this response, and not call the rest of the event
// listeners. Otherwise we will add the response on the response list.
// If a response is returned from the listener and event halting is enabled, we
// will fire the after callbacks (or the failure callbacks when boolean false is
// returned, indicating failure), return this response, and not call the rest of
// the event listeners, otherwise we will add the response to the response list.
if ($halt && ! is_null($response)) {
$hook = $response === false ? static::HOOK_FAILURE : static::HOOK_AFTER;
if ($this->hasCallbacks($hook, $event, $payload)) {
$this->invokeCallbacks($hook, $event, $payload);
}

return $response;
}

// If a boolean false is returned from a listener, we will stop propagating
// the event to any further listeners down in the chain, else we keep on
// looping through the listeners and firing every one in our sequence.
// If a boolean false is returned from a listener (indicating failure), we will
// fire the failure callbacks and stop propagating the event to any further
// listeners down the chain, otherwise we keep on looping through the listeners
// and firing each one in our sequence.
if ($response === false) {
if ($this->hasCallbacks(static::HOOK_FAILURE, $event, $payload)) {
$this->invokeCallbacks(static::HOOK_FAILURE, $event, $payload);
}

$failure = true;

break;
}

$responses[] = $response;
}

// If we've fired all listeners without failure, we will fire the after callbacks.
if (! $failure && $this->hasCallbacks(static::HOOK_AFTER, $event, $payload)) {
$this->invokeCallbacks(static::HOOK_AFTER, $event, $payload);
}

return $halt ? null : $responses;
}

Expand Down Expand Up @@ -357,7 +386,7 @@ protected function broadcastWhen($event)
*/
protected function broadcastEvent($event)
{
$this->container->make(BroadcastFactory::class)->queue($event);
$this->container()->make(BroadcastFactory::class)->queue($event);
}

/**
Expand Down Expand Up @@ -502,7 +531,7 @@ protected function createClassCallable($listener)
return $this->createQueuedHandlerCallable($class, $method);
}

$listener = $this->container->make($class);
$listener = $this->container()->make($class);

return $this->handlerShouldBeDispatchedAfterDatabaseTransactions($listener)
? $this->createCallbackForListenerRunningAfterCommits($listener, $method)
Expand Down Expand Up @@ -599,7 +628,7 @@ function () use ($listener, $method, $payload) {
*/
protected function handlerWantsToBeQueued($class, $arguments)
{
$instance = $this->container->make($class);
$instance = $this->container()->make($class);

if (method_exists($instance, 'shouldQueue')) {
return $instance->shouldQueue($arguments[0]);
Expand Down
Loading