Skip to content

Commit

Permalink
Add ability to customize class resolution in event discovery (#48031)
Browse files Browse the repository at this point in the history
  • Loading branch information
bastien-phi authored Aug 11, 2023
1 parent 7ee6d0d commit 1eed738
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/Illuminate/Foundation/Events/DiscoverEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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(
Expand All @@ -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;
}
}
34 changes: 34 additions & 0 deletions tests/Integration/Foundation/DiscoverEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
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;
use Illuminate\Tests\Integration\Foundation\Fixtures\EventDiscovery\Listeners\Listener;
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');
Expand Down Expand Up @@ -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);
}
}

0 comments on commit 1eed738

Please sign in to comment.