Utilizzo di wp_schedule_single_event con argomenti per inviare email

22 apr 2011, 03:33:02
Visualizzazioni: 14.6K
Voti: 10

Sto cercando di programmare un lavoro pseudo cron per inviare un'email dopo un determinato periodo di tempo utilizzando un plugin WordPress.

Finora, sono riuscito a far funzionare questo codice quando inserisco manualmente l'indirizzo email e il messaggio nella funzione email_about_coupon(). Tuttavia, quando provo a passare gli argomenti alla funzione, l'email non viene mai inviata.

Utilizzando il plugin Cron GUI, posso vedere che il job cron viene registrato anche con gli argomenti. Credo di star facendo qualcosa in modo errato che non permette agli argomenti di essere utilizzati correttamente all'interno della funzione quando viene eseguita.

Ecco il codice che ho:

function schedule_email_cron($post_id)
{
    // Ottieni il tempo UNIX tra 30 giorni da adesso
    $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)
{
    // Testo dell'email
    $text = "<html><body><p>Il tuo coupon intitolato, ".$args['title']." sta per scadere. Visita <a href=\"\">".get_bloginfo('siteurl')."/registered/</a> ".get_bloginfo('siteurl')."/registered/ per rinnovare il tuo coupon.</p></body></html>";

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

    // Invia l'email
    wp_mail($args['email'], 'Rinnova il tuo coupon ora!', $text, $h);
}

Come sempre, grazie mille per il vostro aiuto!

7
Commenti

Cosa produce un print_r($args, true) inserito da qualche parte nel corpo dell'email?

kovshenin kovshenin
22 apr 2011 13:42:46

Grazie per il commento. Posso provarci, ma penso che il problema sia che l'argomento email non viene passato alla funzione email_about_coupon, quindi se uso print_r() nel corpo, non otterrò comunque nulla. Il mio ragionamento è corretto? Proverò a hardcodare l'indirizzo email, aggiungerò print_r al corpo e vedrò cosa succede. Grazie per il suggerimento!

User User
22 apr 2011 19:07:46

@Sardine, il tuo ragionamento è corretto, quindi sì, inserisci il tuo indirizzo email nel parametro $to di wp_mail e prova. Saluti!

kovshenin kovshenin
22 apr 2011 19:21:01

Ho provato e ho ottenuto, curiosamente, utilizzando print_r stampa l'indirizzo email fornito in args, ma il titolo non viene stampato. Inoltre, nel testo dell'email, quando uso $args['title'], viene stampato come t, quando il titolo non è t, né contiene nemmeno t. Qualche idea?

User User
22 apr 2011 19:49:27

Solo per seguire su questo, ho abbandonato la strategia di provare a inviare args alla funzione che dovrebbe essere eseguita nel cron. Invece, ho utilizzato un metodo per identificare i post che avrebbero bisogno di email inviate ai loro autori e ho fatto tutto questo all'interno della funzione email_about_coupons. In questo modo, ho potuto ottenere i dati di cui avevo bisogno senza inviare nulla alla funzione.

User User
23 apr 2011 04:38:10

@Sardine per favore considera di aggiungere la tua soluzione come risposta se è abbastanza generica da essere utile ad altri. :)

Rarst Rarst
24 apr 2011 00:58:48

Rarst...questa è una buona idea; tuttavia, è una quantità considerevole di codice e non credo che possa rientrare in un commento e non posso aggiungere una risposta da solo. C'è un altro modo per farlo?

tollmanz tollmanz
24 apr 2011 01:05:01
Mostra i restanti 2 commenti
Tutte le risposte alla domanda 2
3
19

Grazie a Rarst, ora ha molto più senso. Quindi ho aggiornato questo post per approfondire le differenze menzionate da Rarst e ho votato positivamente il suo contributo per aver fatto luce sulla questione ; )

Fondamentalmente wp_schedule_single_event passa gli argomenti alla tua funzione attraverso la variabile args come mostrato nel codex. Questa variabile "args" deve essere un array perché ogni valore nell'array verrà mappato a un argomento nella tua funzione di callback.

Esempio:

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 andrà a $a, 1 andrà a $b e 3 andrà a $c. Tuttavia, passare tre variabili è possibile solo grazie a questa riga:

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

Guardando il codex per add_action puoi vedere che il quarto argomento, 3, è ciò che controlla quanti argomenti vengono passati alla funzione di callback. Il valore predefinito è 1.

Quindi anche questo esempio funziona:

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

function example($a)
{

}

Qui l'array( 2, 1, 3 ) viene assegnato solo a $a.

Quindi il problema di Sardine potrebbe essere risolto con una modifica di una riga dove la riga 7:

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

diventa invece questo:

$args = array(array('email' => $email, 'title' => $post->post_title));
12 mag 2011 00:54:27
Commenti

Questo non è né un hack né un bug. Il primo funziona esattamente come dovrebbe. Per il secondo, dovrai modificare la tua chiamata add_action() in modo che vengano passati più argomenti invece di quello predefinito.

Rarst Rarst
12 mag 2011 01:38:41

Grazie Thirlan! La risposta di Rarst ha sicuramente dato il via e la tua mi ha aiutato a capire meglio. Ti ho dato un voto positivo, ma ho accettato la risposta di Rarst. Inoltre, dovrei modificare la linea che hai suggerito, ma non dovrei anche cambiare add_action('email_about_coupon_action', 'email_about_coupon', 1, 1); in add_action('email_about_coupon_action', 'email_about_coupon', 1, 3); per far sì che venga accettato il giusto numero di argomenti?

tollmanz tollmanz
14 mag 2011 22:20:14

No, non è necessario. $args = array(array( passa tutto così com'è come una singola variabile array in questo caso.

Thirlan Thirlan
16 mag 2011 12:05:19
2
14

Penso che ci sia un disallineamento nel modo in cui passi gli argomenti e come ti aspetti che funzioni. Passi un array di argomenti a schedule e ti aspetti che la tua funzione hook riceva un array identico di argomenti. Non è così.

Gli eventi Cron vengono elaborati da do_action_ref_array(), che a sua volta passa gli argomenti tramite call_user_func_array().

Quindi la tua funzione hook non riceve un array di argomenti, ma riceve argomenti multipli - uno per ogni elemento nel tuo array.

Quindi devi o avvolgere l'array di argomenti in un altro array o modificare la tua funzione per elaborare argomenti multipli. Nota che per quest'ultimo caso dovrai anche modificare la tua chiamata add_action() in modo che venga passato il numero richiesto di argomenti invece di solo uno.

12 mag 2011 01:35:03
Commenti

Grazie Rarst! È stato di grande aiuto! Funzionano così tutte le chiamate add_action quando si inviano array di valori? Sorprendentemente, nonostante tutto il lavoro che ho fatto con WP, ho davvero avuto a che fare solo con l'invio di argomenti singoli alle funzioni tramite chiamate add_action.

tollmanz tollmanz
14 mag 2011 22:21:37

@Sardine un'azione può essere eseguita sia da do_action() che da do_action_ref_array() e la differenza sta nel modo in cui accettano gli argomenti. Ma avrai sempre l'intero set di argomenti passato alla funzione effettivamente collegata.

Rarst Rarst
14 mag 2011 23:23:46