Что связывает хук Drupal с конкретным модулем?

Что связывает хук Drupal с конкретным модулем?

В Drupal 7 каждый модуль ядра имеет файл «api».

$ ls modules/*/*.api.php
modules/aggregator/aggregator.api.php   modules/openid/openid.api.php
modules/block/block.api.php             modules/overlay/overlay.api.php
modules/comment/comment.api.php         modules/path/path.api.php
modules/contextual/contextual.api.php   modules/rdf/rdf.api.php
modules/dashboard/dashboard.api.php     modules/search/search.api.php
modules/field/field.api.php             modules/shortcut/shortcut.api.php
modules/field_ui/field_ui.api.php       modules/simpletest/simpletest.api.php
modules/file/file.api.php               modules/system/system.api.php
modules/filter/filter.api.php           modules/system/theme.api.php
modules/help/help.api.php               modules/taxonomy/taxonomy.api.php
modules/image/image.api.php             modules/trigger/trigger.api.php
modules/locale/locale.api.php           modules/update/update.api.php
modules/menu/menu.api.php               modules/user/user.api.php
modules/node/node.api.php

Каждый из этих файлов содержит функцию, которая никогда (?) не вызывается, но документирует существование хука, который могут реализовать другие модули (включая сторонние).

File: modules/path/path.api.php
function hook_path_delete($path) {
  db_delete('mytable')
    ->condition('pid', $path['pid'])
    ->execute();
}

Мой вопрос: что связывает конкретный хук с конкретным модулем? Почему хук path_delete включен в файл path.api.php? Почему хук entity_view включен в файл system.api.php? Является ли это просто произвольной организацией постфактум, или в системе Drupal есть что-то, что привязывает конкретный хук к конкретному модулю? Или что-то другое?


person Alan Storm    schedule 15.02.2011    source источник


Ответы (2)


Хуки вызываются с помощью module_invoke() и module_invoke_all(): если вы посмотрите на код этих двух функций, вы мог бы собрать воедино, как это работает, но в основном, если я добавлю это в код моего модуля:

// Other code

$foo = module_invoke_all('foo_bar', $var1, $var2);

// More code

Drupal будет вызывать каждую реализацию hook_foo_bar($var1, $var2), которую найдет в включенных модулях. Исходя из этого, вы должны увидеть, что единственная вещь, которая связывает конкретный хук с конкретным модулем, — это соглашение об именах: если я назову свой модуль foo, мои функции хука должны начинаться с hook_foo_.

Вы правы в том, что *.api.php ничего не вызывается: поскольку вызов модуля - это просто вызов функции, авторы модулей включают foo.api.php просто в целях документации, чтобы сообщить разработчикам, как реализовать хук.

Например, в приведенном выше случае foo.api.php будет включать пример функции, такой как:

/**
 * Doxygen comments documenting the function goes here
 */
function hook_foo_bar($var1, $var2) {
  return $var1 + $var2;
}

Но как разработчик модуля я мог бы реализовать hook_foo_bar() по-другому:

function mymodule_foo_bar($var1, $var2) {
  return $var1 - $var2;
}

И когда будет вызван module_invoke_all(), Drupal создаст функцию, используя короткое имя реализующего модуля (mymodule) и имя хука, переданное module_invoke_all() (foo_bar), тем самым вызывая функцию mymodule_foo_bar(), которую я только что определил.

Модуль system в ядре является своего рода универсальным: одна из задач Drupal 8 — убить его и делегировать его функциональность другим модулям.

person Community    schedule 15.02.2011
comment
Спасибо, как раз то, что я искал. Я понимаю основную концепцию хука, но хотел подтвердить, что между модулем и хуком не было формальной связи, что это было просто соглашением. - person Alan Storm; 15.02.2011


может быть, вы можете попробовать научиться перехватывать друпал? это просто:
http://api.drupal.org/api/drupal/includes--module.inc/group/hooks/7

О hook_path_delete:
Посмотри path.module, где-то увидишь path_delete(...) вызывает.
Например, в path_node_update() - эта функция вызывается, когда вы меняете текущий путь - она ​​удаляет старый путь раньше, чем создает новый путь для узла.
Теперь смотрит, где определена функция path_delete() - она ​​помещена в файл path.inc:
В этой функции вы увидите: module_invoke_all('path_delete', $path); - что делает эта функция?
Это список всех модулей (в drupal 7 он кэшируется), где определено hook_path_delete (как я уже показывал ранее, для пользовательского модуля yiu он определен как YOURMODULENAME_path_delete, и он также будет включен здесь), и запускает все эти функции одну за другой. (порядок запуска определяется весом и именем файлов модулей).
Итак, что теперь вы можете делать в пользовательском модуле? Вы можете ответить на эту реакцию на удаление и выполнить некоторые другие действия - например, удалить другой путь, который можно использовать для дублирования пути этого узла (это просто пример).

p.s. Хорошая идея для запуска пользовательских модулей: http://drupal.org/contributors-guide

person Nikit    schedule 15.02.2011
comment
hook_entity_view вызывается в комментариях, узле, таксономии и пользовательских модулях (и может быть больше в contrib.modules). Это низкоуровневый хук, там вы можете отслеживать, что происходит с вашими объектами. - person Nikit; 15.02.2011
comment
Я знаю, как использовать хуки, и меня не интересует специфика конкретного хука; Я пытаюсь понять модульную систему целиком и по отдельности, чтобы понять остальную часть Drupal. Ваши комментарии полезны, но не отвечают на мой основной вопрос: что связывает хук с конкретным модулем? Конвенция или что-то формальное. - person Alan Storm; 15.02.2011
comment
хм, это видно из ответа: имя_модуля_имя_хука - это имя модуля уровня с именем хука. - person Nikit; 15.02.2011
comment
module_hook_name — это то, как вы реализуете модуль. Однако durpal документирует свои хуки внутри файлов API модуля, что означает, что каждый модуль предоставляет хук для реализации другими модулями. Я спрашивал, были ли эти отношения формальными или просто подразумеваемыми через документацию и использование. - person Alan Storm; 15.02.2011