Rules : Ajouter programmatiquement des événements, actions ou conditions

Dans les épisodes précédents vous avez pu lire une première présentation de Rules, module très utile et avec qui vous allez devoir devenir meilleurs amis lorsque vous utiliserez Drupal Commerce.

Nous allons donc voir comment exposer vos propres événements, conditions et actions à Rules. Rules est très flexible et offre la possibilité par défaut de rajouter les briques dont vous pourriez avoir besoin pour vos développements.

Commençons par les événements qui déclenchent les rules. Nous allons déclencher un événement lorsqu’un type de contenu précis sera visualisé, nous pourrions le faire avec les composants de base de Rules mais cela permet d’avoir un exemple assez simple. N’hésitez pas à consulter la documentation rédigée par fago pour rules, elle est assez complète et à jour.

Pour déclarer un événement il suffit d’implementer le hook hook_rules_event_info() et de décrire tous vos événements avec leurs paramètres. Exemple :

[codesyntax lang= »php »]

<?php
/**
* Implements hook_rules_event_info().
* Déclaration d'un événement basé sur le type du node vu.
*/
function monmodule_rules_event_info() {
  return array(
    'nodearticle_is_viewed' => array( // Nom de l'événement à invoquer via Rules.
      'label' => t("Un node de type article est entrain d'être vu"), // Description de la rule.
      'module' => 'Mon Module', // Groupe dans lequel faire apparaitre l'événement (node, utilisateur ou mon module).
      'arguments' => array( // Tableau des paramètres à passer à la fonction.
        'article' => array('type' => 'node', 'label' => t('Article visualisé.')), // Ici seulement le node.
      ),
    ),
  );
}
?>

[/codesyntax]

Pour que l’implémentation de l’événement soit complète il ne reste plus qu’à signaler à rules que l’événement se produit. Pour cela il suffit d’appeler la fonction rules_invoke_event() au bon moment. Dans notre exemple il suffit de faire cela au sein du hook_nodeapi() si le node est affiché et qu’il a le type article.

[codesyntax lang="php" lines="no" container="pre_valid" tab_width="0"]
/**
* Implements hook_nodeapi().
*/
function monmodule_nodeapi(&$node, $op) {
  if ($op == 'view' && $node->type == 'article') {
    rules_invoke_event('nodearticle_is_viewed', $node); // Invocation de l'événement.
  }
}
[/codesyntax]

Regardons maintenant comment déclarer de nouvelles conditions, l’exemple ici consiste à déterminer si le node que nous sommes entrain de visualiser possède un champ CCK précis (de type nodereférence )avec une valeur.

Cette fois ci il faut implémenter le hook hook_rules_condition_info() pour arriver à nos fins. Comme d’habitude un exemple est plus parlant.

[codesyntax lang= »php »]

/**
 * Implements hook_rules_condition_info().
 */
function monmodule_rules_condition_info() {
  return array(
    'monmodule_has_nodereference' => array(
      'label' => t('Mon node a un node référence.'),
      'arguments' => array(
        'node' => array('type' => 'node', 'label' => t('Node à vérifier')),
      ),
      'module' => 'User',
    ),
  );
}

[/codesyntax]

Comme pour la déclaration d’un événement, les conditions font appel à une fonction de callback, ici monmodule_has_nodereference. Dans cette fonction nous allons implémenter concrètement effectuer le test de la condition à évaluer.

[codesyntax lang= »php »]

function monmodule_has_reference($node, $settings) {
  if (isset($node->field_book)) {
    if (!is_null($node->field_book[0]['nid'])) {
      return TRUE;
    }
  }
  return FALSE;
}

[/codesyntax]

Ici nous évaluons la valeur d’un éventuel node reference pour le champ field_book mais le nom de ce champ pourrait être exposé dans la configuration de la condition, cette valeur se retrouverait dans le paramètre $settings. Pour voir comment configurer les conditions et actions, reportez à la documentation.

Une fois que les événements et conditions sont là, il ne reste qu’une chose à faire, écrire le code qui va être exécuté une fois notre évènement déclenché et notre condition remplie. Vous l’avez compris cette fois il faut exposer cette action via le hook hook_rules_action_info().

[codesyntax lang= »php »]

/**
 * Implements hook_rules_action_info().
 */
function monmodule_rules_action_info() {
  return array(
    'monmodule_domyaction' => array(
      'label' => t('Effectuer mon traitement'),
      'arguments' => array(
        'node' => array('type' => 'node', 'label' => t('Node exposé')),
      ),
      'module' => 'Mon Module',
    ),
  );
}

[/codesyntax]

Et toujours sur le même principe, la fonction de callback que vous avez déclaré est appelée lorsque la rule est déclenchée et satisfait les conditions configurée.

[codesyntax lang= »php »]

function monmodule_domyaction(&$node) {
  drupal_set_message(t("Ce noeud est de type article et possède au moins un node comme node reference dans le champ field_book"));
  // Effectuer tous les traitements imaginables.
}

[/codesyntax]

Etendre Rules 1 est donc quelque chose de très simple, tout se passe principalement dans ces trois hooks et grâce à eux vous pouvez étendre les possibilités de Rules à l’infini. N’hésitez pas à consulter la documentation pour découvrir d’autres fonctionnalités offertes par Rules.

Rules 2 (Drupal 7)  permet d’utiliser Rules comme une API de façon beaucoup plus simple,  cette nouvelle version explore très facilement les types d’entités et si vous installé entity metadata, vous pourrez également exploiter la puissance des informations additionnelles mises à disposition (accès à toutes les données d’un type d’entity).

2 thoughts on “Rules : Ajouter programmatiquement des événements, actions ou conditions

  1. Salut Julien,
    Merci pour cet article et tous les autres d’ailleurs.
    Juste une petite question :
    dans la fonction monmodule_rules_condition_info(), tu mets la valeur « user » pour la clé « module » dans le tableau associatif. C’est une coquille ou c’est volontaire ?
    Merci encore
    Tim

  2. C’est volontaire, lorsque tu indique « user » comme module, ton événement / condition / action apparait dans le groupe « user », c’est à toi de déterminer si cela fait du sens de le faire apparaitre dans un groupe existant ou si tu veux les grouper dans quelque chose de custom.

Comments are closed.