Обзор хуков, применение их своих модулях

Опубликовано 2012.04.15

В CMF Drupal предусмотрена работа с событиями. Для этого используются хуки. Каждый хук привязан к своему событию. Используя хуки можно привязаться к любому событию.

Например, вы хотите, чтобы при добавлении комментария к статье – на ящик автора статьи посылалось уведомление. Для этого привязываемся к событию «добавление комментария» и выполняем отправку сообщения.

Использовать хуки можно в модулях. Хук – это функция с именем <имя модуля>_<название хука>

Например, чтоб использовать hook_menu в модуле test_module – нужно создать функцию с именем test_module_menu, hook_permissiontest_module_permission и т.д. Вызывать хуки не нужно – они сами отработаются  когда надо.

Самый распространенный хук – это hook_menu . Он служит для создания страниц/меню. Все эти страницы «встроятся» в меню.

Давай те создадим несколько разных страниц и посмотрим как они работают.

Для работы с хуком будем использовать наш первый модуль test_module.

Добавим страницу в административный интерфейс по управлению аккаунтами. Выполним страницу в виде вкладки.

  1. //страницы в панели администрирования
  2. $items['admin/config/people/accounts/new_settings'] = array(
  3. 'title' => t('Новая настройка'),
  4. 'page callback' => 'new_function',
  5. 'type' => MENU_LOCAL_TASK,
  6. 'access arguments' => array('new rule'),
  7. 'description' => t('Описание новой страницы')
  8. );

В этот раз мы добавили новый элемент – access arguments. Это массив правил, которые должны быть разрешены у роли пользователя, пытающегося открыть страницу. Также аргумент type имен значение MENU_LOCAL_TASK. Это говорит о том, что страница будет отображена в виде вкладки.

Фразу «Содержание страницы» возвращает функция new_function. Приводить её код мы не будем.

Также чтоб работало правило доступа – необходимо использовать в модуле hook _permission

  1. //раздача прав.
  2. function test_module_permission() {
  3. return array(
  4. 'new rule' => array(
  5. 'title' => t('Новое правило'),
  6. 'description' => t('Доступ к новой админской странице.'),
  7. ),
  8. 'new user rule' => array(
  9. 'title' => t('Страница пользователя'),
  10. 'description' => t('Доступ к новой пользовательской странице.'),
  11. ),
  12. );
  13. }

Такой код добавит следующую строку в интерфейс системы.

Если адрес страницы динамический – например user/<nid>/edit, где <nid> - это номер пользователя – то тогда следует использовать аргументы. Рассмотрим на примере.

  1. $items['user/%/my_url'] = array(
  2. 'title' => t('Личная страница пользователя'),
  3. 'page callback' => 'new_user_function',
  4. 'type' => MENU_LOCAL_TASK,
  5. 'page arguments' => array(1),
  6. 'access arguments' => array('new user rule'),
  7. 'description' => t('Новая пользовательская страница.')
  8.  
  9. );

В адресе страницы аргумент обозначается знаком процента(в коде).В адресной строке вместо аргумента может быть любая строка или число. Аргументов может быть несколько. Также появился аргумент page arguments. В нём будет массив чисел, соответствующих «порядковому номеру аргумента» в адресе страницы. Эти «номера» считаются так – строка адреса делится по знаку «/» и нумеруются с нуля. В нашем случае user – нулевой аргумент, % - первый и my_url – второй. Работать мы будем с первым, поэтому в page arguments передаём единицу.

Если в адресе будет 2 или 3 аргумента – передаём их все.

 Например для адреса custom_url/%/display/%  -  page arguments будет равен array(1,3).

А чтобы использовать аргументы в «каллбэчной» функции – их нужно передать этой функции обыкновенными аргументами. Имя аргумента может быть любым.

Давайте выведем на этой странице часовой пояс пользователя. Функцией user_load загрузим объект пользователя и выведем нужную нам информацию.

  1. //отрисовка уникальной пользовательской страницы
  2. function new_user_function($nid){
  3. $user=user_load($nid);
  4. return $user->timezone;
  5. }

Если вы всё сделали верно – то увидите примерно следующее.

Теперь давайте изменим стандартную форму Друпала, тоесть изменим функциональность ядра, не трогая само ядро. Добавим к форме регистрации возможность ввести промо код.

Нам потребуется hook_form_alter.

  1. //добавление промо кода на страницу регистрации
  2. function test_module_form_alter(&$form, &$form_state, $form_id){
  3. if($form_id=='user_register_form'){
  4. $form['account']['promo']=array(
  5. '#type' => 'textfield',
  6. '#title' => t('Промо код'),
  7. '#maxlength' => 20,
  8. '#description' => 'Если у вас есть промо код - введите его.',
  9. '#required' => 0,
  10. '#access' => 1,
  11. '#weight' => 10
  12. );
  13. }
  14. }

Если идентификатор формы равен user_register_form – то добавляем поле для промо кода.

Проверяем.

Как видите – поле успешно добавлено.

Теперь напишем обработчик. Используем hook_user_insert.

Мы просто отобразим сообщение об использовании промо кода.

  1. //обработчик промо кода.
  2. function test_module_user_insert(&$edit, $account, $category){
  3. if($account->promo){
  4. watchdog('test_module',print_r('Использован промо код:'.$account->promo,1));
  5. }
  6. }

Теперь попробуем зарегистрироваться с промо кодом.

После регистрации посмотрим лог Друпала.

Вместо записи в лог можно было бы добавить пользователю какую-нибудь роль, отправить e-mail или что-нибудь другое.

Список хуков можно посмотреть здесь http://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7