Événements et Hooks des plugins

Aperçu

Elgg a un événement système qui peut être utilisé pour remplacer ou étendre les fonctionnalités du noyau.

Les plugins influencent le système en créant des gestionnaires ou handlers (appelables tels que des fonctions et des méthodes) et en les enregistrant pour gérer deux types d’événements : design/events#events et Hooks des plugins.

Quand un événement est déclenché, un jeu des gestionnaires (handlers) est exécuté par ordre de priorité. Les arguments sont passés à chaque gestionnaire qui peut influencer le processus. Après exécution, la fonction déclencheuse (« trigger ») retourne une valeur qui dépend du comportement des gestionnaires.

Evénements Elgg (Events) vs. Hooks des Plugins

Les principales différences entre événements Elgg Events et les hooks Plugin Hooks sont :

  1. La majorité des événements Elgg peuvent être annulé ; à moins que l’événement soit un événement « after », un gestionnaire qui retourne false peut annuler l’événement, et plus aucun autre gestionnaire n’est appelé.

  2. Les hooks plugin ne peuvent pas être annulé ; tous les gestionnaires sont toujours appelés.

  3. Les hooks lugin passent une valeur arbitraire à travers les gestionnaires, leur donnant à chacun une chance de la modifier en cours de route.

Evénements Elgg (Events)

Les événements Elgg Events sont déclenchés quand un objet Elgg est créé, modifié ou supprimé ; et à différentes étapes importantes du chargement du framework Elgg. Exemples : lors de la création d’un article de blog ou de l’identification d’un utilisateur.

Contrairement aux Hooks de Plugin, la plupart des événements Elgg peuvent être annulés, ce qui arrête l’exécution des gestionnaires, et permet potentiellement d’annuler une action dans le noyau Elgg.

Chaque événement Elgg a un nom et un type d’objet (system, user, object, nom de relation, annotation, group) qui décrit le type d’objet passé aux gestionnaires.

Événements Avant (Before) et Après (After)

Certains événements sont séparés en « before » (avant) et « after » (après). Ceci évite la confusion autour de l’état fluctuant du système. Par ex. Est-ce que l’utilisateur est identifié au cours de l’événement [login, user]?

Les événements Avant ont des noms qui se terminent par « :before » et sont exécutés avant qu’il ne se passe quelque chose. Comme pour les événements traditionnels, les gestionnaires peuvent annuler l’événement en retournant false.

Les événements Après, avec des noms qui se terminent par « :after », sont exécutés après qu’il se soit passé quelque chose. Au contraire des événements traditionnels, ces gestionnaires ne peuvent pas annuler ces événements ; tous les gestionnaires seront toujours appelés.

Là où des événements :before et :after sont disponibles, les développeurs sont encouragés à faire la transition vers eux, même si d’anciens événements resteront supportés pour des raisons de compatibilité descendante.

Gestionnaires d’événement Elgg (Event Handlers)

Les gestionnaires d’événements Elgg devraient avoir le prototype suivant :

/**
 * @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) {
    ...
}

Si un gestionnaire renvoie false, l’événement est annulé, ce qui empêche l’exécution des autres gestionnaires. Toutes les autres valeurs de retour sont ignorées.

Enregistrez un gestionnaire d’événement (Elgg Event)

Enregistrez votre gestionnaire pour un événement en utilisant elgg_register_event_handler :

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

Paramètres :

  • $event Le nom de l’événement.

  • $object_type Le type d’objet (par ex. « user » ou « object ») ou “all” pour tous les types pour lesquels l’événement est déclenché.

  • $handler Le callback ou la fonction gestionnaire.

  • $priority La priorité - 0 en premier et la valeur par défaut est 500.

Objet ne fait pas ici référence à un ElggObject mais plutôt à une chaîne de caractères qui décrit n’importe quel objet dans le framework : le système, un utilisateur, un objet, une relation, une annotation, un groupe.

Exemple :

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

Avertissement

Si vous gérez l’événement « update » d’un objet, évitez d’appeler save() dans votre gestionnaire d’événement. Tout d’abord ce n’est probablement pas nécessaire car l’objet est enregistré après que l’événement soit terminé, mais aussi parce que save() appelle un autre événement « update » et ne rend plus disponible $object->getOriginalAttributes().

Déclencher un événement (Elgg Event)

Vous pouvez déclencher un événement personnalisé en utilisant 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.
}

Pour les événements avec des états ambigus, tels que l’identification d’un utilisateur, vous devriez utiliser les événements Before et After en appelant elgg_trigger_before_event ou elgg_trigger_after_event. Ceci clarifie pour le gestionnaire d’événement l’état auquel attendre et quels événements peuvent être annulés.

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

Paramètres :

  • $event Le nom de l’événement.

  • $object_type Le type d’objet (par ex. « user » ou « object »).

  • $object L’objet (par ex. une instance de ElggUser ou ElggGroup)

La fonction va retourner false si n’importe lequel des gestionnaires sélectionnés retourne false et si l’événement est interruptible, sinon elle retournera true.

Hooks des plugins

Les Hooks Plugin fournissent un moyen pour les plugins de déterminer ou de modifier collaborativement une valeur. Par exemple, pour décider si un utilisateur a la permission de modifier une entité ou d’ajouter des options de configurations supplémentaires à un plugin.

Un hook plugin a une valeur passée à la fonction déclencheuse (« trigger »), et chaque gestionnaire a la possibilité de modifier cette valeur avant qu’elle soit passée au prochain gestionnaire. Après que le dernier gestionnaire a été exécuté, la valeur finale est retournée par le trigger.

Gestionnaires des Hooks plugin

Les gestionnaires de hook de plugin devraient avoir le prototype suivant :

/**
 * @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) {
    ...
}

Si le gestionnaire ne renvoie aucune valeur (ou null explicitement), la valeur du hook de plugin n’est pas modifiée. Sinon, la valeur de retour devient la nouvelle valeur du hook plugin. Elle sera ensuite transmise au gestionnaire suivant en tant que $value.

Enregistrez un gestionnaire de Hook plugin

Enregistrez votre gestionnaire pour un hook plugin en utilisant elgg_register_plugin_hook_handler :

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

Paramètres :

  • $hook Le nom du hook plugin.

  • $type Le type de hook, ou “all” pour tous les types.

  • $handler Le callback ou la fonction gestionnaire.

  • $priority La priorité - 0 en premier et la valeur par défaut est 500.

Type peut avoir des sens différents. Cela peut signifier un type d’entité Elgg ou quelque chose de spécifique au nom du hook plugin.

Exemple :

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

Déclencher un Hook plugin

Vous pouvez déclencher un plugin hook personnalisé en utilisant elgg_trigger_plugin_hook :

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

Paramètres :

  • $hook Le nom du hook plugin.

  • $type Le type de hook, ou “all” pour tous les types.

  • $params Des données arbitraires passées par le déclencheur aux gestionnaires.

  • $value La valeur initiale du hook plugin.

Avertissement

Les arguments $params et $value sont inversés entre les gestionnaires de hook plugin et les focntions de déclenchement !

Dé-enregistrer des gestionnaires d’événement ou de hook

Les fonctions elgg_unregister_event_handler et elgg_unregister_plugin_hook_handler peuvent être utilisées pour retirer des gestionnaires déjà enregistrés par un autre plugin ou le noyau d’Elgg. Les paramètres sont dans le même ordre que pour les fonctions d’enregistrement, excepté qu’il n’y a pas de paramètre de priorité.

elgg_unregister_event_handler('login', 'user', 'myPlugin_handle_login');

Les fonctions anonymes ou les objets invocables ne peuvent pas être enregistrés, mais des fonctions de rappel (callback) de méthode dynamique peuvent être dé-enregistrés en donnant la version statique de la fonction de rappel :

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

// ... elsewhere

elgg_unregister_plugin_hook_handler('foo', 'bar', 'MyPlugin\Handlers::handleFoo');

Même si le gestionnaire d’événement référence un appel à une méthode dynamique, le code ci-dessus va bien supprimer le gesitonnaire.

Ordre d’appel des gestionnaires

Les gestionnaires sont d’abord appelés par ordre de priorité, puis par ordre d’enregistrement.

Note

Avant Elgg 2.0, l’enregistrement avec le mot-clef all provoquait un appel tardif des gestionnaires, même s’ils avaient été enregistrés avec des priorités plus faibles.