web-dev-qa-db-fra.com

Utilisation de wp_schedule_single_event avec des arguments pour envoyer un courrier électronique

J'essaie de planifier un travail pseudo-cron pour envoyer un email après un certain temps en utilisant un plugin WordPress.

Jusqu'à présent, j'ai réussi à faire fonctionner ce code lorsque j'ai codé en dur l'adresse électronique et le message dans la fonction email_about_coupon(). Cependant, lorsque j'essaie d'envoyer les arguments à la fonction, le courrier électronique n'est jamais envoyé.

En utilisant le plugin Cron GUI , je suis en mesure de voir que le travail cron est enregistré même avec les arguments. Je crois que je fais quelque chose de mal qui ne permet pas aux arguments d'être utilisés correctement dans la fonction au moment de son exécution.

Voici ce que j'ai

function schedule_email_cron($post_id)
{
    // Get the UNIX 30 days from now time
    $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
    $text = "<html><body><p>Your coupon titled, ".$args['title']." is expiring soon. Please visit <a href=\"\">".get_bloginfo('siteurl')."/registered/</a> ".get_bloginfo('siteurl')."/registered/ to renew your coupon.</p></body></html>";

    // Email headers
    $headers = array(
        'From: '.get_bloginfo('name').' <'.get_bloginfo('admin_email').'>',
        "Content-Type: text/html"
    );
    $h = implode("\r\n",$headers) . "\r\n";

    // Send email
    wp_mail($args['email'], 'Renew Your Coupon Now!', $text, $h);
}

Comme toujours, merci beaucoup pour votre aide!

6
tollmanz

Je pense que votre façon de faire passer les arguments et de vous attendre à ce que cela fonctionne mal. Vous passez un tableau d'arguments à planifier et attendez-vous à ce que votre fonction accrochée reçoive un tableau d'arguments identique. Ce n'est pas le cas.

Les événements cron sont traités par do_action_ref_array() , qui transmet les arguments via call_user_func_array() .

Donc, votre fonction accrochée ne reçoit pas de tableau d'arguments, elle en reçoit plusieurs - un pour chaque élément de votre tableau.

Vous devez donc soit envelopper un tableau d’arguments dans un tableau une fois de plus, soit modifier votre fonction pour traiter plusieurs arguments. Notez que pour les lettres, vous devrez également modifier votre appel add_action() afin que le nombre requis d’arguments soit passé au lieu d’un seul.

11
Rarst

Grâce à Rarst, cela fait beaucoup plus de sens maintenant. J'ai donc mis à jour ce billet pour préciser les différences mentionnées par Rarst et son vote pour avoir éclairé cette question. )

Fondamentalement wp_schedule_single_event transmet les arguments à votre fonction par le biais de la variable args comme indiqué dans le codex . Cette variable "args" doit être un tableau car chaque valeur du tableau sera mappée à un argument dans votre fonction de rappel.

Exemple:

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 ira à $ a, 1 ira à $ b et 3 ira à $ c. Cependant, passer trois variables n’est possible qu’à cause de cette ligne,

add_action('example_action', 'example', 1, 3);

En regardant le codex pour add_action vous voyez que le quatrième argument, 3, est ce qui contrôle le nombre d’arguments passés à la fonction de rappel. La valeur par défaut est 1.

Donc, cet exemple fonctionne aussi:

add_action('example_action', 'example');
$args = array ( array( 2, 1, 3 ) );
wp_schedule_single_event(time(), 'example_action', $args);

function example($a)
{

}

Donc ici le tableau (2, 1, 3) est assigné à seulement $ a.

Donc, le problème de Sardine pourrait être résolu avec un changement de ligne où la ligne 7,

$args = array('email' => $email, 'title' => $post->post_title);

devient cela à la place,

$args = array(array('email' => $email, 'title' => $post->post_title));
12
Thirlan