Mes crochets ne sont pas invoqués par Drupal

9

Je développe un module, mais les hooks que j'ajoute ne sont pas invoqués depuis Drupal. Cela se produit avec plusieurs crochets.

J'ai lu la documentation des crochets et je ne trouve rien qui pourrait expliquer pourquoi cela se produit. J'ai vérifié que j'utilise les paramètres corrects et que je renvoie la valeur correcte.

Qu'est-ce que je fais mal? Y a-t-il quelque chose qui me manque?

kiamlaluno
la source
Cette question est considérée comme une question canonique pour ces questions sur les crochets qui ne sont pas invoqués par Drupal.
kiamlaluno

Réponses:

13

Lors du développement d'un module, vous devez garder à l'esprit les notes suivantes.

  • L'implémentation d'un hook effectué à partir d'un module est une fonction dont le nom est préfixé par le nom court du module (également appelé nom de la machine ); du nom du crochet, retirez la partie du crochet et remplacez-la par le nom de la machine du module. Par exemple, l'implémentation de hook_menu()done from example.module est example_menu(). Si le module est example_menu.module et que la fonction estexample_menu() , cela n'est pas considéré comme l' hook_menu()implémentation de example_menu.module.
    Cela signifie également, par exemple, que l' hook_form_alter()implémentation dans example_form.module ne l'est pas example_form_alter(), mais example_form_form_alter(). Comme autre exemple, l'implémentation de hook_form_FORM_ID_alter()done pour modifier le formulaire renvoyé user_register_form()par example.module ne l'est pas example_form_user_register_alter(), maisexample_form_user_register_form_alter(). (L'ID du formulaire est user_register_form .)

  • De manière générale, l'utilisation de caractères majuscules dans le nom de la machine du module ne crée pas de problèmes: PHP ne fait pas de différence entre myModule_get_value(), et mymodule_get_value(), et$value = myModule_get_value() appellerait soit myModule_get_value(), soit mymodule_get_value().
    Cependant, il existe un cas où l'utilisation de caractères majuscules dans un nom de machine de module entraînerait des problèmes: lors de la définition des crochets de mise à jour pour un module. drupal_get_schema_versions(), la fonction qui renvoie une liste des mises à jour disponibles, contient le code suivant.

    // Prepare regular expression to match all possible defined hook_update_N().
    $regexp = '/^(?P<module>.+)_update_(?P<version>\d+)$/';
    $functions = get_defined_functions();
    // Narrow this down to functions ending with an integer, since all
    // hook_update_N() functions end this way, and there are other
    // possible functions which match '_update_'. We use preg_grep() here
    // instead of foreaching through all defined functions, since the loop
    // through all PHP functions can take significant page execution time
    // and this function is called on every administrative page via
    // system_requirements().
    foreach (preg_grep('/_\d+$/', $functions['user']) as $function) {
      // If this function is a module update function, add it to the list of
      // module updates.
      if (preg_match($regexp, $function, $matches)) {
        $updates[$matches['module']][] = $matches['version'];
      }
    }

    La dernière ligne exécutée depuis drupal_get_schema_versions()est la suivante.

    return empty($updates[$module]) ? FALSE : $updates[$module];

    Si le nom du module est myModule.module, drupal_get_schema_versions('myModule')renverra uniquement les fonctions avec un nom commençant par myModule_update et se terminant par un nombre; les fonctions comme mymodule_update_7120()ne seront pas incluses car l'expression régulière utilisée à partir de drupal_get_schema_versions()est sensible à la casse. Cela s'applique toujours à Drupal 8, car l'expression régulière est toujours la même que celle utilisée dans Drupal 7.

  • Certains crochets sont appelés à des moments spécifiques. Par exemple hook_menu(), ethook_menu_alter() sont appelés à partir de Drupal 7 après l'activation / la désactivation d'un module ou lorsque le cache des informations du routeur est effacé; hook_init()n'est pas invoqué pour les pages mises en cache.
    Une fois les hooks invoqués parce qu'un événement spécifique s'est produit, ils ne seront plus appelés tant qu'un événement similaire ne se produira pas. Ils ne sont pas appelés dans deux requêtes de page successives.

  • Drupal met en cache la liste des hooks implémentés à partir d'un module. Si vous modifiez le code d'un module activé pour ajouter de nouveaux hooks, vous devez d'abord désactiver et réactiver le module, ou Drupal ne remarquera pas qu'il y a de nouveaux hooks.

  • Assurez-vous qu'une returninstruction ne s'est pas faufilée dans l'une de vos fonctions de hook lors d'une refactorisation. Il a le potentiel de casser non seulement le crochet dans lequel il apparaît, mais également de provoquer une réaction en chaîne qui brise également d'autres crochets, ce qui rend le problème difficile à localiser.

kiamlaluno
la source
Peut-être aussi vaut-il la peine de mentionner mon erreur pour le bien des autres à l'avenir: ne définissez PAS un espace de noms dans votre fichier .module (ou tout autre fichier PHP "plat", non-classe). Sinon, Drupal ne reconnaîtra pas votre fichier et ne découvrira donc pas les crochets qui y sont définis.
Balu Ertl