kelvinmo/f3-event-dispatcher

A PSR-14 compliant event dispatcher for the Fat-Free Framework

v0.1.4 2023-07-22 03:32 UTC

This package is auto-updated.

Last update: 2024-03-30 04:01:11 UTC


README

This is a simple PSR-14 compliant event dispatcher and listener provider library for the Fat-Free Framework.

Latest Stable Version build

Requirements

  • PHP 7.2 or later
  • Fat-Free Framework 3.5 or later

Installation

You can install via Composer.

composer require kelvinmo/f3-event-dispatcher

Usage

Listener Provider

The listener provider is implemented by the \Listeners class. Listeners is a subclass of Fat-Free's \Prefab class.

$listeners = \Listeners::instance();

To add a listener, call the on() method. The name of the event is specified in the first parameter and the listener in the second parameter.

As required by PSR-14, if the name of the event is the name of a class, then the listener will also be triggered for all subclasses of that event class.

The listener can be a PHP callable, or a string that can be resolved by Fat-Free's call() method

// Object method
$listeners->on(FooEvent::class, 'Bar->listener');

// Static method
$listeners->on(FooEvent::class, 'Bar::listener');

// PHP callable
$listeners->on(FooEvent::class, [ $object, 'listener' ]);

// Closure
$listeners->on(FooEvent::class, function($event) {
    // listener
});

The on() method also takes a third, optional parameter, specifying the priority which the listeners should be called. Listeners are called from the highest priority to the lowest.

// Baz->listener is called first, then Bar->listener
$listeners->on(FooEvent::class, 'Bar->listener', 10);
$listeners->on(FooEvent::class, 'Baz->listener', 20);

You can use Listeners with any PSR-14-compliant event dispatcher.

Generic Events

Sometimes it is too cumbersome to create a new event class for every single event. You can use generic events to group a set of related events into a single class.

A generic event implements GenericEventInterface and provides the name of the event through the getEventName() method.

class BarEvent implements GenericEventInterface {
    private $eventName;

    public function __construct($eventName) {
        $this->eventName = $eventName;
    }

    public function getEventName() {
        return $this->eventName;
    }
}

$listeners->on('foo', 'Baz->listener');
$event = new BarEvent('foo');

Adding Listeners via Reflection

You can also add listeners using reflection by the map() method. This method takes a name or an instantiated object of a class. A listener will be added based on a method of this class if:

  1. It is a public method (whether or not it is also static)
  2. The name of the method starts with on
  3. The method takes exactly one parameter, and the parameter is type-hinted with an event class.

The name of the event the method will listen to depends on the name of the method. If the name of the method is the same as the short name of the type hint of the parameter, then the name of the event is the fully qualified name of the parameter type. Otherwise, the name of the event is the method name converted to snake case, in which case the event type must be a generic event (i.e. implements GenericEventInterface).

class TestListener {
    // Will be mapped to FooEvent (with namespace)
    public function onFooEvent(FooEvent $event) {
    }

    // Will be mapped to custom_event
    // (BarEvent must implement GenericEventInterface)
    public function onCustomEvent(BarEvent $event) {
    }
}

$listeners = \Listeners::instance();
$listeners->map(TestListener::class);

Event Dispatcher

The event dispatcher is implemented by the \Events class. Events is a subclass of Fat-Free's \Prefab class.

$dispatcher = \Events::instance();

By default, Events uses the Listeners listener provider included in this library. To use a different listener provider, pass the provider as an argument in the constructor.

use League\Event\PrioritizedListenerRegistry;

$listenerProvider = new PrioritizedListenerRegistry();
$dispatcher = \Events::instance($listenerProvider);

To use the event dispatcher, call the standard PSR-14 dispatch() method:

$dispatcher->dispatch(new FooEvent());

Licence

GPL 3 or later