
Интеграция с Scheduler
MiniShop3 выполняет фоновые задачи через компонент Scheduler.
Требования
Scheduler 1.8.0 или выше. На более ранних версиях задачи работают, но повторяющиеся не перезапускаются автоматически.
Включение интеграции
- Установите компонент Scheduler и настройте для него cron — см. Установка и настройка запуска.
- Включите настройку
ms3_use_scheduler: Система → Системные настройки → minishop3.
Настройка управляет только уведомлениями
ms3_use_scheduler читается в единственном месте — при решении, отправить уведомление сразу или поставить в очередь. На остальные задачи она не влияет:
- уведомления уходят в фон только при включённой настройке и установленном Scheduler;
- импорт ставится в фон галочкой в форме импорта, независимо от настройки;
- очистка токенов и черновиков выполняется по расписанию с момента установки MiniShop3, настройка её не включает и не выключает.
Программно настройку меняют через объект modSystemSetting:
$setting = $modx->getObject(\MODX\Revolution\modSystemSetting::class, 'ms3_use_scheduler');
$setting->set('value', 1);
$setting->save();setOption() настройку не сохраняет
$modx->setOption('ms3_use_scheduler', true) меняет значение только в памяти текущего запроса — в базу не попадает ничего. Задачи Scheduler выполняются отдельным процессом по cron и такого значения не увидят.
Встроенные задачи
MiniShop3 регистрирует при установке четыре задачи:
| Задача | Тип | Интервал | Файл |
|---|---|---|---|
ms3_cleanup_tokens | повторяющаяся | +1 week | elements/tasks/cleanupTokens.php |
ms3_cleanup_drafts | повторяющаяся | +1 day | elements/tasks/cleanupDrafts.php |
ms3_csv_import | одноразовая | — | elements/tasks/csvImport.php |
ms3_send_notification | одноразовая | — | elements/tasks/sendNotification.php |
Интервал — это строка для функции PHP strtotime(), она хранится в поле interval задачи как есть. После успешного запуска Scheduler передаёт её в strtotime() и планирует следующий запуск. Если строка не разбирается или даёт время в прошлом, в MODX Error Log попадает Invalid interval, и повторяющаяся задача больше не планируется.
ms3_cleanup_tokens
Удаляет записи с истёкшим сроком действия из таблицы токенов авторизации покупателей ms3_customer_tokens.
ms3_cleanup_drafts
Удаляет заказы со статусом «Черновик», созданные раньше периода из настройки ms3_delete_drafts_after.
Период задаётся любой строкой, понятной функции PHP strtotime(): -1 day, -2 weeks, -1 month, -1 year. Пустое значение (так поставляется по умолчанию) отключает автоудаление.
$setting = $modx->getObject(\MODX\Revolution\modSystemSetting::class, 'ms3_delete_drafts_after');
$setting->set('value', '-2 weeks');
$setting->save();ms3_csv_import
Импортирует товары из CSV. Режим выбирает человек: в форме импорта есть переключатель «синхронно или в фоне», и фоновый режим ставит задачу в очередь Scheduler.
Настройка ms3_import_sync_limit (по умолчанию 300 строк) на выбор не влияет напрямую: когда в файле строк больше, форма показывает переключатель режима, а если Scheduler не установлен — предупреждение, что файл велик для синхронного прохода. Сам импорт в очередь не уходит, пока переключатель не выставлен.
Передаваемые параметры:
$scriptProperties = [
'file' => 'path/to/file.csv', // Путь к файлу относительно MODX_BASE_PATH
'mapping' => [...], // Соответствие колонок полям товара
'fields' => [...], // Прежний формат соответствия, для совместимости
'update' => false, // Обновлять существующие товары
'key' => 'article', // Поле, по которому ищется существующий товар
'delimiter' => ';', // Разделитель колонок
'skip_header' => false, // Пропустить первую строку
'debug' => false, // Подробный лог вместо записи в базу
'import_id' => 'import_...', // Идентификатор прогона, ставится процессором
];ms3_send_notification
Отправляет уведомления, не блокируя основной запрос. Полезно для медленных каналов — например, для Telegram.
Уведомление уходит в очередь, когда выполнены оба условия: настройка ms3_use_scheduler включена и сервис scheduler зарегистрирован. Иначе уведомление отправляется сразу, в том же запросе. Задержка берётся из настроек самого уведомления (поле «Задержка» для статуса и типа получателя); при нулевой задержке запуск ставится на +1 second.
Передаваемые параметры:
$scriptProperties = [
'notification_class' => 'MiniShop3\Notifications\Order\StatusChangedNotification',
'order_id' => 123,
'channel' => 'telegram', // имя канала: email или telegram
'recipient_type' => 'manager', // customer или manager
'recipient' => [...], // данные получателя для канала
'notification_data' => [...], // снимок данных уведомления
];Задача восстанавливает уведомление по имени класса. Для StatusChangedNotification она берёт идентификаторы статусов из notification_data (new_status.id, old_status.id) и заново загружает объекты статусов; если нового статуса нет в базе, запуск завершается ошибкой.
Каналы. В поставке зарегистрированы два: email и telegram. Класс SmsChannel в коде есть, но сам не подключается — свой канал регистрируют плагином на событие msOnRegisterNotificationChannels, которому приходит параметр manager:
$manager = $modx->getOption('manager', $scriptProperties);
$manager->registerChannel(new \MyPackage\Notifications\SmsChannel($modx));Мониторинг задач
Через админку
Дополнения → Scheduler — три вкладки: «Задания» (зарегистрированные задачи), «Запланированные запуски» и «Прошедшие запуски».
Через API
У задачи нет метода, отдающего последний запуск, — запуски читаются запросом к sTaskRun:
/** @var \Scheduler $scheduler */
$scheduler = $modx->services->get('scheduler');
$task = $scheduler->getTask('minishop3', 'ms3_cleanup_tokens');
$c = $modx->newQuery('sTaskRun');
$c->where(['task' => $task->get('id')]);
$c->sortby('executedon', 'DESC');
$c->limit(1);
/** @var \sTaskRun|null $lastRun */
$lastRun = $modx->getObject('sTaskRun', $c);
if ($lastRun) {
echo $lastRun->get('status'); // 0 ждёт, 1 выполняется, 2 успех, 3 ошибка
echo $lastRun->get('executedon'); // метка времени запуска
echo $lastRun->get('processing_time'); // длительность в секундах
echo $lastRun->get('message'); // сообщение задачи
if ($lastRun->hasErrors()) {
print_r($lastRun->get('errors'));
}
}Числа статуса соответствуют константам sTaskRun::STATUS_SCHEDULED, STATUS_EXECUTING, STATUS_SUCCESS и STATUS_FAILURE.
Ручной запуск задач
Через админку
- Откройте Дополнения → Scheduler → Задания.
- Найдите задачу (namespace: minishop3).
- В контекстном меню выберите Запланировать запуск.
Запуск встанет в очередь. Один проход cron берёт столько запусков, сколько указано в настройке Scheduler scheduler.tasks_per_run — по умолчанию один, поэтому при непустой очереди запуск может подождать несколько проходов.
Через PHP
/** @var \Scheduler $scheduler */
$scheduler = $modx->services->get('scheduler');
// Получить задачу
$task = $scheduler->getTask('minishop3', 'ms3_cleanup_tokens');
// Поставить в очередь — задачу подхватит ближайший запуск cron
$task->schedule('+1 minute');
// Для задач с параметрами они передаются вторым аргументом
$task->schedule('+1 minute', ['import_id' => 'import_123']);Синхронного запуска у задачи нет: schedule() только ставит запуск в очередь, а выполняет его cron-скрипт Scheduler.
Создание собственных задач
Типы задач, передача данных и правила возврата результата описаны в документации Scheduler: Создание задания и Разработка заданий. Ниже — только то, что касается задач рядом с MiniShop3.
Регистрация задачи
/** @var \Scheduler $scheduler */
$scheduler = $modx->services->get('scheduler');
// Создать задачу
$task = $modx->newObject('sTask');
$task->fromArray([
'class_key' => 'sFileTask',
'namespace' => 'mypackage',
'reference' => 'my_custom_task',
'content' => 'elements/tasks/myTask.php', // Относительно core-пути namespace
'description' => 'My custom MiniShop3 task',
'recurring' => true,
'interval' => '+1 hour',
]);
$task->save();
// Запланировать первый запуск
$task->schedule('+1 minute');Файл задачи
Scheduler подключает файл через include и даёт в нём четыре переменные: $modx, $task, $run и $scriptProperties (данные из второго аргумента schedule()). Возвращённое значение попадает в результат запуска.
<?php
/**
* @var modX $modx
* @var sFileTask $task
* @var sTaskRun $run
* @var array $scriptProperties
*/
// Получение сервиса MiniShop3
$ms3 = $modx->services->get('ms3');
// Ваша логика
try {
// ... выполнение задачи ...
$modx->log(modX::LOG_LEVEL_INFO, "[myTask] Completed successfully");
return true;
} catch (\Exception $e) {
$run->addError('exception', ['error' => $e->getMessage()]);
return false;
}Первый аргумент addError() — тип ошибки, подробности передаются массивом вторым аргументом. Именно этот вызов решает судьбу запуска: запуск получает статус «ошибка», если в нём есть хотя бы одна запись об ошибке. Возврат false сам по себе статус не меняет — возвращённое значение попадает в поле message. Подробнее — Регистрация ошибок в Scheduler.
Связанные настройки
| Настройка | По умолчанию | Описание |
|---|---|---|
ms3_use_scheduler | false | Отправлять уведомления через очередь Scheduler |
ms3_delete_drafts_after | пусто | Период хранения черновиков, формат strtotime() |
ms3_import_sync_limit | 300 | Число строк, после которого форма импорта предлагает фоновый режим |
Со стороны Scheduler на поведение задач влияют scheduler.tasks_per_run, scheduler.recurring_on_failure и настройки писем о сбоях.
Устранение проблем
Задачи не выполняются
Проверьте:
- настроен ли cron для Scheduler — как его настроить;
- читает ли веб-сервер файлы задач;
- что пишет Scheduler в MODX Error Log.
Если очередь длинная, запуск ждёт своего прохода: по умолчанию cron берёт одну задачу за раз (scheduler.tasks_per_run).
Повторяющиеся задачи не перезапускаются
Чаще всего причина в том, что прошлый запуск завершился с ошибкой: следующий запуск после неудачи не планируется, в лог идёт stopped due to failure. Чтобы цикл продолжался и после ошибок, включите настройку Scheduler scheduler.recurring_on_failure — по умолчанию она выключена.
Остальное, что стоит проверить:
- версию Scheduler — нужна 1.8.0 или выше;
- поле
recurringв настройках задачи; - значение
interval— строка, которую не разбираетstrtotime(), даётInvalid intervalи останавливает цикл.
Ошибки в задачах
Логи задач:
- MODX Error Log (
core/cache/logs/error.log); - вкладка «Прошедшие запуски» в Scheduler — у каждого запуска видны сообщение и список ошибок.
Записи об ошибках хранятся в поле errors запуска: это массив, где у каждой записи есть type (первый аргумент addError()), timestamp и переданные подробности.
