Использование wp_schedule_single_event с аргументами для отправки email
Я пытаюсь запланировать псевдо-cron задачу для отправки email через определенное время с использованием плагина WordPress.
Пока мне удалось заставить этот код работать, когда я жестко прописываю email и сообщение прямо в функции email_about_coupon()
. Однако при попытке передать аргументы в функцию email никогда не отправляется.
С помощью плагина Cron GUI я вижу, что cron-задача регистрируется даже с аргументами. Я предполагаю, что делаю что-то неправильно, из-за чего аргументы не передаются должным образом в функцию во время ее выполнения.
Вот мой код:
function schedule_email_cron($post_id)
{
// Получаем UNIX-время через 30 дней от текущего момента
$thirty_days = time() + 60; // (30 * 24 * 60 * 60)
$post = get_post($post_id);
$email = get_the_author_meta('user_email', $post->post_author);
$args = array('email' => $email, 'title' => $post->post_title);
wp_schedule_single_event($thirty_days, 'email_about_coupon_action', $args);
}
add_action('save_post', 'schedule_email_cron', 1, 1);
add_action('email_about_coupon_action', 'email_about_coupon', 1, 1);
function email_about_coupon($args)
{
// Текст email
$text = "<html><body><p>Ваш купон с названием ".$args['title']." скоро истекает. Пожалуйста, посетите <a href=\"\">".get_bloginfo('siteurl')."/registered/</a> ".get_bloginfo('siteurl')."/registered/ чтобы продлить ваш купон.</p></body></html>";
// Заголовки email
$headers = array(
'From: '.get_bloginfo('name').' <'.get_bloginfo('admin_email').'>',
"Content-Type: text/html"
);
$h = implode("\r\n",$headers) . "\r\n";
// Отправка email
wp_mail($args['email'], 'Продлите ваш купон сейчас!', $text, $h);
}
Как всегда, огромное спасибо за помощь!
Спасибо Rarst, теперь всё стало намного понятнее. Поэтому я обновил этот пост, чтобы подробнее объяснить различия, о которых упомянул Rarst, и плюсанул его ответ за то, что он пролил свет на этот вопрос ; )
По сути, wp_schedule_single_event передает аргументы в вашу функцию через переменную args, как показано в codex. Эта переменная "args" должна быть массивом, потому что каждое значение в массиве будет сопоставлено с аргументом в вашей callback-функции.
Пример:
add_action('example_action', 'example', 1, 3);
$args = array ( 2, 1, 3 );
wp_schedule_single_event(time(), 'example_action', $args);
function example($a, $b, $c)
{
}
2 пойдет в $a, 1 — в $b, а 3 — в $c. Однако передача трех переменных возможна только благодаря этой строке:
add_action('example_action', 'example', 1, 3);
Если посмотреть codex для add_action, то видно, что четвертый аргумент, 3, определяет, сколько аргументов будет передано в callback-функцию. По умолчанию значение равно 1.
Поэтому этот пример также работает:
add_action('example_action', 'example');
$args = array ( array( 2, 1, 3 ) );
wp_schedule_single_event(time(), 'example_action', $args);
function example($a)
{
}
Здесь массив array(2, 1, 3) просто присваивается переменной $a.
Таким образом, проблему Sardine можно решить одной строкой, заменив строку 7:
$args = array('email' => $email, 'title' => $post->post_title);
На это:
$args = array(array('email' => $email, 'title' => $post->post_title));

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

Спасибо, Thirlan! Ответ Rarst определенно дал старт решению, а твой помог мне понять его лучше. Я поставил тебе плюс, но отметил ответ Rarst как принятый. Также, мне нужно изменить строку, которую ты предложил, но разве мне не нужно также изменить add_action('email_about_coupon_action', 'email_about_coupon', 1, 1);
на add_action('email_about_coupon_action', 'email_about_coupon', 1, 3);
, чтобы принималось правильное количество аргументов?

Я думаю, у вас есть несоответствие в том, как вы передаете аргументы и как ожидаете их работу. Вы передаете массив аргументов в расписание и ожидаете, что ваша подключенная функция получит идентичный массив аргументов. Но это не так.
События Cron обрабатываются функцией do_action_ref_array()
, которая в свою очередь передает аргументы через call_user_func_array()
.
Таким образом, ваша подключенная функция не получает массив аргументов - она получает несколько аргументов, по одному для каждого элемента в вашем массиве.
Поэтому вам нужно либо обернуть массив аргументов в массив еще раз, либо изменить свою функцию для обработки нескольких аргументов. Обратите внимание, что для второго варианта вам также потребуется изменить вызов add_action()
, чтобы передавалось необходимое количество аргументов, а не только один.

Спасибо, Rarst! Это очень помогло! Значит ли это, что все вызовы add_action
работают таким образом при передаче массивов значений? Удивительно, что за все время работы с WordPress мне приходилось иметь дело только с передачей отдельных аргументов в функции через вызовы add_action.
