Guides

Events

Register the listeners of every layer without Event::listen(), like the ones of app/Listeners.

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:

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.

functional/billing/src/Listeners/SendInvoice.php
<?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