Na jednom systému jsem využil plugin Events manager pro WordPress, pro správu událostí. Plugin při vytvoření opakované události vytvoří automaticky jednotlivé události na všechny dny. Zde ale nastal problém, pokud se události mají zveřejnit v budoucnu.
Zmeškané publikování
Pokud se vytvoří post, který má datum publikování v budoucnu, WordPress automaticky nastaví cron na danou dobu. Pokud ale stránka nemá dostatečný traffic, jsou rozdíly v časových pásmech (lze upravit v administraci), nebo jiný plugin přepsal celý cron, post se nikdy nepublikuje.
V mém případě WordPress nastavil cron pouze pro první událost, ne již pro všechny ostatní. Pak nastal problém, že události zůstaly ve stavu future, i když měly být publikovány.
Kontrola všech postů při každém načtení stránky
Nejjednodušší řešení je, zkontrolovat všechny posty ve stavu future s časem publikování v minulosti a publikovat je. Zde je jednoduchý kód, který vše udělá:
add_action('init', 'check_all_nonpublished_posts'); function check_all_nonpublished_posts() { global $wpdb; // Získáme IDčka všech postů, které jsou future // a publikování již mělo proběhnout // time() ve WordPressu je vždy v GMT $results = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date_gmt < '".date("Y-m-d H:i:s", time())."'", ARRAY_A); foreach ($results as $postToUpdate) { // Post publikuje a zavolá všechny akce, nemusíme se starat wp_publish_post($postToUpdate['ID']); // Výjimka je akce publish_future_post, ta je volána pouze // cronem, který ale neproběhl, zavoláme tedy ručně do_action("publish_future_post", $postToUpdate['ID']); } }
Moc mi to vytěžuje a zpomaluje web
Funkce se nemusí volat při každém spuštění, může se nastavit pomocí cronu na každých 10 minut, či jiný potřebný čas:
add_action('init', 'initPublishingCron'); function initPublishingCron() { // Akce vůbec není nastavena if (wp_next_scheduled("check_all_nonpublished_action") === false) { wp_schedule_single_event(time() + 10*60, "check_all_nonpublished_action"); } } // Nahradíme řádek add_action("init"... z předchozí ukázky tímto add_action('check_all_nonpublished_action', 'check_all_nonpublished_posts'); function check_all_nonpublished_posts() { // Původní obsah funkce vložíme zde // Jedná se o jednorázovou akci, je potřeba ji nastavit znova wp_clear_scheduled_hook("check_all_nonpublished_action"); wp_schedule_single_event(time() + 10*60, "check_all_nonpublished_action"); }
Mám vlastní cron
Nyní WordPress při každém načtení stránky zkontroluje veškeré cron úlohy a případně je spustí. Pokud ale na web nikdo nepřijde, cron se nespustí. Pokud se například odesílají v noci emaily apod., je vhodné nastavit si vlastní cron na serveru.
Prvně je potřeba upravit soubor wp-config.php a vložit do něj následující kód. Ten zajistí, že při načtení stránky uživatelem se cron nikdy nebude spouštět.
define( 'DISABLE_WP_CRON', true );
A nyní do přes příkaz crontab nebo na hostingu ve správci cron úloh je nutné vložit následující URL adresu k provádění tak často, jak je potřeba. PS. Je potřeba změnit URL adresu pro daný web samozřejmě...
http://www.example.com/wp-cron.php?doing_wp_cron
WordPress cron se již postará o spuštění té úlohy, u které je to potřeba. Nebude se ale o ně starat u běžného návštěvníka, ale pouze na této URL adrese.
Máte vlastní zkušenosti s WordPress a cronem? Podělte se v komentářích
K tomuto článku již není možné přidávat další komentáře