20 декабря 2015

Создание своего события для модуля Rules в Drupal 7

Евгений Тристамов
Разработчик

С помощью модуля Rules можно реагировать на различные события на сайте. Добавлять какие-то действия, которые выполняются после, например, запуска крона, создания материала, добавления комментария, регистрации пользователя и множества других событий.

Функционал Rules даёт возможность самостоятельно продумывать события из различных условий. И к этим событиям можно прикреплять различные действия. Например, отправку e-mail, запуск скрипта, пересохранение материала и так далее.

Установка модулей

Установим модуль через Drush:

drush dl rules && drush en -y rules_admin

Для работы нам потребуется включить Rules и Rules Admin

Модуль Rules зависит от модуля Entity, его также необходимо скачать и установить.

Страница правил находится по адресу admin/config/workflow/rules — там вы увидите уже созданные правила и сможете добавить новые.

Собственное событие

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

Для создания своего события, нужно создать модуль. Назовём его azimut7_rules. В нём будут элементы для модуля Rules и он должен быть зависим от него.

Содержимое файла azimut7_rules.info:

name = Azimut7 rules.
description = Custom rules events.
core=7.x
version = "7.x-1.0"
project = "azimut7_rules"
dependencies[] = rules

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

azimut7_rules.module:

function azimut7_rules_node_insert($node) {
  dpm($node);
}

Не забудьте включить модуль.

Я попробовал создать материал и увидел вывод своего отладочного сообщения. Это говорит о том, что хук работает. Давайте напишем требуемую проверку.

Напишем функцию:

function azimut7_rules_node_insert($node) {
  global $user;
  $time = strtotime('-1 day');
  $node_count = db_select('node', 'n')
    ->fields('n', array('nid'))
    ->condition('n.uid', $user->uid)
    ->condition('n.created', $time, '>')
    ->execute()
    ->rowCount();
  dpm($node_count);
}

Таким запросом мы найдем количество материалов, созданных текущим пользователем за последние 24 часа. Создаваемый материал тоже входит в эту цифру. Попробуйте создать материал и увидите искомое значение.

Теперь нужно создать само событие. Для этого создадим файл с именем azimut7_rules.rules.inc и объявим в нём событие:

function azimut7_rules_rules_event_info() {
  $items = array(
    'azimut7_rules_created_node_count' => array(
      'label' => t('Count of last user nodes'),
      'category' => 'node',
    ),
  );
  return $items;
}

Чтобы Друпал узнал об этом событии, нужно добавить в info указание об этом файле:

name = Azimut7 rules.
description = Custom rules events.
core=7.x
version = "7.x-1.0"
files[] = azimut7_rules.rules.inc
project = "azimut7_rules"
dependencies[] = rules

Не забудьте очистить кэш сайта.

Теперь можно вызвать созданное событие из нашего первого хука:

function azimut7_rules_node_insert($node) {
  global $user;
  $time = strtotime('-1 day');
  $node_count = db_select('node', 'n')
    ->fields('n', array('nid'))
    ->condition('n.uid', $user->uid)
    ->condition('n.created', $time, '>')
    ->execute()
    ->rowCount();
  if ($node_count >= 3) {
    rules_invoke_event('azimut7_rules_created_node_count');
  }
}

На этом написание кода закончено и теперь можно создать правило.

Переходим на admin/config/workflow/rules/reaction/add. На странице будет наше созданное событие. Выбираем его:

Нужно заполнить поле с названием правила, можно добавить тэг:

Теперь добавим действие для этого события, например, вывод сообщения. Нажимаем Add action и выбираем вывод сообщения:

Пишем текст сообщения и нажимаем Сохранить.

Теперь правило готово. Можно перейти к списку всех правил и увидеть наше правило:

Создадим ноды и проверим работоспособность правила. Я создал уже более трёх нод и вижу своё сообщение: