Создания хука — процесс, при котором будут срабатывать вызовы всех реализаций хука, в пределах проекта по его имени.
¶Нужно ли мне создавать хук?
Прежде всего, стоит определиться, действительно ли вам нужны именно хуки? Хуки в Drupal 8, это отчасти legacy подход, который пытаются убрать из ядра. Тем самым, это не самый предпочтительный способ добавить гибкости своему модулю.
Они могут быть легко заменены сервисами с метками, плагинами или же событиями. Все эти инструменты — ООП реализации на замену хукам с более конкретными целями и задачами.
Прежде чем использовать хуки, рассмотрите данные варианты, так как, скорее всего, правильнее всего делать с использованием одного, или нескольких перечисленных ранее инструментов.
Таким образом, выбор хуков — не самый лучший выбор в реалиях Drupal 8, тем не менее, он является поддерживаемым, и хуки, скорее всего, не исчезнут и в Drupal 9.
¶Создание хука
У хуков нет централизованного хранилища или менеджера, поэтому производить их вызов и обработку можно из любого модуля или функции в коде Drupal.
Ввиду особенностей работы хуков, их необходимо вызвать там, где они нужны и для какой цели они были созданы. Таким образом, их можно найти где угодно, и в каком угодно количестве.
Единственное что соединяет хуки с API - это сервис module_handler
, через который и происходит вызов хуков.
Сервис module_handler
отвечает за куда большее количество задач, чем просто хуки, при этом, хуки, вызванные через данный сервис, также и вызываются у тем оформления, а не только у модулей.
Данный сервис также делит хуки на два типа: исполняемые хуки и альтер хуки.
¶Регистрация (вызов) исполняемого хука
Для вызова исполняемых хуков данный сервис предоставляет два метода:
-
invokeAll($hook, array $args = [])
- вызывает все реализации хука$hook
, передавая в качестве аргументов$args
. -
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 документации и комментариев".
¶Ссылки
- Drupal 8: hooks (+ YouTube), Niklan, 2018