Создание хуков

Создания хука — процесс, при котором будут срабатывать вызовы всех реализаций хука, в пределах проекта по его имени.

Нужно ли мне создавать хук?

Прежде всего, стоит определиться, действительно ли вам нужны именно хуки? Хуки в Drupal 8, это отчасти legacy подход, который пытаются убрать из ядра. Тем самым, это не самый предпочтительный способ добавить гибкости своему модулю.

Они могут быть легко заменены сервисами с метками, плагинами или же событиями. Все эти инструменты — ООП реализации на замену хукам с более конкретными целями и задачами.

Прежде чем использовать хуки, рассмотрите данные варианты, так как, скорее всего, правильнее всего делать с использованием одного, или нескольких перечисленных ранее инструментов.

Таким образом, выбор хуков — не самый лучший выбор в реалиях Drupal 8, тем не менее, он является поддерживаемым, и хуки, скорее всего, не исчезнут и в Drupal 9.

Создание хука

У хуков нет централизованного хранилища или менеджера, поэтому производить их вызов и обработку можно из любого модуля или функции в коде Drupal.

Ввиду особенностей работы хуков, их необходимо вызвать там, где они нужны и для какой цели они были созданы. Таким образом, их можно найти где угодно, и в каком угодно количестве.

Единственное что соединяет хуки с API - это сервис module_handler, через который и происходит вызов хуков.

Сервис module_handler отвечает за куда большее количество задач, чем просто хуки, при этом, хуки, вызванные через данный сервис, также и вызываются у тем оформления, а не только у модулей.

Данный сервис также делит хуки на два типа: исполняемые хуки и альтер хуки.

Регистрация (вызов) исполняемого хука

Для вызова исполняемых хуков данный сервис предоставляет два метода:

  1. invokeAll($hook, array $args = []) - вызывает все реализации хука $hook, передавая в качестве аргументов $args.
  2. invoke($module, $hook, array $args = []) - вызывающий реализации хука $hook, передавая в качестве аргументов $args, но только для указанного модуля или темы $module.

Обратите внимание, что в качестве аргументов, передаваемых хуку, принимается массив $args, но каждый элемент данного массива, будет передан как отдельный аргумент.

Пример простого вызова

Пример регистрации (вызова) хука hook_to_rule_them_all() для всех активных модулей и тем, что реализуют данный хук.

\Drupal::moduleHandler()->invokeAll('to_rule_them_all');

Данный хук будет вызван, а что произойдет внутри - не важно модулю, который его вызывает.

Пример вызова с передачей аргументов

Пример регистрации (вызова) хука hook_to_rule_them_all($foo, $bar = NULL) с передачей двух аргументов.

$args = [
  'Hello',
  'World',
];

\Drupal::moduleHandler()->invokeAll('to_rule_them_all', $args);

Все реализации хука получат в качестве аргумента $foo значение Hello, а для аргумента $bar - World.

Пример вызова и ожидание результата

Пример регистрации (вызова) хука hook_to_rule_them_all(), где ожидается, что реализация хука вернет что-то.

$results = \Drupal::moduleHandler()->invokeAll('to_rule_them_all');

В результате данного вызова, переменная $results будет массивом, содержащим все ответы от реализаций данных хуков. Если ответов не было, или реализации отсутствуют, то массив окажется пустым.

Регистрация (вызов) альтер хука

Для альтер хуков в сервисе module_handler всего один метод alter().

Альтер хуки вызываются несколько иначе от исполняемых. Метод alter() принимает следующие аргументы:

  • $type: Название альтер хука. Приставка _alter() будет добавлена к названию автоматически.
  • &$data: Аргумент, который будет передан в альтер хук первым по ссылке.
  • &$context1: (опционально) Дополнительная переменная для передачи данных в хуки.
  • &$context2: (опционально) Дополнительная переменная для передачи данных в хуки.

Таким образом, у альтер хуков ограниченное число переменных для передачи. Если вам не хватает 3 аргументов, рекомендуется использовать их в качестве ассоциативных массивов.

Пример вызова альтер хука

Пример регистрации хука hook_to_rule_them_all_alter($value).

$value_to_alter = 'Hello World!`;

\Drupal::moduleHandler()->alter('to_rule_them_all', $value_to_alter);

Документирование хука

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

В данном файле вы должны описать каждый хук в виде функции, где её название равно названию хука, а также его аргументами. Вы должны написать документацию в комментарии, а в теле функции, привести пример использования.

Пример документации хука:

/**
 * Allows you to alter some value.
 *
 * @param mixed $value
 *   The value to alter.
 */
function hook_to_rule_them_all_alter(&$value) {
  if ($value == 'Hello World!') {
    $value = 'World Hello!';
  }
}

Для более детальной информации обращайтесь к "Стандарты API документации и комментариев".

Ссылки

🌱 Помогите нам сделать документацию лучше!

Вся документация Druki с отрытым исходным кодом. Нашли ошибку или неточность? Создайте pull request.

Редактировать текущий документ Обсудить улучшение

Или узнайте как контрибутить.

🤔 По-прежнему нужна помощь?

Не нашли ответа на свой вопрос? Попросите помощи у сообщества!

Задайте вопрос на GitHub Смотрите другие ресурсы сообщества