Drupal不会调用我的钩子


9

我正在开发一个模块,但是我要添加的钩子没有从Drupal调用。它发生在多个钩子上。

我阅读了有关挂钩的文档,但找不到任何可以解释为什么发生这种情况的内容。我确认我使用了正确的参数,并返回了正确的值。

我究竟做错了什么?我有什么想念的吗?


对于有关Drupal未调用的钩子的问题,该问题被认为是规范问题。
kiamlaluno

Answers:


13

在开发模块时,应牢记以下注意事项。

  • 从模块完成钩子的实现是一个函数,该函数的名称以模块短名称(也称为机器名)为前缀。从挂钩名称中脱下挂钩部分,然后将其替换为模块机器名称。例如,hook_menu()example.module 的done 实现是example_menu()。如果模块为example_menu.module,而函数为example_menu(),则不视为hook_menu()example_menu.module 的实现。
    例如,这还意味着hook_form_alter()example_form.module 中的实现不是example_form_alter(),而是example_form_form_alter()。再举一个例子,不是hook_form_FORM_ID_alter()为了更改user_register_form()从example.module 返回的表单而完成的实现example_form_user_register_alter(),而是example_form_user_register_form_alter()。(表单ID为user_register_form。)

  • 一般而言,在模块机器名称中使用大写字母不会产生问题:PHP不会在myModule_get_value()mymodule_get_value()和之间产生区别,而是$value = myModule_get_value()会调用myModule_get_value()mymodule_get_value()
    但是,在某些情况下,在模块机器名称中使用大写字母会引起问题:在为模块定义更新挂钩时。drupal_get_schema_versions(),该函数返回可用更新的列表,其中包含以下代码。

    // 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'];
      }
    }

    执行的最后一行drupal_get_schema_versions()是下一行。

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

    如果模块名称为myModule.module,drupal_get_schema_versions('myModule')则仅返回名称以myModule_update开头,以数字结尾的函数;之类的函数mymodule_update_7120()不会包含在内,因为from drupal_get_schema_versions()中使用的正则表达式区分大小写。这仍然适用于Drupal 8,因为正则表达式仍与Drupal 7中使用的正则表达式相同。

  • 一些挂钩在特定时刻被调用。例如,在启用/禁用模块后或清除路由器信息的缓存后,从Drupal 7中调用hook_menu(),和hook_menu_alter()hook_init()不为缓存的页面调用。
    一旦挂钩因特定事件发生而被调用,它们将不会再次调用,直到类似事件不再发生为止。在两个连续的页面请求中未调用它们。

  • Drupal缓存从模块实现的挂钩列表。如果您正在编辑已启用模块的代码以添加新的挂钩,则首先需要禁用并重新启用该模块,否则Drupal不会注意到有新的挂钩。

  • 确保return在重构过程中语句不会潜入您的钩子函数之一。它不仅可能破坏它出现的钩子,而且还可能导致连锁反应也破坏其他钩子,从而使问题很难定位。


为了将来其他人的考虑,也许还值得一提的是我的错误:请勿在.module(或任何其他“平面”,非类PHP)文件中定义名称空间。否则,Drupal将无法识别您的文件,因此不会发现其中定义的钩子。
Balu Ertl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.