From 1eed73851aacf820ef9d2afc5781412a0d7acdb2 Mon Sep 17 00:00:00 2001 From: bastien-phi Date: Fri, 11 Aug 2023 16:33:16 +0200 Subject: [PATCH] Add ability to customize class resolution in event discovery (#48031) --- .../Foundation/Events/DiscoverEvents.php | 22 ++++++++++++ .../Foundation/DiscoverEventsTest.php | 34 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/Illuminate/Foundation/Events/DiscoverEvents.php b/src/Illuminate/Foundation/Events/DiscoverEvents.php index 1e26f55679d4..b285759d2188 100644 --- a/src/Illuminate/Foundation/Events/DiscoverEvents.php +++ b/src/Illuminate/Foundation/Events/DiscoverEvents.php @@ -12,6 +12,13 @@ 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. * @@ -87,6 +94,10 @@ protected static function getListenerEvents($listeners, $basePath) */ 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( @@ -95,4 +106,15 @@ protected static function classFromFile(SplFileInfo $file, $basePath) 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; + } } diff --git a/tests/Integration/Foundation/DiscoverEventsTest.php b/tests/Integration/Foundation/DiscoverEventsTest.php index 2c5a5926c51c..d07a7ddd5e93 100644 --- a/tests/Integration/Foundation/DiscoverEventsTest.php +++ b/tests/Integration/Foundation/DiscoverEventsTest.php @@ -3,6 +3,7 @@ namespace Illuminate\Tests\Integration\Foundation; use Illuminate\Foundation\Events\DiscoverEvents; +use Illuminate\Support\Str; use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\Events\EventOne; use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\Events\EventTwo; use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\Listeners\AbstractListener; @@ -10,9 +11,17 @@ use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\Listeners\ListenerInterface; use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\UnionListeners\UnionListener; use Orchestra\Testbench\TestCase; +use SplFileInfo; class DiscoverEventsTest extends TestCase { + protected function tearDown(): void + { + DiscoverEvents::$guessClassNamesUsingCallback = null; + + parent::tearDown(); + } + public function testEventsCanBeDiscovered() { class_alias(Listener::class, 'Tests\Integration\Foundation\Fixtures\EventDiscovery\Listeners\Listener'); @@ -47,4 +56,29 @@ class_alias(UnionListener::class, 'Tests\Integration\Foundation\Fixtures\EventDi ], ], $events); } + + public function testEventsCanBeDiscoveredUsingCustomClassNameGuessing() + { + DiscoverEvents::guessClassNamesUsing(function (SplFileInfo $file, $basePath) { + return Str::of($file->getRealPath()) + ->after($basePath.DIRECTORY_SEPARATOR) + ->before('.php') + ->replace(DIRECTORY_SEPARATOR, '\\') + ->ucfirst() + ->prepend('Illuminate\\') + ->toString(); + }); + + $events = DiscoverEvents::within(__DIR__.'/Fixtures/EventDiscovery/Listeners', getcwd()); + + $this->assertEquals([ + EventOne::class => [ + Listener::class.'@handle', + Listener::class.'@handleEventOne', + ], + EventTwo::class => [ + Listener::class.'@handleEventTwo', + ], + ], $events); + } }