VOOZH about

URL: https://deepwiki.com/hypervel/event/2.1-eventdispatcher

⇱ EventDispatcher | hypervel/event | DeepWiki


Loading...
Menu

EventDispatcher

The EventDispatcher class is the central orchestrator of the event system. It implements the PSR-14 EventDispatcherInterface and the Hypervel\Event\Contracts\Dispatcher interface, providing the primary entry point for dispatching events, registering listeners, and managing event flow control. This class coordinates interactions between events, listeners, and external systems including queues, database transactions, and broadcasting.

For information about how listeners are stored and retrieved, see ListenerProvider and ListenerData. For registering listeners through various methods, see Creating Event Listeners. For asynchronous processing details, see Asynchronous Event Processing.

Class Structure and Dependencies

The EventDispatcher class is located at src/EventDispatcher.php31 and manages several key collaborators through constructor injection and resolver patterns.

Core Dependencies

DependencyTypePurpose
ListenerProviderContractConstructorRetrieves listeners for events
LoggerInterfaceConstructor (optional)Debug logging of event handling
ContainerInterfaceConstructor (optional)Resolves listener instances
QueueFactoryContractResolverCreates queue connections for async dispatch
TransactionManagerResolverManages after-commit event callbacks
BroadcastFactoryContainerQueues events for broadcasting

Diagram: EventDispatcher Class Structure


Sources: src/EventDispatcher.php31-57 src/Contracts/Dispatcher.php12

Core Dispatch Flow

The dispatch() method at src/EventDispatcher.php62-88 is the primary entry point for firing events. It implements a sophisticated flow that handles deferred events, transaction-aware dispatching, and listener invocation.

Diagram: Dispatch Method Decision Flow


Sources: src/EventDispatcher.php62-88

Dispatch Parameters

ParameterTypeDefaultDescription
$eventobject|string-Event object or event name
$payloadmixed[]Additional data to pass to listeners
$haltboolfalseStop after first non-null response

Return value: The original event object or event name.

Dispatch Lifecycle Steps

  1. Deferred Event Check src/EventDispatcher.php64-73: If currently deferring events (via defer() method), the event is stored in context storage and returned immediately without invoking listeners.

  2. After-Commit Check src/EventDispatcher.php78-85: If the event implements ShouldDispatchAfterCommit and a TransactionManager is available, the entire dispatch is wrapped in a transaction callback and deferred until commit.

  3. Listener Invocation src/EventDispatcher.php87: If neither deferral condition applies, invokeListeners() is called immediately.

Sources: src/EventDispatcher.php62-88 src/Contracts/Dispatcher.php14-17

Listener Invocation Process

The invokeListeners() method at src/EventDispatcher.php157-174 handles the actual execution of listeners and integration with broadcasting.

Diagram: Listener Invocation Flow


Sources: src/EventDispatcher.php157-174

Broadcasting Integration

Before invoking listeners, the dispatcher checks if the event should be broadcast src/EventDispatcher.php159-161:

  • Events implementing ShouldBroadcast are automatically queued for broadcasting
  • Optional broadcastWhen() method on the event provides conditional broadcasting
  • Broadcasting is delegated to BroadcastFactory via src/EventDispatcher.php197-200

For detailed broadcasting information, see Event Broadcasting.

Listener Execution Loop

The dispatcher iterates through listeners obtained from getListeners() src/EventDispatcher.php163-171:

  1. Invoke: Each listener is called as a closure with $event and $payload arguments
  2. Log: Debug logging via dump() method src/EventDispatcher.php166
  3. Check Halt: Three conditions stop iteration:
    • $halt parameter is true
    • Listener returns false
    • Event implements StoppableEventInterface and propagation is stopped

Sources: src/EventDispatcher.php157-174 src/EventDispatcher.php179-200

Halt Behavior and Until Pattern

The until() method at src/EventDispatcher.php149-152 provides a convenience wrapper for halt behavior:


When $halt is true, the dispatcher stops after the first listener that:

  • Returns a non-null value
  • Returns false
  • Stops propagation (for StoppableEventInterface events)

This pattern is useful for:

  • Authorization checks (first listener to deny stops execution)
  • Validation chains (first failure halts processing)
  • Query resolution (first listener with result stops searching)

Sources: src/EventDispatcher.php149-152 src/Contracts/Dispatcher.php29-31

Listener Preparation and Resolution

The dispatcher converts raw listener registrations into executable closures through a multi-step preparation process.

Diagram: Listener Resolution Chain


Sources: src/EventDispatcher.php205-282

Listener Type Handling

The makeListener() method at src/EventDispatcher.php229-242 handles two listener types:

Class-based listeners src/EventDispatcher.php231-232:

  • String format: 'App\Listeners\MyListener' or 'App\Listeners\MyListener@handle'
  • Array format: ['App\Listeners\MyListener', 'handle']
  • Delegated to createClassListener()

Closure-based listeners src/EventDispatcher.php235-241:

  • Already callable, wrapped in a closure that unpacks payload arrays

Class Callable Resolution

The createClassCallable() method at src/EventDispatcher.php263-282 performs sophisticated listener resolution:

  1. Parse: Extract class and method using parseClassCallable() src/EventDispatcher.php265-267

  2. Queue Check: If listener implements ShouldQueue, return queued callable src/EventDispatcher.php273-275

  3. Instantiate: Resolve listener from container src/EventDispatcher.php277

  4. Commit Check: If listener should run after commits, wrap in transaction callback src/EventDispatcher.php279-281

  5. Direct: Return [$listener, $method] callable array

Sources: src/EventDispatcher.php229-282

Queue Integration

The dispatcher automatically queues listeners that implement ShouldQueue. This integration involves multiple layers of handler creation and job configuration.

Queue Handler Creation

When a listener should be queued, createQueuedHandlerCallable() at src/EventDispatcher.php413-424 returns a closure that:

  1. Clones arguments to prevent object mutation src/EventDispatcher.php416-418
  2. Checks shouldQueue() method if present src/EventDispatcher.php420
  3. Calls queueHandler() to dispatch the job src/EventDispatcher.php421

Queue Handler Dispatching

The queueHandler() method at src/EventDispatcher.php459-478 performs job dispatching:

Diagram: Queue Handler Configuration Flow


Sources: src/EventDispatcher.php459-478

Job Creation and Property Propagation

The createListenerAndJob() method at src/EventDispatcher.php483-492 creates a CallQueuedListener job wrapper, and propagateListenerOptions() at src/EventDispatcher.php497-522 copies listener properties to the job:

PropertySourcePurpose
afterCommitShouldQueueAfterCommit or propertyQueue after transaction commit
backoffMethod or propertyRetry backoff duration
maxExceptionsPropertyMax exceptions before fail
retryUntilMethodAbsolute retry deadline
shouldBeEncryptedShouldBeEncrypted interfaceEncrypt job payload
timeoutPropertyMax execution time
failOnTimeoutPropertyFail job on timeout
triesPropertyMax retry attempts
middlewareMethod or propertyJob middleware pipeline

Sources: src/EventDispatcher.php483-522

For detailed queue configuration, see Configuring Queued Events. For CallQueuedListener internals, see CallQueuedListener.

Transaction-Aware Dispatching

The dispatcher integrates with TransactionManager to support two transaction-aware patterns.

Event-Level After-Commit

Events implementing ShouldDispatchAfterCommit defer entire event dispatch until transaction commit src/EventDispatcher.php78-85:


This defers all listener invocations, broadcasting, and queue dispatching until the database transaction commits.

For detailed information, see Dispatching Events After Commit.

Listener-Level After-Commit

Individual listeners can defer execution via ShouldHandleEventsAfterCommit or the afterCommit property. The handlerShouldBeDispatchedAfterDatabaseTransactions() method at src/EventDispatcher.php287-292 checks:


If true, createCallbackForListenerRunningAfterCommits() at src/EventDispatcher.php429-440 wraps the listener in a transaction callback that executes after commit.

For detailed information, see Handling Events After Commit.

Sources: src/EventDispatcher.php78-85 src/EventDispatcher.php287-292 src/EventDispatcher.php429-440

Deferred Event Execution

The defer() method at src/EventDispatcher.php573-598 provides programmatic control over event deferral, batching events dispatched within a callback for later execution.

Defer Method Signature


Parameters:

  • $callback: Code to execute while deferring events
  • $events: Optional array of event classes to defer (null defers all)

Return: Result of the callback

Context State Management

The method manages three context keys src/EventDispatcher.php575-581:

Context KeyTypePurpose
__event.deferringboolWhether currently deferring
__event.deferred_eventsarrayQueue of [event, payload, halt] tuples
__event.events_to_defer?arrayWhitelist of event classes to defer

Defer Execution Flow

  1. Save State src/EventDispatcher.php575-577: Store current deferring state and deferred events
  2. Set Deferring src/EventDispatcher.php579-581: Enable deferring mode, clear queue, set whitelist
  3. Execute Callback src/EventDispatcher.php583-584: Run the provided callback
  4. Disable Deferring src/EventDispatcher.php586: Turn off deferring mode
  5. Dispatch Deferred src/EventDispatcher.php588-590: Execute all queued events
  6. Restore State src/EventDispatcher.php594-596: Restore previous context (in finally block)

The shouldDeferEvent() method at src/EventDispatcher.php603-617 determines if an event should be deferred:

  • Returns false if not in deferring mode
  • Returns true if no whitelist is set (defer all events)
  • Returns true if event class is in the whitelist

Sources: src/EventDispatcher.php573-617

For practical examples and use cases, see Deferred Events.

Push/Flush Pattern

The push/flush pattern provides an alternative deferral mechanism based on event names rather than execution context.

Push Method

The push() method at src/EventDispatcher.php305-310 registers an event for later dispatch:


This registers a temporary listener on the synthetic event {$event}_pushed that will dispatch the original event when triggered.

Flush Method

The flush() method at src/EventDispatcher.php315-318 triggers all pushed events:


This fires the synthetic event, which invokes all listeners registered via push().

Forget Pushed

The forgetPushed() method at src/EventDispatcher.php323-330 clears all pushed events by removing all listeners ending with '_pushed'.

Use cases:

  • Accumulating events during a request and flushing at response time
  • Batching related events for single dispatch
  • Testing scenarios requiring programmatic event control

Sources: src/EventDispatcher.php305-330

Listener Registration and Management

While the dispatcher delegates listener storage to ListenerProvider, it provides convenience methods for registration and query.

Listen Method

The listen() method at src/EventDispatcher.php116-144 registers listeners with special handling for closures and QueuedClosure:

Closure listeners src/EventDispatcher.php121-127:

  • Uses firstClosureParameterTypes() to extract event type from closure signature
  • Registers closure for each detected event type
  • Supports passing priority as second parameter when first parameter is closure

QueuedClosure listeners src/EventDispatcher.php129-135:

  • Extracts wrapped closure
  • Registers resolved callable

Standard listeners src/EventDispatcher.php141-143:

  • Registers listener for each event in array

Query Methods

MethodLocationPurpose
hasListeners()src/EventDispatcher.php343-346Check if event has any listeners
hasWildcardListeners()src/EventDispatcher.php351-354Check for wildcard listeners matching event
getListeners()src/EventDispatcher.php205-208Get all prepared listeners for event
getRawListeners()src/EventDispatcher.php551-554Get unprepared listeners from provider

Forget Methods

MethodLocationPurpose
forget()src/EventDispatcher.php335-338Remove all listeners for an event
forgetPushed()src/EventDispatcher.php323-330Remove all pushed event listeners

Sources: src/EventDispatcher.php116-144 src/EventDispatcher.php205-208 src/EventDispatcher.php323-346 src/EventDispatcher.php351-354 src/EventDispatcher.php551-554

Event Subscriber Support

The subscribe() method at src/EventDispatcher.php527-546 registers event subscriber classes that define multiple event-to-listener mappings.

Subscriber Registration Flow

  1. Resolve Subscriber src/EventDispatcher.php529: If subscriber is a string, resolve from container
  2. Get Event Map src/EventDispatcher.php531: Call $subscriber->subscribe($this)
  3. Register Mappings src/EventDispatcher.php533-545: If result is an array, iterate and register

Event Map Format

Subscribers can return an array mapping event names to listeners:


The dispatcher handles two listener formats src/EventDispatcher.php536-542:

  • String method names: Registered as [SubscriberClass, 'method']
  • Other callables: Registered directly

Sources: src/EventDispatcher.php527-568

For practical subscriber usage, see Event Subscribers.

Resolver Configuration

The dispatcher uses resolver callables for lazy dependency resolution, avoiding hard dependencies on optional systems.

Queue Resolver

Set via setQueueResolver() at src/EventDispatcher.php369-374 resolved via resolveQueue() at src/EventDispatcher.php359-362

Purpose: Provides access to QueueFactoryContract for dispatching queued listeners.

Transaction Manager Resolver

Set via setTransactionManagerResolver() at src/EventDispatcher.php387-392 resolved via resolveTransactionManager() at src/EventDispatcher.php379-382

Purpose: Provides access to TransactionManager for after-commit behavior. Returns null if unavailable, allowing graceful degradation.

Sources: src/EventDispatcher.php359-392

For factory configuration, see Factory System and Dependency Injection.

Debug Logging

The dump() method at src/EventDispatcher.php93-111 provides debug logging of event-listener pairs:


Logging format: "Event {EventClass} handled by {ListenerClass} listener."

Listener name extraction:

  • Array listeners: Use class name or string
  • String listeners: Use string directly
  • Object listeners: Use class name
  • Unknown types: Use '[ERROR TYPE]'

Logging only occurs if a LoggerInterface was provided to the constructor.

Sources: src/EventDispatcher.php93-111

Refresh this wiki

On this page