Эта статья - дополненный перевод статьи How to Create Joomla Task Scheduler Plugin.
В Joomla! появился планировщик задач начиная с версии 4.1. Он помогает автоматизировать повторяющиеся и рутинные задачи самого широкого спектра, начиная от технического обслуживания и заканчивая сложными синхронизациями по API.
Планировщик задач запускает задачу, определенную в плагине, с помощью задания CRON.
Задания CRON (CRON Job): Задание CRON используется для автоматизации повторяющихся задач. Например, для обработки очередей электронной почты, для синхронизации заказов или остатков товаров, обновления цен интернет-магазина, для проверки веб-сайта на наличие проблем и так далее.
Также о технологии WebCron в Joomla 4.1 сообщалось в обзоре Новое в Joomla 4.1 на Хабре, в разделе "WebCron в Joomla 4.1".
Плагин планировщика задач Joomla 4 (Task Scheduler)
Это стандартный Joomla! плагин с group="task"
. В нём необходимо использовать TaskPluginTrait
.
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\Scheduler\Administrator\Event\ExecuteTaskEvent;
use Joomla\Component\Scheduler\Administrator\Task\Status;
use Joomla\Component\Scheduler\Administrator\Task\Task;
use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait;
use Joomla\Event\SubscriberInterface;
class PlgTaskExample extends CMSPlugin implements SubscriberInterface
{
use TaskPluginTrait;
protected const TASKS_MAP = array(
'plg_task_do_example' => array(
'langConstPrefix' => 'PLG_TASK_DO_EXAMPLE',
'method' => 'doExample',
'form' => 'do_example'
)
);
protected $autoloadLanguage = true;
protected $app;
protected $db;
public static function getSubscribedEvents(): array
{
return array(
'onTaskOptionsList' => 'advertiseRoutines',
'onExecuteTask' => 'standardRoutineHandler',
'onContentPrepareForm' => 'enhanceTaskItemForm',
);
}
private function doExample(ExecuteTaskEvent $event): int
{
// Code for Tasks
return Status::OK;
}
}
Реализация
Плагин планировщика задач в Joomla 4 должен использовать TaskPluginTrait
и определять методы, соответствующие каждой процедуре вместе с константой класса TASKS_MAP
для объявления поддерживаемых процедур и связанных с ними свойств. TaskPluginTrait
включает в себя стандартные методы для трансляции процедур (routines), улучшения форм задач и вызов подзадач.
advertiseRoutines()
Этот метод объявляет процедуры, поддерживаемые плагином. Он должен быть сопоставлен с событием onTaskOptionsList
, позволяющим плагину объявлять свои процедуры. Метод уже определен в трейте, поэтому Вам не требуется определять его в вашем плагине.
enhanceTaskItemForm()
Этот метод расширяет форму задачи из XML-файла плагина, объявленного с помощью константы TASKS_MAP
. Этот метод может быть сопоставлен с событием onContentPrepareForm
. Этот метод уже определен в трейте, поэтому вам не требуется определять его в вашем плагине.
Вам нужно добавить имя формы в TASKS_MAP
и константу и создать XML-форму в папке forms
плагина с тем же именем.
standardRoutineHandler()
Метод сопоставляет стандартные процедуры задачи с методами класса. Вы можете добавить имя метода в константу TASKS_MAP
и определить его в своем плагине. Выполняться метод будет при запуске задачи.
Этот метод должен быть сопоставлен с событием onExecuteTask
. Ожидается, что эти методы будут принимать один аргумент (событие) и возвращать статус задачи в виде числа (integer).
logTask()
Этот метод добавляет сообщение в логи. Первый аргумент - это сообщение, а второй аргумент - приоритет: отладка, ошибка, предупреждение, уведомление, информация:
- debug
- error
- info
- notice
- warning
$this->logTask('Task is being executed', 'info');
Основной метод для выполнения задачи (doExample)
В примере выше это метод doExample.
use Joomla\Component\Scheduler\Administrator\Event\ExecuteTaskEvent;
use Joomla\Component\Scheduler\Administrator\Task\Status;
/**
* Standard routine method for the get request routine.
*
* @param ExecuteTaskEvent $event The onExecuteTask event
*
* @return integer The exit code
*
* @since 4.1.0
* @throws Exception
*/
private function doExample(ExecuteTaskEvent $event): int
{
// Code for Tasks
return Status::OK;
}
В качестве параметра он принимает объект события onExecuteTask
. Для выполнения задачи нам могут понадобится параметры, указанные в настройках плагина задачи. Получить параметры плагина можно с помощью метода $event->getArgument('params')
$id = $event->getTaskId();
// Получаем параметры плагина, указанные в настройках
$params = $event->getArgument('params');
$url = $params->url;
$timeout = $params->timeout;
$auth = (string) $params->auth ?? 0;
$authType = (string) $params->authType ?? '';
$authKey = (string) $params->authKey ?? '';
По завершении работы основного метода он должен вернуть статус выхода задачи.
Статусы выхода задачи в Joomla
На данный момент в Joomla 4 существует 12 возможных статусов завершения задачи, которым назначены числовые значения.
INVALID_EXIT
= -2: используется, когда процедура возвращает неверный (не целочисленное, non-integer) статус завершения задачи.NO_EXIT
= -1: используется, когда процедура не возвращает статус завершения задачи.RUNNING
= 1: Используется при старте задачи. Это значение не должно быть статусом завершения задачи.NO_LOCK
= 2: Используется при невозможности полученияpseudo-lock
.NO_RUN
= 3: Используется при ошибке запуска задачи.NO_RELEASE
= 4: Используется при невозможности снять блокировку или обновить запись.KNOCKOUT
= 5: Используется, когда процедура "валится" из-за выкинутых исключений (Exception).WILL_RESUME
= 123: Используется, когда необходимо возобновить выполнение задачи. Используйте это для длительных задач, чтобы разделить их на более мелкие пакеты. Когда будет выполнен последний пакет, вернитеStatus::OK
.TIMEOUT
= 124: Используется в случае таймаута задачи.NO_TASK
= 125: Используется в случае, если задача не обнаружена.NO_ROUTINE
= 127: Используется в случае, если процедура задачи не обнаружена.OK
= 0: Успешное завершение задачи.
Пример из кода плагина Задача - GET-запрос
use Joomla\Component\Scheduler\Administrator\Task\Status as TaskStatus;
protected function makeGetRequest(ExecuteTaskEvent $event): int
{
...
try
{
$response = HttpFactory::getHttp($options)->get($url, $headers, $timeout);
}
catch (Exception $e)
{
$this->logTask(Text::sprintf('PLG_TASK_REQUESTS_TASK_GET_REQUEST_LOG_TIMEOUT'));
return TaskStatus::TIMEOUT;
}
...
$this->logTask(Text::sprintf('PLG_TASK_REQUESTS_TASK_GET_REQUEST_LOG_RESPONSE', $responseCode));
if ($response->code !== 200)
{
return TaskStatus::KNOCKOUT;
}
return TaskStatus::OK;
}