Загрузка...

Пример работы с cron-bundle в Symfony

Пример запланированной отправки письма с помощью cron-bundle в Symfony


Такое решение имеет место быть, но всё же возможно лучше использовать брокеры сообщений, чем завязываться на крон

Покажу простой пример отложенного действия на сервере, которое должно произойти однажды, то есть при наступлении интересующей даты с использованием этого пакета. Допустим есть письмо (у него еще может быть куча полей, такие как контент, вложение и т. д.), которое составил пользователь, у него есть дата отправки, когда эта дата наступает, письмо автоматически отправляется. С точки зрения кода есть сущность Letter и у него есть поле sendDate. Это минимально необходимые данные для примера.

Подтягиваем в проект cron-bundle. В мануале уже показаны все тонкости настройки и установка, но мой пример будет более приближен к предметной области и сделан акцент на формирование shedule из даты отправки письма.

После установки и запуска миграции в проекте появится интересующая нас таблица cron_job. Именно в неё записываются все действия. У данной сущности есть поле schedule, которое содержит формат расписания cron ( minute hour day month dayOfWeek и необязательный year)

Записываем в планировщик ( crontab -e ) автоматическое отслеживание каждую минуту:

* * * * * php /path/to/symfonyProject/bin/console cron:run 1>> /dev/null 2>&1

Если в текущую минуту cron_job.schedule удовлетворяет условию наступления даты отправки письма, то выполняется cron_job.command, а это название обычной консольной команды симфони в проекте, которая просто запускается. Собственно там и осуществляется отправка письма.

В контролере, например при сохранении сущности письма, выполняется метод createCronJob, который заполняет сущность cron_job примерно таким образом:

// ... код контроллера выше

private function createCronJob(Letter $letter)
{
    $cronJob = new CronJob();
    $cronJobShedule = $this->convertDateToCronSchedule($letter->getSendDate());
    $cronJobName = 'newsletter ' . $cronJobShedule . ' ' . $letter->getId();
    $cronJobName = str_replace(' ', '_', $cronJobName);
    $cronJobCommand = 'newsletter:send-letter ' . $letter->getId();

    $cronJob
        ->setEnabled(true)
        ->setName($cronJobName)
        ->setDescription($cronJobName)
        ->setSchedule($cronJobShedule)
    ;
    $cronJob->setCommand($cronJobCommand);
    return $cronJob;
}

private function convertDateToCronSchedule(\DateTime $date)
{
    return $date->format('i') . ' ' .
        $date->format('H') . ' ' .
        $date->format('d') . ' ' .
        intval($date->format('m')) . ' * ' . // здесь обязательно INT, иначе не пройдет внутренняя проверка cron-bundle, CrontabValidator ::73 строка
        $date->format('Y');
}

// ... далее код ниже

Ну и после создания джобы уже $entityManager->flush(), чтобы записать все изменения в базу данных вместе с расписанием в cron_job. В результате после всего у нас в таблице cron_job должно появится что-то вроде этого:

schedule_cron_1

В поле command указано название консольной команды, которая должна быть зарегистрирована в симфони и отправлять письмо, число 26 это аргумент, который принимает команда и обозначает идентификатор письма в бд, который понадобится при обработке. В поле schedule формат расписания с необязательным параметром year (2019 из скриншота). Если вставить этот формат (данные schedule со скриншота) без числа 2019, который обозначает год и выполняется однажды благодаря этому, сюда crontab.guru, то там будет сказано что отправка письма будет 19 сентября в 16:35. Если эта дата ещё не наступила, то консольная команда не выполнится.



Похожие заметки:

Веб-разработка

Займусь вашим проектом, если вам нужен специалист в области веб-разработки

Открыть здесь

Вывод комментариев с пагинацией

Выводим все комменты на WordPress из базы данных с пагинацией

Открыть здесь

Прикручиваем Sphinx к своему поиску на сайте

Установка, задание конфигурации и запуск службы на Ubuntu для высокоскоростного поиска. Быстрый гайд

Открыть здесь


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии