Download the PHP package olvlvl/event-dispatcher without Composer
On this page you can find all versions of the php package olvlvl/event-dispatcher. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download olvlvl/event-dispatcher
More information about olvlvl/event-dispatcher
Files in olvlvl/event-dispatcher
Package event-dispatcher
Short Description PSR-14 Event Dispatcher implementation
License BSD-3-Clause
Informations about the package event-dispatcher
olvlvl/event-dispatcher
olvlvl/event-dispatcher
provides an implementation of psr/event-dispatcher, which establishes a common mechanism
for event-based extension and collaboration.
Package highlights
- Supports Event inheritance, including interfaces.
- Supports stoppable Events.
- Provides a collection of composable Event Dispatchers and Listener Providers.
- Introduces Mutable Listener Providers.
- Provides a compiler pass for symfony/dependency-injection, with priorities and relatives.
Installation
Event Dispatcher
An Event Dispatcher is a service object that is given an Event object by an Emitter. The Dispatcher is responsible for ensuring that the Event is passed to all relevant Listeners, but MUST defer determining the responsible listeners to a Listener Provider.
Basic Event Dispatcher
BasicEventDispatcher
is a basic implementation of an Event Dispatcher, that complies
with the requirements for Dispatchers.
Buffered Event Dispatcher
In some situations, it can be desired to defer the dispatching of events. For instance, an application that's presenting an API to create recipes, and needs to index created recipes and run additional time-consuming calculations, would want to defer dispatching the events, to reply as soon as possible to the user.
BufferedEventDispatcher
decorates an Event Dispatcher and buffers events that can be dispatched at a later time. The
user can provide a discriminator that decides whether an event should be buffered or dispatched immediately.
Careful using this type of Dispatcher! Because event dispatching is delayed, it will cause issues for users that expect Events to be modified.
Note: In accordance with Dispatchers requirements, stopped Events are discarded and not be buffered.
Listener Provider
A Listener Provider is responsible for determining what Listeners are relevant to and should be called for a given
Event. olvlvl/event-dispatcher
provides a few Listener Provider implementations, that comply with
the requirements and recommendations for Listener Providers.
Listener Provider with a map
ListenerProviderWithMap
is a Listener Provider that uses an array of Event/Listeners pairs.
Listener Provider with a container
ListenerProviderWithContainer
is a Listener Provider that uses an array of Event/service id pairs and retrieves
Listeners from a PSR container.
Note: olvlvl/event-dispatcher
provides symfony/dependency-injection that
is very handy to collect Event Listeners and build Listener Providers.
Mutable Listener Provider
MutableListenerProvider
is a mutable Listener Provider, that is, listeners can be added and removed. To this effect,
the Provider has no constructor arguments so that any Listener it contains can also be removed.
The Listener Provider implements MutableListenerProviderInterface
, which extends ListenerProviderInterface
. The
interface can be used to distinguish a mutable Listener Provider from a non-mutable one.
A Listener for an Event can be added to the end of the list with the method appendListenerForEvent()
, or to the
beginning of the list with the method prependListenerForEvent()
. Both methods return a callable that can be used to
remove the Listener.
Note: A LogicException
is thrown if a Listener is added twice for an Event type. The call is not failing silently
because a Listener can have very different and unpredictable outcomes whether it was prepended or appended.
The following example demonstrates how a Listener can be appended for an Event to a mutable Listener Provider. In the example, the "remove" callable is used by the Listener to remove itself once it has been called. This is how one would set up a "once" Listener. Of course, this is just an example of application.
Listener Provider Chain
With ListenerProviderChain
, multiple Listener Providers can be combined to act like one. They are called in succession
to provide Listeners for an Event.
The chain is mutable, Listener Providers can be added to the end of the chain using the appendListenerProviders()
method, or to the beginning of the chain using the prependListenerProviders()
method.
Note: Since ListenerProviderChain
is a Provider Listener like any other, creating a chain of chains is a
possibility.
The following example demonstrates how to create a chain of Listener Providers, and modify that chain by appending and prepending others.
Listener Provider Filter
ListenerProviderFilter
decorates a Listener Provider to filter Listeners according to a user specified discriminator.
The filter can be used to implement some form of access control so that certain Listeners will only be called if the
current user has a certain permission.
The following example demonstrates how the filter can be used to discard $listener_1
for SampleEventA
and $listener_2
for SampleEventC
.
Compiler pass for symfony/dependency-injection
The package provides a compiler pass for symfony/dependency-injection that builds one or many Listener Providers automatically.
Basically, the compiler pass searches for the tagged services, collect their Event Listeners, creates a mapping with their events, and overwrite a few attributes to complete the definition of the service.
If Listeners are spread over multiple files, or if it's not practical to keep them ordered, priorities and relatives can be specified for each Event/Listener pairs, and Listeners will be sorted accordingly.
Adding the compiler pass
By default, the tag used to identify the Listener Providers to build is listener_provider
, but it can be configured:
Defining the services
The following example uses the PSR interface as service identifier, but a name such as my_listener_provider
can be
used just the same, as we'll see later when building multiple Listener Providers. Also, it is not required to specify
the synthetic
attribute, but it is recommended to indicate to fellow developers that the service definition is a stub.
Note: To complete the service definition, the compiler pass overwrites the attributes synthetic
, class
,
and arguments
, but leaves intact any other attribute.
By default, the tag for the Listener services is event_listener
but it can be configured, which is required when
building multiple Listener Providers.
The following example demonstrates own Listener services are attached to a Listener Provider. They are tagged
with event_listener
, which is the default tag. A listener can listen to multiple events, as is demonstrated
by ListenerC
.
Building multiple Listener Providers
It is possible to build multiple Listener Providers, you just need to specify which Listener tag to use for each of them:
Specify priorities
The compiler pass can use priorities to sort listeners. Valid priorities are integers, positive or negative, or one of
the special values first
and last
. With these special values, the Listener is placed first or last, no matter the
other priorities. Multiple Listeners can use these special values, in which case, the effect stacks. In the case of
equal priorities, the original order is preserved.
Note: If not specified, the priority defaults to 0, unless the attributes before
or after
are defined.
The following example demonstrates how the priority
attribute can be used to specify the order of Listeners. The final
order will be as follows:
- For
SampleEventA
:listener_e
,listener_d
,listener_c
,listener_a
,listener_b
. - For
SampleEventB
:listener_d
,listener_b
.
Specify relatives
The compiler pass can sort Listeners relatively to others. The before
attribute allows a Listener to be placed before
another Listener, while the after
attribute allows a Listener to be placed after another Listener.
Note: Only one of priority
, before
, or after
can be used at once.
The following example demonstrates how priorities and relatives can be used to order Listeners. The final order will be
as follows: listener_e
, listener_d
, listener_c
, listener_b
, listener_a
.
Continuous Integration
The project is continuously tested by GitHub actions.
Code of Conduct
This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you are expected to uphold this code.
Contributing
Please see CONTRIBUTING for details.
License
olvlvl/event-dispatcher is released under the BSD-3-Clause.