¿Alguna vez os habéis preguntado cómo WordPress detecta si hay alguna nueva versión? ¿O cómo se publican las entradas automáticamente tal día y tal hora en aquellas que están programadas?
Introducción
WordPress tiene un sistema de automatización de eventos cuyas funciones del núcleo las podéis encontrar en wp-cron.php y en cron.php dentro de la carpeta wp-includes de nuestra instalación.
Para hablar de cron nos tenemos que ir por un momento a Unix donde en este sistema cron es un administrador de procesos en segundo plano, es decir, es un programa que se ejecuta en segundo plano y que se dedica a lanzar uno o varios procesos cada determinado tiempo. Según la Wikipedia y para aquellos usuarios de Windows es algo parecido a las Tareas Programadas.
WordPress ha intentado emular este administrador de procesos en su núcleo de forma que se puedan ejecutar acciones cada cierto tiempo, pero como vamos a ver en WordPress hay una serie de limitaciones, es decir, no funciona exactamente igual que el cron de Unix.
Mientras que en Unix los procesos programados se ejecutan puntualmente cada tiempo indicado en WordPress la cosa no es así, sino que primero se programa la acción cada cierto tiempo, posteriormente se espera una visita al sitio web y por último se comprueba que ese tiempo se haya superado para ejecutar el proceso.
Limitaciones de WP-Cron
Este pseudo-cron tiene una serie de limitaciones, la primera que se puede deducir a partir del último párrafo es que, ¿quiere decir que si no tengo visitas el evento no se dispara? Exactamente. Por ejemplo, si hemos programado un evento para que suceda diariamente, digamos que a las 12 de la noche, si durante las 11 horas siguientes nadie visita nuestra página web este evento no se lanzará hasta después de esas 11 horas. Qué jodienda… por suerte podemos hacer algún apaño desde el servidor como luego veremos.
Otro problema que nos puede dar es la carga del servidor por lo que todas las acciones programadas deberán ser simples para que no consuma muchos recursos del servidor, imaginaos un sitio en WordPress con 100 tareas programadas para cada 5 minutos en las cuales se haga una copia de seguridad de toda la base de datos, de los ficheros, que se envíen 300 emails y 400 castelleres hagan un castillo. Sin duda en ejemplo un poco exagerado pero ilustra lo que quiero decir. Procesos pesados y programados harán lenta la carga del sitio.
Un paseo por las funciones
No es el objetivo del post poner ejemplos complejos, daremos un paseo por las funciones que tenemos en el CODEX.
wp_schedule_event($timestamp, $recurrence, $hook, $args)
La principal función, o al menos la que más uso he hecho hasta ahora pues es la que programa un evento, soporta los siguientes parámetros:
- $timestamp: Tiene que ser en formato UNIX, para ello podemos usar la función time() de PHP.
- $recurrence: Es el periodo de tiempo en el que se ejecutará, por defecto soporta ‘hourly’, ‘daily’ y ‘twicedaily’ aunque se pueden generar más periodos como veremos.
- $hook: Gancho de la acción que se ejecutará.
- $args: Es un array opcional de argumentos para la función asociada a la acción definida por el parámetro anterior.
Por poner un ejemplo pensemos en un plugin que tiene que programar un evento.
[php]
register_activation_hook( __FILE__, ‘funcion_activacion’ ); //Función a ejecutar cuando se activa el plugin
register_deactivation_hook( __FILE__, ‘funcion_desactivacion’ ); //Función a ejecutar cuando se desactiva el plugin
function funcion_activacion() {
wp_schedule_event( time(), ‘daily’, ‘envio_mails_hook’ );
}
function funcion_desactivacion() {
wp_clear_scheduled_hook( ‘envio_mails_hook’ );
}
add_action( ‘envio_mails_hook’, ‘funcion_envio_mails’ );
function funcion_envio_mails() {
// Código para el envío de emails
}
[/php]
En el ejemplo anterior hemos introducido otra función.
wp_clear_scheduled_hook( $hook, $args );
Esta función se encarga de desprogramar todos los eventos asociados a una acción, como se puede ver en el ejemplo anterior. Los parámetros que acepta son:
- $hook: El nombre del gancho al que se le asocia la función.
- $args: Array de argumentos para la función asociada al gancho.
Otra función muy parecida es:
wp_unschedule_event( $timestamp, $hook, $args );
En lugar de desprogramar todos los eventos asociados a un gancho solamente desprograma aquel evento indicado por $timestamp, el resto de argumentos son los mismos que en wp_clear_scheduled_hook.
wp_next_scheduled( $hook, $args );
Devuelve un timestamp en formato UNIX del siguiente evento, por ejemplo si hemos programado un evento cada hora, nos devolverá el timestamp de la próxima vez que se deberá ejecutar la acción programada.
Nos puede servir junto con la función anterior para desprogramar un evento.
[php]
$timestamp = wp_next_scheduled( ‘envio_mails_hook’ );
wp_unschedule_event( $timestamp, ‘envio_mails_hook’ );
[/php]
La última función que considero muy importante es:
wp_get_schedules();
Esta función devuelve un array con todos los periodos de tiempos definidos, si bien la función en sí no es lo que considero muy importante como he dicho, sino la posibilidad de crear nuevos periodos de tiempo:
[php]
add_filter( ‘cron_schedules’, ‘anyadir_semana’ );
function anyadir_semana( $schedules ) {
$schedules[‘semanal’] = array(
‘interval’ => 604800, // En segundos: 7 * 24 * 60 * 60
‘display’ => __( ‘Semanalmente’ )
);
return $schedules;
}
[/php]
Concluyendo
WordPress nos ofrece un sistema para programar eventos que aunque imperfecto sí es útil para tareas sencillas y no demasiado pesadas. El núcleo de WordPress nos ofrece una serie de funciones muy útiles para programar nuestros propios eventos, por ejemplo podemos crear un tema que reciba actualizaciones o un plugin para que haga una copia de la base de datos automáticamente y la envíe por email a un correo electrónico.
En el siguiente post sobre WP-Cron hablaremos de como crear una tarea cron de verdad (sistema UNIX) en un servidor, a través de CPanel y veremos algunos plugins para WordPress que nos ayudarán a ver los eventos programados, su siguiente ejecución y más información útil sobre todo para un debug.
Os dejo con las referencias que he usado para programar un plugin que usa WP-Cron para uno de los proyectos que llevamos en Convershare y para escribir esta entrada.
Referencias:
3 comentarios en «WP-Cron. Eventos en WordPress (1/2)»
Excelente post, hay manera de disparar el evento solo una vez sin necesidad de una visita web?
Hola.
WP-Cron funciona con visitas web aunque desde el servidor puedes crear una tarea CRON que emule una visita a la web.
Echa un ojo a este enlace:
https://www.siteground.es/tutoriales/tutorial-wordpress/reemplazar-el-cron-de-wordpress.htm
Puede desactivar el sistema Cron WP añadiendo
define ( ‘DISABLE_WP_CRON’, true);
a su archivo wp-config.php, y cron servidor de uso o servicio cron externo (como https://www.easycron.com).