Skip to content

Commit bcfa7c3

Browse files
authored
feat: support iterables for event discovery paths (#55699)
1 parent ea17178 commit bcfa7c3

File tree

4 files changed

+56
-25
lines changed

4 files changed

+56
-25
lines changed

src/Illuminate/Foundation/Configuration/ApplicationBuilder.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ public function withProviders(array $providers = [], bool $withBootstrapProvider
9292
/**
9393
* Register the core event service provider for the application.
9494
*
95-
* @param array|bool $discover
95+
* @param iterable<int, string>|bool $discover
9696
* @return $this
9797
*/
98-
public function withEvents(array|bool $discover = [])
98+
public function withEvents(iterable|bool $discover = true)
9999
{
100-
if (is_array($discover) && count($discover) > 0) {
100+
if (is_iterable($discover)) {
101101
AppEventServiceProvider::setEventDiscoveryPaths($discover);
102102
}
103103

src/Illuminate/Foundation/Events/DiscoverEvents.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Illuminate\Foundation\Events;
44

5+
use Illuminate\Support\Arr;
56
use Illuminate\Support\Collection;
67
use Illuminate\Support\Reflector;
78
use Illuminate\Support\Str;
@@ -16,19 +17,23 @@ class DiscoverEvents
1617
/**
1718
* The callback to be used to guess class names.
1819
*
19-
* @var callable(SplFileInfo, string): string|null
20+
* @var (callable(SplFileInfo, string): class-string)|null
2021
*/
2122
public static $guessClassNamesUsingCallback;
2223

2324
/**
2425
* Get all of the events and listeners by searching the given listener directory.
2526
*
26-
* @param string $listenerPath
27+
* @param array<int, string>|string $listenerPath
2728
* @param string $basePath
2829
* @return array
2930
*/
3031
public static function within($listenerPath, $basePath)
3132
{
33+
if (Arr::wrap($listenerPath) === []) {
34+
return [];
35+
}
36+
3237
$listeners = new Collection(static::getListenerEvents(
3338
Finder::create()->files()->in($listenerPath), $basePath
3439
));
@@ -51,7 +56,7 @@ public static function within($listenerPath, $basePath)
5156
/**
5257
* Get all of the listeners and their corresponding events.
5358
*
54-
* @param iterable $listeners
59+
* @param iterable<string, SplFileInfo> $listeners
5560
* @param string $basePath
5661
* @return array
5762
*/
@@ -91,7 +96,7 @@ protected static function getListenerEvents($listeners, $basePath)
9196
*
9297
* @param \SplFileInfo $file
9398
* @param string $basePath
94-
* @return string
99+
* @return class-string
95100
*/
96101
protected static function classFromFile(SplFileInfo $file, $basePath)
97102
{
@@ -111,7 +116,7 @@ protected static function classFromFile(SplFileInfo $file, $basePath)
111116
/**
112117
* Specify a callback to be used to guess class names.
113118
*
114-
* @param callable(SplFileInfo, string): string $callback
119+
* @param callable(SplFileInfo, string): class-string $callback
115120
* @return void
116121
*/
117122
public static function guessClassNamesUsing(callable $callback)

src/Illuminate/Foundation/Support/Providers/EventServiceProvider.php

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
77
use Illuminate\Foundation\Events\DiscoverEvents;
88
use Illuminate\Support\Arr;
9-
use Illuminate\Support\Collection;
109
use Illuminate\Support\Facades\Event;
10+
use Illuminate\Support\LazyCollection;
1111
use Illuminate\Support\ServiceProvider;
1212

1313
class EventServiceProvider extends ServiceProvider
@@ -43,7 +43,7 @@ class EventServiceProvider extends ServiceProvider
4343
/**
4444
* The configured event discovery paths.
4545
*
46-
* @var array|null
46+
* @var iterable<int, string>|null
4747
*/
4848
protected static $eventDiscoveryPaths;
4949

@@ -145,25 +145,23 @@ public function shouldDiscoverEvents()
145145
*/
146146
public function discoverEvents()
147147
{
148-
return (new Collection($this->discoverEventsWithin()))
148+
return (new LazyCollection($this->discoverEventsWithin()))
149149
->flatMap(function ($directory) {
150150
return glob($directory, GLOB_ONLYDIR);
151151
})
152152
->reject(function ($directory) {
153153
return ! is_dir($directory);
154154
})
155-
->reduce(function ($discovered, $directory) {
156-
return array_merge_recursive(
157-
$discovered,
158-
DiscoverEvents::within($directory, $this->eventDiscoveryBasePath())
159-
);
160-
}, []);
155+
->pipe(fn ($directories) => DiscoverEvents::within(
156+
$directories->all(),
157+
$this->eventDiscoveryBasePath(),
158+
));
161159
}
162160

163161
/**
164162
* Get the listener directories that should be used to discover events.
165163
*
166-
* @return array
164+
* @return iterable<int, string>
167165
*/
168166
protected function discoverEventsWithin()
169167
{
@@ -175,23 +173,24 @@ protected function discoverEventsWithin()
175173
/**
176174
* Add the given event discovery paths to the application's event discovery paths.
177175
*
178-
* @param string|array $paths
176+
* @param string|iterable<int, string> $paths
179177
* @return void
180178
*/
181-
public static function addEventDiscoveryPaths(array|string $paths)
179+
public static function addEventDiscoveryPaths(iterable|string $paths)
182180
{
183-
static::$eventDiscoveryPaths = array_values(array_unique(
184-
array_merge(static::$eventDiscoveryPaths, Arr::wrap($paths))
185-
));
181+
static::$eventDiscoveryPaths = (new LazyCollection(static::$eventDiscoveryPaths))
182+
->merge(is_string($paths) ? [$paths] : $paths)
183+
->unique()
184+
->values();
186185
}
187186

188187
/**
189188
* Set the globally configured event discovery paths.
190189
*
191-
* @param array $paths
190+
* @param iterable<int, string> $paths
192191
* @return void
193192
*/
194-
public static function setEventDiscoveryPaths(array $paths)
193+
public static function setEventDiscoveryPaths(iterable $paths)
195194
{
196195
static::$eventDiscoveryPaths = $paths;
197196
}

tests/Integration/Foundation/DiscoverEventsTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,33 @@ class_alias(UnionListener::class, 'Tests\Integration\Foundation\Fixtures\EventDi
5757
], $events);
5858
}
5959

60+
public function testMultipleDirectoriesCanBeDiscovered(): void
61+
{
62+
$events = DiscoverEvents::within([
63+
__DIR__.'/Fixtures/EventDiscovery/Listeners',
64+
__DIR__.'/Fixtures/EventDiscovery/UnionListeners',
65+
], getcwd());
66+
67+
$this->assertEquals([
68+
EventOne::class => [
69+
Listener::class.'@handle',
70+
Listener::class.'@handleEventOne',
71+
UnionListener::class.'@handle',
72+
],
73+
EventTwo::class => [
74+
Listener::class.'@handleEventTwo',
75+
UnionListener::class.'@handle',
76+
],
77+
], $events);
78+
}
79+
80+
public function testNoExceptionForEmptyDirectories(): void
81+
{
82+
$events = DiscoverEvents::within([], getcwd());
83+
84+
$this->assertEquals([], $events);
85+
}
86+
6087
public function testEventsCanBeDiscoveredUsingCustomClassNameGuessing()
6188
{
6289
DiscoverEvents::guessClassNamesUsing(function (SplFileInfo $file, $basePath) {

0 commit comments

Comments
 (0)