Мои крючки не вызываются Drupal

9

Я разрабатываю модуль, но добавляемые мной хуки не вызываются из Drupal. Это происходит с более чем одним крючком.

Я прочитал документацию по хукам и не могу найти ничего, что объясняло бы, почему это происходит. Я подтвердил, что использую правильные параметры и возвращаю правильное значение.

Что я делаю неправильно? Есть что-то, что я пропускаю?

kiamlaluno
источник
Этот вопрос считается каноническим вопросом для тех вопросов о том, что Drupal не вызывает хуки.
kiamlaluno

Ответы:

13

При разработке модуля вы должны учитывать следующие замечания.

  • Реализация ловушки, выполняемой из модуля, представляет собой функцию, имя которой начинается с короткого имени модуля (также называемого именем машины ); от имени крюка, снимите часть крюка и замените его именем машины модуля. Например, реализация hook_menu()делается из example.module 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()done для изменения формы, возвращаемой user_register_form()из example.module example_form_user_register_alter(), ноexample_form_user_register_form_alter(), (Идентификатор формы - 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 и заканчивается числом; функции like mymodule_update_7120()не будут включены, потому что используемое регулярное выражение с drupal_get_schema_versions()учетом регистра. Это все еще относится к Drupal 8, так как регулярное выражение все равно используется в Drupal 7.

  • Некоторые крючки вызываются в определенные моменты. Например, hook_menu()и hook_menu_alter()вызываются из Drupal 7 после того, как модуль был включен / отключен, или когда очищен кэш для информации маршрутизатора; hook_init()не вызывается для кэшированных страниц.
    Как только перехваты вызваны, потому что произошло определенное событие, они не будут вызываться снова, пока подобное событие не произойдет. Они не вызываются в двух последовательных запросах страницы.

  • Drupal кэширует список хуков, реализованных из модуля. Если вы редактируете код активированного модуля для добавления новых хуков, сначала нужно отключить и снова включить модуль, иначе Drupal не заметит, что появились новые хуки.

  • Убедитесь, что returnоператор не проник в одну из ваших функций ловушки во время рефакторинга. Он может сломать не только тот крючок, в котором он появляется, но и вызвать цепную реакцию, которая сломает и другие крючки, затрудняя поиск проблемы.

kiamlaluno
источник
Также, возможно, стоит упомянуть мою ошибку ради других в будущем: НЕ определяйте пространство имен в вашем файле .module (или любом другом «плоском», не относящемся к классу PHP) файле. В противном случае Drupal не распознает ваш файл, поэтому не обнаружит определенные в нем хуки.
Balu Ertl