Utilizarea wp_schedule_single_event cu argumente pentru trimiterea de emailuri

22 apr. 2011, 03:33:02
Vizualizări: 14.6K
Voturi: 10

Încerc să programez un pseudo cron job pentru a trimite un email după o anumită perioadă de timp folosind un plugin WordPress.

Până acum, am reușit să fac acest cod să funcționeze când introduc manual adresa de email și mesajul în funcția email_about_coupon(). Totuși, când încerc să trimit argumentele către funcție, emailul nu este niciodată trimis.

Folosind pluginul Cron GUI, pot vedea că cron job-ul este înregistrat chiar și cu argumentele. Cred că fac ceva greșit care nu permite utilizarea corectă a argumentelor în funcție în momentul în care aceasta este executată.

Iată ce am:

function schedule_email_cron($post_id)
{
    // Obține timpul UNIX pentru 30 de zile de acum
    $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)
{
    // Textul emailului
    $text = "<html><body><p>Couponul tău intitulat, ".$args['title']." expiră în curând. Te rugăm să vizitezi <a href=\"\">".get_bloginfo('siteurl')."/registered/</a> ".get_bloginfo('siteurl')."/registered/ pentru a-ți reînnoi couponul.</p></body></html>";

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

    // Trimite emailul
    wp_mail($args['email'], 'Reînnoiește-ți couponul acum!', $text, $h);
}

Ca întotdeauna, mulțumesc foarte mult pentru ajutor!

7
Comentarii

Ce rezultă dintr-un print_r($args, true) plasat undeva în corpul e-mailului?

kovshenin kovshenin
22 apr. 2011 13:42:46

Mulțumesc pentru comentariu. Pot încerca, dar cred că problema este că argumentul e-mail nu este transmis funcției email_about_coupon, așadar dacă folosesc print_r() în corp, oricum nu voi obține nimic. Este corectă această gândire? Voi încerca să hardcodez adresa de e-mail, să adaug print_r în corp și să văd ce se întâmplă. Mulțumesc pentru sugestie!

User User
22 apr. 2011 19:07:46

@Sardine, gândirea ta este corectă, așa că da, introdu adresa ta de e-mail în parametrul $to al funcției wp_mail și încearcă. Noroc!

kovshenin kovshenin
22 apr. 2011 19:21:01

Am încercat și am obținut, și interesant, folosind print_r afișează adresa de email furnizată în args, dar titlul nu apare. De asemenea, în textul emailului, când folosesc $args['title'], acesta apare ca t, deși titlul nu este t și nici măcar nu conține t. Aveți vreo idee?

User User
22 apr. 2011 19:49:27

Doar pentru a urmări această problemă, am renunțat la strategia de a încerca să trimit args la funcția care ar trebui să ruleze pe cron. În schimb, am utilizat o metodă de identificare a postărilor care ar avea nevoie să fie trimise email-uri către autorii lor și am făcut toate acestea în funcția email_about_coupons. În acest fel, am putut obține datele de care aveam nevoie fără să trimit nimic către funcție.

User User
23 apr. 2011 04:38:10

@Sardine te rog să consideri adăugarea soluției tale ca răspuns dacă este suficient de generică pentru a fi utilă și altora. :)

Rarst Rarst
24 apr. 2011 00:58:48

Rarst...asta este o idee bună; totuși, este o cantitate destul de mare de cod și nu cred că s-ar potrivi într-un comentariu, iar eu nu pot adăuga un răspuns singur. Există vreo altă modalitate prin care aș putea face asta?

tollmanz tollmanz
24 apr. 2011 01:05:01
Arată celelalte 2 comentarii
Toate răspunsurile la întrebare 2
3
19

Mulțumesc lui Rarst, acum are mult mai mult sens. Așadar, am actualizat acest articol pentru a elabora diferențele menționate de Rarst și i-am dat un vot pozitiv pentru că a lămurit această problemă ; )

În esență, wp_schedule_single_event transmite argumentele către funcția ta prin variabila args, așa cum este arătat în codex. Această variabilă "args" trebuie să fie un array, deoarece fiecare valoare din array va fi mapată la un argument în funcția ta de callback.

Exemplu:

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 va merge la $a, 1 va merge la $b și 3 va merge la $c. Cu toate acestea, transmiterea a trei variabile este posibilă doar datorită acestei linii,

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

Dacă ne uităm la codex pentru add_action, vedem că al patrulea argument, 3, este cel care controlează câte argumente sunt transmise funcției de callback. Valoarea implicită este 1.

Deci, acest exemplu funcționează și el:

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

function example($a)
{

}

Aici, array( 2, 1, 3) este atribuit doar lui $a.

Deci, problema lui Sardine ar putea fi rezolvată cu o singură modificare, unde linia 7,

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

devine asta în schimb,

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

Acest lucru nu este nici hacky, nici bug. Primul funcționează exact așa cum trebuie. Pentru al doilea, va trebui să modifici apelul tău add_action() astfel încât să fie transmise mai multe argumente în loc de cel implicit.

Rarst Rarst
12 mai 2011 01:38:41

Mulțumesc, Thirlan! Răspunsul lui Rarst a dat cu siguranță startul discuției, iar al tău m-a ajutat să înțeleg mai bine. Ți-am dat upvote, dar i-am acordat lui Rarst acceptul pentru răspuns. De asemenea, ar trebui să modific linia pe care ai sugerat-o, dar nu ar trebui și să schimb add_action('email_about_coupon_action', 'email_about_coupon', 1, 1); în add_action('email_about_coupon_action', 'email_about_coupon', 1, 3); pentru ca numărul corect de argumente să fie acceptat?

tollmanz tollmanz
14 mai 2011 22:20:14

Nu este necesar. $args = array(array( transmite totul ca un singur variabil de tip array în acest caz.

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

Cred că există o nepotrivire în modul în care transmiți argumentele și cum te aștepți să funcționeze. Tu transmiți un array de argumente la programare și te aștepți ca funcția ta asociată să primească exact același array de argumente. Nu este cazul.

Evenimentele Cron sunt procesate prin do_action_ref_array(), care la rândul său transmite argumentele prin call_user_func_array().

Deci funcția ta asociată nu primește un array de argumente, ci mai multe argumente - câte unul pentru fiecare element din array-ul tău.

Deci trebuie fie să înfășori array-ul de argumente într-un alt array, fie să modifici funcția ta să proceseze mai multe argumente. Reține că pentru a doua variantă va trebui să modifici și apelul add_action() astfel încât să fie transmis numărul necesar de argumente în loc de doar unul.

12 mai 2011 01:35:03
Comentarii

Mulțumesc Rarst! M-a ajutat foarte mult! Așa funcționează toate apelurile add_action când trimiteți array-uri de valori. În mod surprinzător, cu toată munca pe care am făcut-o în WP, am avut de-a face doar cu trimiterea de argumente unice către funcții prin apeluri add_action.

tollmanz tollmanz
14 mai 2011 22:21:37

@Sardine o acțiune poate fi executată fie prin do_action() fie prin do_action_ref_array(), diferența fiind modul în care argumentele sunt acceptate de acestea. Dar întotdeauna aveți întregul set de argumente trimise către funcția efectiv hook-uită.

Rarst Rarst
14 mai 2011 23:23:46