Events
Contents
Overview
Elgg has an event system that can be used to replace or extend core functionality.
Plugins influence the system by creating handlers (callables such as functions and methods) and registering them to handle the events.
When an event is triggered, a set of handlers is executed in order of priority. Each handler is passed arguments and has a chance to influence the process. After execution, the „trigger“ function returns a value based on the behavior of the handlers.
Siehe auch
Elgg Events
Elgg Events are triggered when an Elgg object is created, updated, or deleted; and at important milestones while the Elgg framework is loading. Examples: a blog post being created or a user logging in.
These events are mostly used to notify the rest of the system that something has happened.
There are also events that are used to influence output, configuration or behaviour of the system.
Each Elgg event has a name and a type (system, user, object, relationship name, annotation, group) describing the type of object passed to the handlers.
Before and After Events
Some events are split into „before“ and „after“. This avoids confusion around the state of the system while in flux. E.g. Is the user logged in during the [login, user] event?
Before Events have names ending in „:before“ and are triggered before
something happens. Handlers can cancel the event by returning false
.
When false
is returned by a handler, following handlers will not be called.
After Events, with names ending in „:after“, are triggered after something happened. Handlers cannot cancel these events; all handlers will always be called.
Where before and after events are available, developers are encouraged to transition to them, though older events will be supported for backwards compatibility.
Elgg Event Handlers
Elgg event handlers are callables:
<?php
/**
* @param \Elgg\Event $event The event object
*
* @return bool if false, the handler is requesting to cancel the event
*/
function event_handler(\Elgg\Event $event) {
...
}
In event_handler
, the Event
object has various methods for getting the name, object type,
and object of the event. See the Elgg\Event
class for details.
Register to handle an Elgg Event
Register your handler to an event using elgg_register_event_handler
:
<?php
elgg_register_event_handler($event, $type, $handler, $priority);
Parameters:
$event The event name.
$type The event type (e.g. „user“ or „object“) or ‚all‘ for all types on which the event is fired.
$handler The callback of the handler function.
$priority The priority - 0 is first and the default is 500.
Example:
<?php
// Register the function myPlugin_handle_create_object() to handle the
// create object event with priority 400.
elgg_register_event_handler('create:after', 'object', 'myPlugin_handle_create_object', 400);
Warnung
If you handle the „update“ event on an object, avoid calling save()
in your event handler. For one it’s
probably not necessary as the object is saved after the event completes, but also because save()
calls
another „update“ event and makes $object->getOriginalAttributes()
no longer available.
Invokable classes as handlers
You may use a class with an __invoke()
method as a handler. Just register the class name and it will be instantiated (with no arguments)
for the lifetime of the event.
<?php
namespace MyPlugin;
class UpdateObjectHandler {
public function __invoke(\Elgg\Event $event) {
}
}
// in init, system
elgg_register_event_handler('update', 'object', MyPlugin\UpdateObjectHandler::class);
Trigger an Elgg Event
You can trigger a custom Elgg event using elgg_trigger_event
:
<?php
if (elgg_trigger_event($event, $object_type, $object)) {
// Proceed with doing something.
} else {
// Event was cancelled. Roll back any progress made before the event.
}
For events with ambiguous states, like logging in a user, you should use Before and After Events
by calling elgg_trigger_before_event
or elgg_trigger_after_event
.
This makes it clear for the event handler what state to expect and which events can be cancelled.
<?php
// handlers for the user, login:before event know the user isn't logged in yet.
if (!elgg_trigger_before_event('login', 'user', $user)) {
return false;
}
// handlers for the user, login:after event know the user is logged in.
elgg_trigger_after_event('login', 'user', $user);
Parameters:
$event The event name.
$object_type The object type (e.g. „user“ or „object“).
$object The object (e.g. an instance of
ElggUser
orElggGroup
)
The function will return false
if any of the selected handlers returned
false
and the event is stoppable, otherwise it will return true
.
Trigger an Event with results
Events with results provide a way for plugins to collaboratively determine or alter a value. For example, to decide whether a user has permission to edit an entity or to add additional configuration options to a plugin.
An event has a value passed into the trigger function, and each handler has an opportunity to alter the value before it’s passed to the next handler. After the last handler has completed, the final value is returned by the trigger.
You can trigger a custom event using elgg_trigger_event_results
:
<?php
// filter $value through the handlers
$value = elgg_trigger_event_results($name, $type, $params, $value);
Parameters:
$name The name of the event.
$type The type of the event or ‚all‘ for all types.
$params Arbitrary data passed from the trigger to the handlers.
$value The initial value of the event.
Trigger an Elgg Event sequence
Instead of triggering the :before
and :after
event manually, it’s possible to trigger an event sequence. This will trigger
the :before
event, then the actual event and finally the :after
event.
elgg()->events->triggerSequence($event, $type, $object, $callable);
// or if you wish to have a result sequence
$result = elgg->events->triggerResultsSequence($name, $type, $params, $value, $callable);
When called with for example 'cache:clear', 'system'
the following three events are triggered
'cache:clear:before', 'system'
'cache:clear', 'system'
'cache:clear:after', 'system'
Parameters:
$event The event name.
$object_type The object type (e.g. „user“ or „object“).
$object The object (e.g. an instance of
ElggUser
orElggGroup
)$callable Callable to run on successful event, before event:after
Bemerkung
As of Elgg 6.0 the :after
event will no longer be triggered if the result of the callable is false
. This was
done in order to prevent the system from thinking something was done which wasn’t successful. For example the
'delete', 'user'
event sequence. If the callback (which handles the actual removal from the database) wasn’t
successful the :after
event implied that the user was deleted. Now this is only triggered when the user is actually
removed from the database.
Unregister Event Handlers
The functions elgg_unregister_event_handler
can be used to remove
handlers already registered by another plugin or Elgg core. The parameters are in the same order as the registration
functions, except there’s no priority parameter.
<?php
elgg_unregister_event_handler('login', 'user', 'myPlugin_handle_login');
Anonymous functions or invokable objects cannot be unregistered, but dynamic method callbacks can be unregistered by giving the static version of the callback:
<?php
$obj = new MyPlugin\Handlers();
elgg_register_event_handler('foo', 'bar', [$obj, 'handleFoo']);
// ... elsewhere
elgg_unregister_event_handler('foo', 'bar', 'MyPlugin\Handlers::handleFoo');
Even though the event handler references a dynamic method call, the code above will successfully remove the handler.
Handler Calling Order
Handlers are called first in order of priority, then registration order.
Bemerkung
Before Elgg 2.0, registering with the all
keywords caused handlers to be called later, even
if they were registered with lower priorities.