Pull to refresh

Запланированная отправка постов (php, mongo, cron, regexp)

Reading time 2 min
Views 2K
Добрый день.

Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.

Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.

Шаблон * * * * *

После этого встал вопрос — как получить только нужные поля для отправки?

Cron срабатывает каждую минуту и вызывает скрипт отправки постов, и перебирать каждую минуту всю таблицу подготовленных для отправки постов и сравниать с текущей датой/временем было бы лишней операцией.

Я использую базу данных MongoDB, которая может выбирать все поля по регулярному выражению. Вот что я сделал:

Берем текущую дату и время и переводим в массив

$dateTime = explode(' ', date('i G j n w', time()));

Далее строим регулярное выражение, которое выбирает записи, подходящие для отправки на текущий момент (текущая минута).

$joe_search = new \MongoRegex(
'/^(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[0]*1).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[1]).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[2]).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[3]).'){1}(\,\d{1,2})*)\s'.
'(\*|(([1-6]{1}\,)|(\*\/))*('.($dateTime[4]).'){1}(\,[1-6]{1})*)$/i'
));

$cursor = $collection->find(array("sendRule" => $joe_search));

sendRule — название поля в базе, которое содержит наше cron правило.
$dateTime[0] (минуты) могут быть с нулями в начале (например 05 минут), по этому мы умножаем их на 1 что бы убрать ноль.

Тестировал * 1,12,20 7,8,12 * */3 (каждую минуту 1,12 и 20 часа 7,8,12 числа каждого месяца в среду).

Вот собственно и все, далее циклом обрабатываем полученный массив и отправляем все что нужно.
Tags:
Hubs:
-5
Comments 13
Comments Comments 13

Articles