Eventos y ganchos de complementos

Resumen

Elgg cuenta con un sistema de eventos que puedes usar para substituir o extender su funcionalidad predeterminada.

Los complementos influencian el sistema mediante la creación de manejadores (llamadas de retorno como funciones o métodos) y registrándolos para manejar dos tipos de eventos: eventos de Elgg y ganchos de complementos.

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.

Diferencias entre los eventos de Elgg y los ganchos de complementos

The main differences between Elgg Events and Plugin Hooks are:

  1. La mayor parte de los eventos de Elgg se pueden cancelar. A menos que los eventos sean eventos «after» (que tienen lugar después de que suceda algo), los manejadores de los eventos pueden cancelar dichos eventos devolviendo false, y con ello evitarán que se llame al resto de manejadores.
  2. Los ganchos de complementos no pueden cancelarse; todos los ganchos se llaman siempre.
  3. Los ganchos de complementos pasan un valor arbitrario a través de los manegadores, dándole a cada uno de ellos la oportunidad de modificarlo.

Eventos de Elgg

Los eventos de Elgg se desencadenan cuando se crea, actualizar o elimina un objeto. También tienen lugar en puntos importantes del proceso de carga de la infraestructura Elgg. Por ejemplo, existen eventos que suceden al crear un artículo de blog o al acceder un usuario al sitio.

Unlike Plugin Hooks, most Elgg events can be cancelled, halting the execution of the handlers, and possibly cancelling an some action in the Elgg core.

Todos los eventos de Elgg tienen un nombre y un tipo de objeto (system, user, object, relationship, annotation, group) que describe el tipo del objeto que se pasa a los manejadores.

Eventos del antes y el después

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. Like traditional events, handlers can cancel the event by returning false.

Los eventos del después, con nombres que terminan en «:after», ocurren después de que algo suceda. A diferencia de los eventos tradicionales, sus manejadores no pueden cancelar estos eventos; se llama siempre a todos los manejadores.

Cuando para un evento existen tanto la versión del antes como la del después, se recomienda a los desarrolladores que usen estas versiones del evento en vez de la principal —la que no es ni del antes ni del después—, si bien se seguirá permitiendo el uso de la versión original del evento para que Elgg siga siendo compatible con versiones anteriores de la infraestructura.

Manejadores de eventos de Elgg

Los manejadores de eventos de Elgg deberían tener el siguiente prototipo:

/**
 * @param string $event       The name of the event
 * @param string $object_type The type of $object (e.g. "user", "group")
 * @param mixed  $object      The object of the event
 *
 * @return bool if false, the handler is requesting to cancel the event
 */
function event_handler($event, $object_type, $object) {
    ...
}

If the handler returns false, the event is cancelled, preventing execution of the other handlers. All other return values are ignored.

Registrar un manejador para un evento de Elgg

Registre su manejador para un evento mediante elgg_register_event_handler:

elgg_register_event_handler($event, $object_type, $handler, $priority);

Parámetros:

  • $event: El nombre del evento.
  • $object_type: El tipo de objeto (por ejemplo: «user» o «object») en el que se lanza el evento, «all» si son todos los tipos.
  • $handler: La llamada de retorno de la función manejadora.
  • $priority: La prioridad. 0 es la mayor prioridad, 500 es el valor predeterminado.

Object here does not refer to an ElggObject but rather a string describing any object in the framework: system, user, object, relationship, annotation, group.

Ejemplo:

// Register the function myPlugin_handle_login() to handle the
// user login event with priority 400.
elgg_register_event_handler('login', 'user', 'myPlugin_handle_login', 400);

Advertencia

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.

Desencadenar un evento de Elgg

Usted puede desencadenar un evento personalizado de Elgg mediante elgg_trigger_event:

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.

// 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);

Parámetros:

  • $event: El nombre del evento.
  • $object_type: El tipo de objeto (por ejemplo: «user» o «object»).
  • $object: El objeto (como puede ser una instancia de ElggUser o de ElggGroup).

The function will return false if any of the selected handlers returned false and the event is stoppable, otherwise it will return true.

Ganchos de complementos

Plugin Hooks 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.

A plugin hook 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.

Manejadores de ganchos de complementos

Los manejadores de ganchos de complementos deberían tener el siguiente prototipo:

/**
 * @param string $hook    The name of the plugin hook
 * @param string $type    The type of the plugin hook
 * @param mixed  $value   The current value of the plugin hook
 * @param mixed  $params  Data passed from the trigger
 *
 * @return mixed if not null, this will be the new value of the plugin hook
 */
function plugin_hook_handler($hook, $type, $value, $params) {
    ...
}

If the handler returns no value (or null explicitly), the plugin hook value is not altered. Otherwise the return value becomes the new value of the plugin hook. It will then be passed to the next handler as $value.

Registrar un manejador para un gancho de complemento

Para registrar un manejador para un gancho de complementos, use elgg_register_plugin_hook_handler:

elgg_register_plugin_hook_handler($hook, $type, $handler, $priority);

Parámetros:

  • $hook: El nombre del gancho de complementos.
  • $type: El tipo del gancho, o «all» si son todos los tipos.
  • $handler: La llamada de retorno de la función manejadora.
  • $priority: La prioridad. 0 es la mayor prioridad, 500 es el valor predeterminado.

El significado del tipo puede variar. Podría tratarse del tipo de una entidad de Elgg o de algo específico del nombre del gancho de complementos.

Ejemplo:

// Register the function myPlugin_hourly_job() to be called with priority 400.
elgg_register_plugin_hook_handler('cron', 'hourly', 'myPlugin_hourly_job', 400);

Desencadenar un gancho de componente

Usted puede desencadenar un gancho de componente personalizado mediante elgg_trigger_plugin_hook:

// filter $value through the handlers
$value = elgg_trigger_plugin_hook($hook, $type, $params, $value);

Parámetros:

  • $hook: El nombre del gancho de complementos.
  • $type: El tipo del gancho, o «all» si son todos los tipos.
  • $params: Datos arbitrarios que se pasaron del desencadenante a los manejadores.
  • $value: El valor inicial del gancho de complementos.

Advertencia

The $params and $value arguments are reversed between the plugin hook handlers and trigger functions!

Unregister Event/Hook Handlers

The functions elgg_unregister_event_handler and elgg_unregister_plugin_hook_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.

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:

$obj = new MyPlugin\Handlers();
elgg_register_plugin_hook_handler('foo', 'bar', [$obj, 'handleFoo']);

// ... elsewhere

elgg_unregister_plugin_hook_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.

Nota

Before Elgg 2.0, registering with the all keywords caused handlers to be called later, even if they were registered with lower priorities.