В этой статье расскажу о программном использовании cron в Drupal 7. Cron позволяет выполнять запланированные действия через определенный промежуток времени. Тем самым снижается разовая нагрузка сайт. В качестве приведу пример модуля, который позволяет изменять слова в тексте на их синонимы. Для этого модуль с помощью cron, будет обращаться к сайту seogenerator.ru. Данный способ активно применяется в SEO для уникализации текста. Лично я не являюсь сторонником данного метода. Считаю что, материал не должен быть сворован и оптимизирован под SEO. Такие сайты никогда не будут пользоваться популярностью.
Создадим директорию seogenerator для будущего модуля. Добавим информацию о модуле в файл seogenerator.info.
name = SeoGeneratordescription = SeoGeneratorcore = 7.xconfigure = admin/config/content/seogenerator
Добавим функцию, которая будет отвечать за создание таблицы в базе данных. В этой таблице будем хранить информацию об узлах, которые прошли обработку с помощью нашего модуля.
/*** hook_schema().*/function seogenerator_schema() {$schema['seogenerator'] = array('description' => 'SeoGenerator','fields' => array('nid' => array('type' => 'int','unsigned' => TRUE,'not null' => TRUE,'default' => 0,'description' => "{node}.nid.",),),'primary key' => array('nid'),);return $schema;}
Добавим функцию для удаления модуля из Drupal.
/*** hook_uninstall().*/function seogenerator_uninstall() {db_delete('variable')->condition('name', 'seogenerator_%', 'LIKE')->execute();cache_clear_all('variables', 'cache_bootstrap');}
Добавим страницу для настройки нашего модуля.
/*** hook_menu().*/function seogenerator_menu() {$items['admin/config/content/seogenerator'] = array('title' => 'SeoGenerator','description' => 'Настройки SeoGenerator','page callback' => 'drupal_get_form','page arguments' => array('seogenerator_settings'),'access arguments' => array('administer seogenerator'),);return $items;}function seogenerator_settings() {...}
Добавим поле типа переключатель, которое позволит включить / выключить модуль.
$form['seogenerator_enable'] = array('#type' => 'checkbox','#title' => t('Включить SeoGenerator'),'#default_value' => variable_get('seogenerator_enable', 0),);
Добавим группу независимых переключателей для выбора типа материала, для которого будем применять наш модуль. Функция node_type_get_names позволяет поличить список всех типов материала.
$form['seogenerator_node_types'] = array('#type' => 'checkboxes','#title' => t('Типы материалов'),'#options' => node_type_get_names(),'#default_value' => variable_get('seogenerator_node_types', array()),);
Функционал сайта позволяет использовать несколько баз синонимов для генерации текста. Позволим пользователям выбирать из какой базы генерировать текст. Добавим список зависимых переключателей для выбора.
$form['seogenerator_base'] = array('#type' => 'radios','#title' => t('База синонимов'),'#default_value' => variable_get('seogenerator_base', 0),'#options' => array(0 => 'Big one', 1 => 'Small one', 2 => 'Small two'),'#description' => t('Используемая база синонимов для генерации текста.'),);
Также функционал сайта позволяет выбрать метод подстановки символов. Обеспечим для пользоватлей возможность выбора. Добавим список зависимых переключателей для выбора.
$form['seogenerator_type'] = array('#type' => 'radios','#title' => t('Метод подстановки'),'#default_value' => variable_get('seogenerator_type', 0),'#options' => array(0 => 'Первый', 1 => 'Случайный'),'#description' => t('Метод подстановки синонимов (первый или случайный).'),);
Добавим стандартные кнопки и обработчик результатов заполнения формы.
return system_settings_form($form);Определим права доступа к странице настройки модуля.
/*** hook_permission().*/function seogenerator_permission() {return array('administer seogenerator' => array('title' => t('Администратирование SeoGenerator'),'description' => t('Изменение настроек модуля SeoGenerator.'),),);}
Для определения новой задачи cron существует хук hook_cron_queue_info. В параметре worker callback указываем какая функция будет вызываться при выполнении cron. Параметр time определяет время выполнения функции.
/*** hook_cron_queue_info()*/function seogenerator_cron_queue_info() {$queues['seogenerator'] = array('worker callback' => '_seogenerator_update','time' => 5,);return $queues;}
Функция выполняет запросы на сайт и заменяет заголовок узла и его содержимое на сгенерированный текст. Сайт позволяет за один раз генерировать только 6 тысяч символов. Поэтому разбираем текст на части.
В завершении добавляет запись в базу данных об уникализации нашего материала.
function _seogenerator_update($node) {watchdog('seogenerator', $node->nid, array(), WATCHDOG_INFO);$node = node_load($node->nid);$node->title = _seogenerator_query($node->title);$body = $node->body['und'][0]['value'];$elements = str_split($body, 6000);$node->body['und'][0]['value'] = '';foreach ($elements as $element) {$body = _seogenerator_query($element);$node->body['und'][0]['value'] .= $body;}node_save($node);db_insert('seogenerator')->fields(array('nid' => $node->nid))->execute();}
Функция для выполнения запроса с помощью cURL на сайт seogenerator.ru. Отправляем параметры для генератора текста и получаем ответ.
function _seogenerator_query($text) {$params = array();$params['text'] = $text;$params['base'] = variable_get('seogenerator_base', 0);$params['type'] = variable_get('seogenerator_type', 0);$params['format'] = 'text';$curl = curl_init();curl_setopt($curl, CURLOPT_URL, 'http://seogenerator.ru/api/synonym/');curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, $params);curl_setopt($curl, CURLOPT_HEADER,0);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);$result = curl_exec($curl);curl_close($curl);return $result == 'Exceeded the limit queries from this IP address'? $text : $result;}
Для перехвата cron используем хук hook_cron.
/*** hook_cron()*/function seogenerator_cron() {if (variable_get('seogenerator_enable', 0)) {...}}
Выполняем запрос в базу данных и получаем список id узлов, которые отсутствуют в нашем списке обработанных узлов. Для этого формируем запрос в базу данных.
$nodes = db_select('node', 'n');$nodes->leftJoin('seogenerator', 's', 'n.nid = s.nid');$nodes = $nodes->fields('n', array('nid'))->range(0, 5)->condition('n.type', _seogenerator_get_selected_node_types())->isNull('s.nid')->execute()->fetchAll();
Добавляем элементы для выполнения нашей задачи, с помощью cron. Для этого в Drupal 7 предназначен объект DrupalQueue. Метод get устанавливает задачу. Как добавить новую задачу было рассказано выше. Используя метод createItem мы можем добавить новый элемент к нашей задачи. Параметры этого метода передаются функции, которая была установлена для задачи cron.
$queue = DrupalQueue::get('seogenerator');foreach($nodes as $node) {$queue->createItem($node);}