Events
Laravel discovers the listeners of app/Listeners on its own. It guesses each class name from the file path under the project root, so it skips the listeners of a layer. Turn on OSDD's discovery to register them too.
Turning it on
Set osdd.events.discover to true in technical/osdd/config/osdd.php:
'events' => [
'discover' => true,
],
The value must be a real boolean: anything else throws when the application boots. Discovery is off by default.
What is discovered
Every class in a layer's Listeners folder, under its source directory (src/Listeners for a layer mapped to src/), sub-folders included. OSDD names each file through the layer's autoload.psr-4, then applies Laravel's own rules: each public handle*() or __invoke() method listens to the event class of its first parameter, union types included, and ShouldBeDiscovered is honoured.
<?php
namespace Functional\Billing\Listeners;
use Functional\Orders\Events\OrderPlaced;
class SendInvoice
{
public function handle(OrderPlaced $event): void
{
// ...
}
}
OrderPlaced::dispatch($order) now runs SendInvoice::handle(). Generate a listener in a layer with:
php artisan osdd:listener SendInvoice --event='\Functional\Orders\Events\OrderPlaced' --layer=functional/billing
--event=OrderPlaced names an event of the layer itself (Functional\Billing\Events\OrderPlaced); start the name with a backslash for an event of another layer.
A file that does not declare the class its path names is skipped.
functional/billing uses an event of functional/orders here: require functional/orders in functional/billing/composer.json, or osdd:check reports it.Listeners registered by hand
The discovered listeners are registered once the application has booted, after every provider's boot(). A listener already registered for the same event and the same method is skipped, so these run once:
Event::listen(OrderPlaced::class, SendInvoice::class);
Event::listen(OrderPlaced::class, SendInvoice::class.'@handle');
Event::listen(OrderPlaced::class, [SendInvoice::class, 'handle']);
in a provider's boot(), or in the $listen array of an event service provider. A listener registered later, in a booted() callback or at runtime, is not seen and runs twice. Remove the hand-written registrations when you turn discovery on.
In production
php artisan event:cache, which php artisan optimize runs, caches the layer listeners with the application's ones, so a request never scans the folders. They are stored under the Lomkit\Osdd\Events\LayerEventServiceProvider key of bootstrap/cache/events.php; OSDD registers that provider for you.
As with app/Listeners, a listener added after event:cache stays unregistered until event:cache runs again, and event:clear goes back to scanning. Check the result with:
php artisan event:list