EventListCommand.php
TLDR
This file, EventListCommand.php
, is part of the Illuminate\Foundation\Console
namespace in the Laravel framework. It is responsible for listing the application's events and their corresponding listeners. The command can be executed using the event:list
command.
Methods
handle
This method executes the event:list
command. It retrieves the events and their listeners and displays them in the console output.
getEvents
This method retrieves all the events and listeners configured for the application.
getListenersOnDispatcher
This method retrieves the event and listeners from the dispatcher object.
appendEventInterfaces
This method adds the implemented interfaces of an event to the output.
appendListenerInterfaces
This method adds the implemented interfaces of a listener to the output.
stringifyClosure
This method returns a displayable string representation of a Closure listener.
filterEvents
This method filters the events using the provided event name filter.
filteringByEvent
This method determines whether the user is filtering by an event name.
getRawListeners
This method gets the raw version of event listeners from the event dispatcher.
getEventsDispatcher
This method gets the event dispatcher.
resolveEventsUsing
This static method sets a callback that should be used when resolving the events dispatcher.
<?php
namespace Illuminate\Foundation\Console;
use Closure;
use Illuminate\Console\Command;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Queue\ShouldQueue;
use ReflectionFunction;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand(name: 'event:list')]
class EventListCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'event:list {--event= : Filter the events by name}';
/**
* The console command description.
*
* @var string
*/
protected $description = "List the application's events and listeners";
/**
* The events dispatcher resolver callback.
*
* @var \Closure|null
*/
protected static $eventsResolver;
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$events = $this->getEvents()->sortKeys();
if ($events->isEmpty()) {
$this->components->info("Your application doesn't have any events matching the given criteria.");
return;
}
$this->newLine();
$events->each(function ($listeners, $event) {
$this->components->twoColumnDetail($this->appendEventInterfaces($event));
$this->components->bulletList($listeners);
});
$this->newLine();
}
/**
* Get all of the events and listeners configured for the application.
*
* @return \Illuminate\Support\Collection
*/
protected function getEvents()
{
$events = collect($this->getListenersOnDispatcher());
if ($this->filteringByEvent()) {
$events = $this->filterEvents($events);
}
return $events;
}
/**
* Get the event / listeners from the dispatcher object.
*
* @return array
*/
protected function getListenersOnDispatcher()
{
$events = [];
foreach ($this->getRawListeners() as $event => $rawListeners) {
foreach ($rawListeners as $rawListener) {
if (is_string($rawListener)) {
$events[$event][] = $this->appendListenerInterfaces($rawListener);
} elseif ($rawListener instanceof Closure) {
$events[$event][] = $this->stringifyClosure($rawListener);
} elseif (is_array($rawListener) && count($rawListener) === 2) {
if (is_object($rawListener[0])) {
$rawListener[0] = get_class($rawListener[0]);
}
$events[$event][] = $this->appendListenerInterfaces(implode('@', $rawListener));
}
}
}
return $events;
}
/**
* Add the event implemented interfaces to the output.
*
* @param string $event
* @return string
*/
protected function appendEventInterfaces($event)
{
if (! class_exists($event)) {
return $event;
}
$interfaces = class_implements($event);
if (in_array(ShouldBroadcast::class, $interfaces)) {
$event .= ' <fg=bright-blue>(ShouldBroadcast)</>';
}
return $event;
}
/**
* Add the listener implemented interfaces to the output.
*
* @param string $listener
* @return string
*/
protected function appendListenerInterfaces($listener)
{
$listener = explode('@', $listener);
$interfaces = class_implements($listener[0]);
$listener = implode('@', $listener);
if (in_array(ShouldQueue::class, $interfaces)) {
$listener .= ' <fg=bright-blue>(ShouldQueue)</>';
}
return $listener;
}
/**
* Get a displayable string representation of a Closure listener.
*
* @param \Closure $rawListener
* @return string
*/
protected function stringifyClosure(Closure $rawListener)
{
$reflection = new ReflectionFunction($rawListener);
$path = str_replace([base_path(), DIRECTORY_SEPARATOR], ['', '/'], $reflection->getFileName() ?: '');
return 'Closure at: '.$path.':'.$reflection->getStartLine();
}
/**
* Filter the given events using the provided event name filter.
*
* @param \Illuminate\Support\Collection $events
* @return \Illuminate\Support\Collection
*/
protected function filterEvents($events)
{
if (! $eventName = $this->option('event')) {
return $events;
}
return $events->filter(
fn ($listeners, $event) => str_contains($event, $eventName)
);
}
/**
* Determine whether the user is filtering by an event name.
*
* @return bool
*/
protected function filteringByEvent()
{
return ! empty($this->option('event'));
}
/**
* Gets the raw version of event listeners from the event dispatcher.
*
* @return array
*/
protected function getRawListeners()
{
return $this->getEventsDispatcher()->getRawListeners();
}
/**
* Get the event dispatcher.
*
* @return \Illuminate\Events\Dispatcher
*/
public function getEventsDispatcher()
{
return is_null(self::$eventsResolver)
? $this->getLaravel()->make('events')
: call_user_func(self::$eventsResolver);
}
/**
* Set a callback that should be used when resolving the events dispatcher.
*
* @param \Closure|null $resolver
* @return void
*/
public static function resolveEventsUsing($resolver)
{
static::$eventsResolver = $resolver;
}
}