EventScanner
in package
The `EventScanner` is a utility for scanning a class to see if it has any event-listeners. It may check for common interfaces and conventions. Example:
$map = EventScanner::findListeners($someObject);
$dispatcher->addListenerMap($someObject, $map);
Table of Contents
Properties
- $listenerMaps : array<string|int, mixed>
- In-memory cache of the listener-maps found on various classes.
Methods
- findListeners() : array<string|int, mixed>
- Scan an object or class for event listeners.
- findFunctionListeners() : array<string|int, mixed>
- mergeListenerMap() : array<string|int, mixed>
- normalizeListenerMap() : array<string|int, mixed>
- Convert the listeners to a standard flavor.
Properties
$listenerMaps
In-memory cache of the listener-maps found on various classes.
private
static array<string|int, mixed>
$listenerMaps
= []
This cache is a little unusual -- it is geared toward improving unit-tests. Bear in mind:
- The
EventScanner
is fundamentally scanning class-structure. - Within a given PHP process, the class-structure cannot change. Therefore, the cached view in
static::$listenerMaps
cannot be stale. - There are three kinds of PHP processes:
- System-flushes -- During this operation, we rebuild the
Container
. This may do some scanning, and the results will be recorded inContainer
. - Ordinary page-loads -- We use the
Container
cache. It shouldn't need any more scans. - Headless unit-tests -- For these, we must frequently tear-down and rebuild a fresh
Container
, often with varying decisions about which extensions/services/classes to activate. The container-cache does not operate.
- System-flushes -- During this operation, we rebuild the
Here's how $listenerMaps
plays out in each:
- The
$listenerMaps
is not needed or used. - The
$listenerMaps
(andEventScanner
generally) is not needed or used. - The
$listenerMaps
is used frequently, preventing redundant scanning.
A more common approach would be to use Civi::$statics
or Civi::cache()
. These would be inappropriate because we want the data to be
preserved across multiple test-runs -- and because the underlying data (PHP class-structure) does not change within a unit-test.
Ex: ['api_v3_SyntaxConformanceTest' => [...listener-names...]]
Methods
findListeners()
Scan an object or class for event listeners.
public
static findListeners(string|object $target[, string|null $self = NULL ]) : array<string|int, mixed>
Note: This requires scanning. Consequently, it should not be run in bulk on a regular (runtime) basis. Instead, store
the listener-maps in a cache (e.g. Container
).
Parameters
- $target : string|object
-
The object/class which will receive the notifications. Use a string (class-name) if the listeners are static methods. Use an object-instance if the listeners are regular methods.
- $self : string|null = NULL
-
If the target $class is focused on a specific entity/form/etc, use the
$self
parameter to specify it. This will activate support forself_{$event}
methods. Ex: if '$self' is 'Contact', then 'function self_hook_civicrm_pre()' maps to 'on_hook_civicrm_pre::Contact'.
Return values
array<string|int, mixed> —List of events/listeners. Format is compatible with 'getSubscribedEvents()'. Ex: ['some.event' => [['firstFunc'], ['secondFunc']]
findFunctionListeners()
protected
static findFunctionListeners(string $class[, string|null $self = NULL ]) : array<string|int, mixed>
Parameters
- $class : string
- $self : string|null = NULL
-
If the target $class is focused on a specific entity/form/etc, use the
$self
parameter to specify it. This will activate support forself_{$event}
methods. Ex: if '$self' is 'Contact', then 'function self_hook_civicrm_pre()' maps to 'hook_civicrm_pre::Contact'.
Return values
array<string|int, mixed>mergeListenerMap()
protected
static mergeListenerMap(array<string|int, mixed> $left, array<string|int, mixed> $right) : array<string|int, mixed>
Parameters
- $left : array<string|int, mixed>
- $right : array<string|int, mixed>
Return values
array<string|int, mixed>normalizeListenerMap()
Convert the listeners to a standard flavor.
protected
static normalizeListenerMap(iterable<string|int, mixed> $listenerMap) : array<string|int, mixed>
Parameters
- $listenerMap : iterable<string|int, mixed>
-
List of events/listeners. Listeners may be given in singular or plural form. Ex: ['some.event' => 'oneListener'] Ex: ['some.event' => ['oneListener', 100]] Ex: ['some.event' => [['firstListener', 100], ['secondListener']]]
Return values
array<string|int, mixed> —List of events/listeners. All listeners are described in plural form. Ex: ['some.event' => [['firstListener', 100], ['secondListener']]]