DiscoverEvents.php
TLDR
This file contains the DiscoverEvents
class with several methods for discovering events and listeners in a listener directory.
Methods
within
This method takes a listener directory path and a base path as parameters and returns an array containing all the discovered events and their corresponding listeners.
getListenerEvents
This method takes an iterable of listeners and the base path as parameters and returns an array of the listeners with their corresponding events.
classFromFile
This method takes a SplFileInfo
object and the base path as parameters and returns the class name extracted from the given file path.
guessClassNamesUsing
This method takes a callback function as a parameter and sets it as the callback to be used for guessing class names.
Classes
None
<?php
namespace Illuminate\Foundation\Events;
use Illuminate\Support\Reflector;
use Illuminate\Support\Str;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use SplFileInfo;
use Symfony\Component\Finder\Finder;
class DiscoverEvents
{
/**
* The callback to be used to guess class names.
*
* @var callable(SplFileInfo, string): string|null
*/
public static $guessClassNamesUsingCallback;
/**
* Get all of the events and listeners by searching the given listener directory.
*
* @param string $listenerPath
* @param string $basePath
* @return array
*/
public static function within($listenerPath, $basePath)
{
$listeners = collect(static::getListenerEvents(
(new Finder)->files()->in($listenerPath), $basePath
));
$discoveredEvents = [];
foreach ($listeners as $listener => $events) {
foreach ($events as $event) {
if (! isset($discoveredEvents[$event])) {
$discoveredEvents[$event] = [];
}
$discoveredEvents[$event][] = $listener;
}
}
return $discoveredEvents;
}
/**
* Get all of the listeners and their corresponding events.
*
* @param iterable $listeners
* @param string $basePath
* @return array
*/
protected static function getListenerEvents($listeners, $basePath)
{
$listenerEvents = [];
foreach ($listeners as $listener) {
try {
$listener = new ReflectionClass(
static::classFromFile($listener, $basePath)
);
} catch (ReflectionException) {
continue;
}
if (! $listener->isInstantiable()) {
continue;
}
foreach ($listener->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if ((! Str::is('handle*', $method->name) && ! Str::is('__invoke', $method->name)) ||
! isset($method->getParameters()[0])) {
continue;
}
$listenerEvents[$listener->name.'@'.$method->name] =
Reflector::getParameterClassNames($method->getParameters()[0]);
}
}
return array_filter($listenerEvents);
}
/**
* Extract the class name from the given file path.
*
* @param \SplFileInfo $file
* @param string $basePath
* @return string
*/
protected static function classFromFile(SplFileInfo $file, $basePath)
{
if (static::$guessClassNamesUsingCallback) {
return call_user_func(static::$guessClassNamesUsingCallback, $file, $basePath);
}
$class = trim(Str::replaceFirst($basePath, '', $file->getRealPath()), DIRECTORY_SEPARATOR);
return str_replace(
[DIRECTORY_SEPARATOR, ucfirst(basename(app()->path())).'\\'],
['\\', app()->getNamespace()],
ucfirst(Str::replaceLast('.php', '', $class))
);
}
/**
* Specify a callback to be used to guess class names.
*
* @param callable(SplFileInfo, string): string $callback
* @return void
*/
public static function guessClassNamesUsing(callable $callback)
{
static::$guessClassNamesUsingCallback = $callback;
}
}