ertttert
Books-CMS.clan.su

Действия

Действие (action) — это что-то, выполняемое Drupal. Вот несколько примеров:

  • Продвижение ноды на главную страницу
  • Изменение состояния ноды с неопубликованного на опубликованное
  • Удаление пользователя
  • Отправка почтового сообщения

В каждом из этих случаев имеется четко определенная задача. Программисты могут отметить сходство приведенного списка с функциями PHP. Например, почтовое сообщение можно послать с помощью функции drupal_mail() из includes/mail.inc. Действия похожи на функции потому, что действия и являются функциями. Эти функции Drupal может анализировать и слабо связывать с событиями (об этом речь пойдет чуть ниже). А пока рассмотрим модуль триггера.

Пользовательский интерфейс триггера

Выберите пункт меню Modules (Модули) в верхней части страницы и на странице Modules активируйте модуль триггера. Щелкните на ссылке Structure (Структура) в верхней части страницы, а затем на странице Structure щелкните на ссылке Triggers (Триггеры). Появится интерфейс, похожий на показанный на рис. 3.1.

Обратите внимание на вкладки в верхней части. Они соответствуют хукам Drupal! На рис. 3.1 мы видим операции для хука ноды. Им всем назначены удобные имена, например, операция удаления хука ноды помечена текстом Trigger: After deleting content (Триггер: после удаления контента). Так что каждая операция хука показана с возможностью назначения действия, такого как Publish Content (Опубликовать контент), при выполнении этой операции. Все возможные действия приведены в раскрывающемся списке Choose an action (Выберите действие).

На заметку! Не для всех триггеров доступны все действия, т.к. некоторые действия в определенных контекстах не имеют смысла. Например, невозможно выполнить действие “Переместить заметку на заглавную страницу” с триггером “После удаления контента”. В зависимости от конкретной установки, некоторые триггеры могут выдать сообщение No actions available for this trigger (Для данного триггера нет доступных действий).

Имена некоторых триггеров с соответствующими им хуками и операциями приведены в табл. 3.2.

Таблица 3.2. Взаимосвязь хуков и триггеров в Drupal 7

After deleting a comment (После удаления комментария)

Хук Имя триггера
comment_insert After saving a new comment (После сохранения нового комментария)
comment_update After saving an updated comment (После сохранения измененного комментария)
comment_delete After deleting a comment (После удаления комментария)
comment_vew When a comment is being viewed by an authenticated user
(При просмотре комментария аутентифицированным пользователем)
cron When cron runs (При запуске cron)
node_presave When either saving a new post or updating an existing post
(При сохранении нового сообщения или изменении существующего сообщения)
node_insert After saving a new post (После сохранения нового сообщения)
node_update After saving an updated post (После сохранения измененного сообщения)
node_delete After deleting a post (После удаления сообщения)
node_view When content is viewed by an authenticated user
(При просмотре контента аутентифицированным пользователем)
taxonomy_term_insert After saving a new term to the database (После сохранения в базе данных нового термина) Book_
taxonomy_term_update After saving an updated term to the database (После сохране- ния в базе данных измененного термина)
taxonomy_term_delete After deleting a term (После удаления термина)
user_insert After a user account has been created (После создания пользовательской учетной записи)
user_update After a user’s profile has been updated (После изменения пользовательской учетной записи)
user_delete After a user has been deleted (После удаления пользователя)
user_login After a user has logged in (После входа пользователя)
user_logout After a user has logged out (После выхода пользователя)
user_view When a user’s profile is being viewed (При просмотре пользова- тельского профиля)

Первое действие

Что же понадобится предпринять, чтобы наша функция выдачи звукового сигнала стала полноправным действием? Для этого необходимо выполнить два шага.

  1. Сообщить Drupal, какие триггеры должно поддерживать действие.
  2. Создать саму функцию действия.

Первый шаг выполняется за счет реализации функции hook_action_info(). В модуле звукового сигнала она должна выглядеть так:

/**
* Реализация hook_action_info().
*/
function beep_action_info() {
 return array(
 'beep_beep_action' => array(
 'type' => 'system',
 'label' => t('Beep annoyingly'), // Противно гудит
 'configurable' => FALSE,
 'triggers' => array('node_view', 'node_insert', 'node_update', 'node_delete'),
 ),
 );
}

Функция называется beep_action_info(), поскольку, как и другие реализации хуков, для этого используется имя модуля (beep) с добавлением имени хука (action_info). Функция возвращает массив с элементами для каждого действия в модуле. Поскольку мы пишем лишь одно действие, в этом массиве будет только один элемент с ключом, содержащим имя функции, которая выполняет действие: beep_beep_action(). При чтении кода лучше сразу видеть, что функция представляет собой действие, поэтому к имени функции добавлен суффикс _action — в результате получилось beep_beep_action(). Рассмотрим внимательнее ключи в нашем массиве.

  • type. Указывает на вид создаваемого действия. Drupal использует эту информацию для разбивки действий по категориям в раскрывающемся списке выбора, который находится в пользовательском интерфейсе назначения триггера. К возможным типам относятся system (система), node (нода), user (пользователь), comment (комментарий) и taxonomy (таксономия). При определении типа создаваемого действия удобно задать вопрос: “С каким объектом работает это действие?” (Если ответ неочевиден или объекты могут быть различными, используйте тип system.)
  • label. Это дружественное имя действия, отображаемое в раскрывающемся списке выбора, который находится в пользовательском интерфейсе назначения триггера.
  • configurable. Указывает, принимает ли действие параметры.
  • triggers. В массиве хуков каждый элемент должен перечислять операции, поддерживаемые действием. Drupal использует эту информацию для определения, стоит ли перечислять все возможные действия в пользовательском интерфейсе назначения триггера.

После описания нашего действия его можно реализовать:

/**
* Действие Drupal — имитация гудка.
*/
function beep_beep_action() {
beep_beep();
}

Совсем не трудно, так ведь? Прежде чем продолжить, удалите реализации beep_user() и beep_nodeapi(), поскольку мы будем использовать триггеры и действия, а не непосредственные реализации хуков.

Назначение действия

Теперь щелкните на ссылке Structure (Структура) в верхнем меню, а затем на странице Structure щелкните на ссылке Triggers (Триггеры). Если все сделано правильно, ваше действие должно быть доступно в пользовательском интерфейсе, как показано на рис. 3.2.

Назначьте действие триггеру, связанному с сохранением нового контента, для чего выберите пункт Beep annoyingly (Противно гудит) в раскрывающемся списке и щелкните на кнопке Assign (Назначить). После этого создайте новый элемент контента типа Basic page (Базовая страница) и сохраните его. После сохранения щелкните на ссылке Reports (Отчеты) в верхней части страницы и выберите отчет Recent log entries (Последние записи в журнале). Если вы правильно создали и настроили действие и триггер, должны появиться результаты, подобные приведенным на рис. 3.3.

Изменение триггеров, поддерживаемых действием

При изменении значений, которые определяют операции, поддерживаемые данным действием, это изменение должно отразиться и в пользовательском интерфейсе. Например, если модифицировать код beep_action_info() так, как описано ниже, действие Beep будет доступно лишь триггеру After deleting a node (После удаления ноды):

/**
* Реализация hook_action_info().
*/
function beep_action_info() {
 return array(
 'beep_beep_action' => array(
 'type' => 'system',
 'label' => t('Beep annoyingly'), // Противно гудит
 'configurable' => FALSE,
 'triggers' => array('node_delete'),
 ),
 );
}

Действия, поддерживающие любые триггеры

Если вы не хотите ограничить свое действие каким-то конкретным триггером или набором триггеров, можете объявить, что данное действие поддерживает любые триггеры:

/**
* Реализация hook_action_info().
*/
function beep_action_info() {
return array(
'beep_beep_action' => array(
 'type' => 'system',
 'label' => t('Beep annoyingly'), // Противно гудит
 'configurable' => FALSE,
 'triggers' => array('any'),
 ),
 );
}

Расширенные действия

По сути, действия бывают двух видов: действия, принимающие параметры, и действия, которые параметров не принимают. Действие Beep, с которым мы работаем, не принимает параметров. При выполнении это действие выдает один звуковой сигнал, и все. Но зачастую действия должны быть несколько более специализированными. Например, действие Send e-mail (Отправить почтовое сообщение) должно знать адресата, тему и текст сообщения. Такие действия требуют некоторой настройки с помощью формы конфигурирования и называются расширенными (advanced) или конфигурируемыми (configurable) действиями.

Простые действия не принимают параметров, не требуют наличия формы конфигурирования и автоматически доступны системе. Чтобы сообщить Drupal, что создаваемое действие является расширенным, в реализации функции hook_action_info() понадобится установить ключ configurable в TRUE, построить форму для конфигурирования действия и создать необязательный обработчик проверки достоверности и обязательный обработчик отправки данных из формы конфигурирования. Различия между простым и расширенным действием представлены в табл. 3.3.

Таблица 3.3. Сводка различий простых и расширенных действий

  Простое действие Расширенное действие
Параметры Нет* Требуются
Форма конфигурирования Нет Требуется
Доступность Автоматически Необходимо создание экземпляра действия с помощью страницы администрирования действий
Значение ключа configure в hook_action_info() FALSE TRUE
* При необходимости доступны параметры $object и $context

Давайте создадим расширенное действие, которое будет выдавать звуковой сигнал несколько раз. Конкретное количество гудков можно будет указывать с помощью формы конфигурирования. Сначала понадобится указать Drupal, что это действие является конфигурируемым. Добавим в реализацию хука action_info в модуле beep.module элемент для нового действия:

/**
* Реализация hook_action_info().
*/
function beep_action_info() {
 return array(
 'beep_beep_action' => array(
 'type' => 'system',
 'label' => t('Beep annoyingly'), // Противно гудит
 'configurable' => FALSE,
 'triggers' => array('node_view', 'node_insert', 'node_update', 'node_delete'),
 ),
 'beep_multiple_beep_action' => array(
 'type' => 'system',
 'label' => t('Beep multiple times'), // Гудит несколько раз
 'configurable' => TRUE,
 'triggers' => array('node_view', 'node_insert', 'node_update', 'node_delete'),
 ),
 );
}

Быстро проверим, все ли правильно сделано — для этого нужно выбрать пункт меню Administer Site configuration Actions (Администрирование -> Настройка сайта -> Действия). Наше действие должно появиться в раскрывающемся списке расширенных действий, как показано на рис. 3.4.

Теперь необходимо предоставить форму, в которой администратор сможет указать нужное количество звуковых сигналов. Для этого нужно определить одну или несколько форм с помощью API форм системы Drupal. Кроме того, понадобится написать функции для проверки форм и отправляемых данных. Имена этих функций основаны на идентификаторе действия, определенном в функции hook_action_info(). Для нашего действия идентификатор имеет вид beep_multiple_beep_action, и по соглашению к имени функции определения формы должно быть добавлено _form — получится beep_multiple_beep_action_form. В Drupal принято, что имя функции проверки образуется из идентификатора действия с добавлением суффикса _validate (beep_multiple_beep_action_validate), а имя функции отправки — с добавлением суффикса _submit (beep_multiple_beep_action_submit).

/**
* Форма для конфигурируемого действия Drupal — выдачи нескольких звуковых сигналов.
*/
function beep_multiple_beep_action_form($context) {
 $form['beeps'] = array(
 '#type' => 'textfield',
 '#title' => t('Number of beeps'), // Количество гудков
 '#description' => t('Enter the number of times to beep when this action executes'),
 // Введите количество гудков при выполнении этого действия
 '#default_value' => isset($context['beeps']) ? $context['beeps'] : '1',
 '#required' => TRUE,
 );
 return $form;
}

function beep_multiple_beep_action_validate($form, $form_state) {
 $beeps = $form_state['values']['beeps'];
 if (!is_int($beeps)) {
 form_set_error('beeps', t('Please enter a whole number between 0 and 10.'));
 // Введите целое число от 0 до 10.
 }
 else if ((int) $beeps > 10 ) {
 form_set_error('beeps', t('That would be too annoying. Please choose fewer than 10 beeps.'));
 // Это будет слишком занудно. Укажите менее 10 сигналов.
 } else if ((int) $beeps < 0) {
 form_set_error('beeps', t('That would likely create a black hole! Beeps must be a positive integer.'));
 // Решили создать черную дыру?
 // Количество должно быть положительным целым числом.
 }
}

function beep_multiple_beep_action_submit($form, $form_state) {
 return array(
 'beeps' => (int)$form_state['values']['beeps']
 );
}

Первая функция создает описание формы для Drupal. В ней определено единственное текстовое поле, в котором администратор может вводить количество гудков. Чтобы открыть форму расширенного действия, щелкните на ссылке Configuration (Настройка) в верхней части страницы, а на открывшейся странице Configuration щелкните на ссылке Actions (Действия). Внизу страницы Actions откройте список выбора Create an Advanced action (Создать расширенное действие) и щелкните на пункте Beep multiple times (Гудит несколько раз). После выбора этого пункта Drupal отобразит форму настройки расширенного действия, показанную на рис. 3.5.

В форму настройки действия среда Drupal добавила поле Description (Описание). Текст в этом поле можно изменить и использовать вместо стандартного описания, определенного в хуке action_info. Такие описания могут пригодиться в случаях, когда создается одно расширенное действие с двумя звуковыми сигналами и описанием “Два гудка” и другое действие с пятью звуковыми сигналами и описанием “Пять гудков”. Это позволяет различить два расширенных действия при их назначении триггеру. То есть расширенные действия можно снабжать описаниями, понятными администратору.

Совет. Эти два действия — “Два гудка” и “Пять гудков” — можно назвать экземплярами действия “Несколько гудков”.

Функция проверки достоверности ничем не отличается от других функций проверки форм в Drupal (подробно о проверке форм рассказывается в главе 10). В нашем случае нужно просто проверить, что пользователь действительно ввел число, и это число не слишком велико. Значение, возвращаемое функцией отправки данных для форм конфигурирования действий, имеет специальный вид. Оно должно быть массивом с ключами, содержащими имена необходимых полей. Значения в этом массиве доступны при выполнении действия. Описание обрабатывается автоматически, поэтому нужно только возвратить значение из введенного нами поля — т.е. количество звуковых сигналов. Ну, наконец, пришло время написать само расширенное действие:

/**
* Конфигурируемое действие. Воспроизводит указанное количество гудков.
*/
function beep_multiple_beep_action($object, $context) {
for ($i = 1; $i < $context['beeps']; $i++) {
beep_beep();
}
}

Это действие принимает два параметра — $object и $context. В простом действии, которое было написано нами ранее, параметров не было.

На заметку! Простые действия могут принимать такие же параметры, как и конфигурируемые действия. Поскольку PHP игнорирует параметры, которые передаются функции, но отсутствуют в сигнатуре функции, можно просто заменить сигнатуру нашего простого действия beep_beep_action() на beep_beep_action($object, $context), и тогда можно будет кое-что узнать о текущем контексте. Все действия вызываются с параметрами $object и $context.
Всего комментариев: 0
Имя *:
Email *:
Код *:


Бесплатный конструктор сайтов - uCoz