master

laravel/framework

Last updated at: 29/12/2023 09:23

EventServiceProvider.php

TLDR

The EventServiceProvider.php file is a class that extends the ServiceProvider class. It provides methods for registering and booting the application's event listeners, as well as methods for discovering and configuring events and listeners.

Methods

register

This method is used to register the application's event listeners. It loops through the events and their listeners defined in the listen array and adds them to the global event dispatcher. It also subscribes any subscribers defined in the subscribe array and registers any model observers defined in the observers array.

boot

This method is empty and does not perform any operations. It is meant to be overridden in child classes if needed.

listens

This method returns the listen array, which contains the event handler mappings for the application.

getEvents

This method returns the discovered events and listeners for the application. It checks if the events are cached and returns them from the cache if they are, otherwise it merges the discovered events from the discoveredEvents method with the events defined in the listen array.

discoveredEvents

This method returns the discovered events for the application by calling the discoverEvents method if event discovery is enabled, otherwise it returns an empty array.

shouldDiscoverEvents

This method determines if events and listeners should be automatically discovered by comparing the current class with the EventServiceProvider class.

discoverEvents

This method discovers the events and listeners for the application by iterating over the listener directories and calling the DiscoverEvents::within method to retrieve the events and listeners within each directory. The discovered events are then merged together into a single array.

discoverEventsWithin

This method returns the listener directories that should be used to discover events. In this case, it returns the Listeners directory within the application's path.

eventDiscoveryBasePath

This method returns the base path to be used during event discovery. It returns the application base path.

configureEmailVerification

This method configures the proper event listeners for email verification. If the Registered event is not already defined in the listen array or if the SendEmailVerificationNotification listener is not already associated with the Registered event, it adds the SendEmailVerificationNotification listener to the Registered event.

<?php

namespace Illuminate\Foundation\Support\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Events\DiscoverEvents;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event handler mappings for the application.
     *
     * @var array<string, array<int, string>>
     */
    protected $listen = [];

    /**
     * The subscribers to register.
     *
     * @var array
     */
    protected $subscribe = [];

    /**
     * The model observers to register.
     *
     * @var array<string, string|object|array<int, string|object>>
     */
    protected $observers = [];

    /**
     * Register the application's event listeners.
     *
     * @return void
     */
    public function register()
    {
        $this->booting(function () {
            $events = $this->getEvents();

            foreach ($events as $event => $listeners) {
                foreach (array_unique($listeners, SORT_REGULAR) as $listener) {
                    Event::listen($event, $listener);
                }
            }

            foreach ($this->subscribe as $subscriber) {
                Event::subscribe($subscriber);
            }

            foreach ($this->observers as $model => $observers) {
                $model::observe($observers);
            }
        });

        $this->booted(function () {
            $this->configureEmailVerification();
        });
    }

    /**
     * Boot any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Get the events and handlers.
     *
     * @return array
     */
    public function listens()
    {
        return $this->listen;
    }

    /**
     * Get the discovered events and listeners for the application.
     *
     * @return array
     */
    public function getEvents()
    {
        if ($this->app->eventsAreCached()) {
            $cache = require $this->app->getCachedEventsPath();

            return $cache[get_class($this)] ?? [];
        } else {
            return array_merge_recursive(
                $this->discoveredEvents(),
                $this->listens()
            );
        }
    }

    /**
     * Get the discovered events for the application.
     *
     * @return array
     */
    protected function discoveredEvents()
    {
        return $this->shouldDiscoverEvents()
                    ? $this->discoverEvents()
                    : [];
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     *
     * @return bool
     */
    public function shouldDiscoverEvents()
    {
        return get_class($this) === __CLASS__;
    }

    /**
     * Discover the events and listeners for the application.
     *
     * @return array
     */
    public function discoverEvents()
    {
        return collect($this->discoverEventsWithin())
                    ->reject(function ($directory) {
                        return ! is_dir($directory);
                    })
                    ->reduce(function ($discovered, $directory) {
                        return array_merge_recursive(
                            $discovered,
                            DiscoverEvents::within($directory, $this->eventDiscoveryBasePath())
                        );
                    }, []);
    }

    /**
     * Get the listener directories that should be used to discover events.
     *
     * @return array
     */
    protected function discoverEventsWithin()
    {
        return [
            $this->app->path('Listeners'),
        ];
    }

    /**
     * Get the base path to be used during event discovery.
     *
     * @return string
     */
    protected function eventDiscoveryBasePath()
    {
        return base_path();
    }

    /**
     * Configure the proper event listeners for email verification.
     *
     * @return void
     */
    protected function configureEmailVerification()
    {
        if (! isset($this->listen[Registered::class]) ||
            ! in_array(SendEmailVerificationNotification::class, Arr::wrap($this->listen[Registered::class]))) {
            Event::listen(Registered::class, SendEmailVerificationNotification::class);
        }
    }
}