¿En qué podemos ayudarte?
Gestionar el cron de WordPress es importante para la buena salud de nuestra web. En un artículo reciente vimos como optimizar su ejecución para garantizar que las tareas programadas se ejecuten a su hora y al mismo tiempo reducir la carga sobre nuestro servidor web. El siguiente paso es tomar el control sobre las tareas que se ejecutan y sus programaciones.
Lo haremos con algunas funciones simples, que podemos incorporar al functions.php de nuestro tema hijo, o a nuestros desarrollos personalizados. También veremos como añadir nuestras propias tareas y programar su ejecución en segundo plano.
Estructura del cron de WordPress
WordPress usa un sistema muy simple para gestionar las tareas programada. Básicamente consiste en una lista de eventos que se almacena en la tabla wp_options. Esta lista es consultada por el archivo wp-cron.php y la tarea asociada a cada evento se ejecuta cuando procede.
Los eventos están asociados a ganchos (hooks) de acciones. Esto nos da libertad total para ejecutar cualquier proceso. Y al mismp tiempo, tendremos acceso a todas las funcionalidades del núcleo de WordPress y plugins instalados. Por supuesto, podremos establecer cualquier frecuencia de repetición .
En el Codex encontraremos toda la información necesaria para crear tareas y gestionar el cron de WordPress. Los pasos a seguir apara añadir nuestras propias tareas son simples:
- Creamos la función que realizará el trabajo y la asociamos a un gancho
- Si los intervalos de ejecución predefinidos (1 vez al día, 2 veces al día, cada hora, semanalmente) no se adaptan a nuestras necesidades, creamos uno a medida y lo registramos en el sistema.
- Añadimos el gancho y su intervalo a la lista de tareas programadas.
Estos tres pasos son suficientes para que el cron de WordPress ejecute nuestra tarea en la fecha y hora programadas.
WP-Control como gestor del cron
Hay muchos plugins para gestionar el cron de WordPress. WP-Control es uno de los más utilizados. Tiene +100.000 instalaciones activas y una valoración de 5 estrellas. Podemos usarlo como un ejemplo de las funcionalidades a replicar.
WP-Control nos muestra la lista de tareas registradas y nos permite crear tareas nuevas, así como modificar, ejecutar y eliminar las existentes
También tenemos a mano las programaciones disponibles y podremos añadir las que estimemos necesarias
Como vemos, tenemos todo lo necesario para gestionar las tareas programadas, sin complicarnos la vida. La única pega que le pongo es que ofrece más de lo habitualmente necesario, además de mi fobia a instalar más complemento de los absolutamente necesarios.. Me explico.
Las tareas programadas son generadas por el núcleo de WordPress o plugins. Por tanto, antes de alterar su programación debemos tener muy claro su funcionamiento o podemos llevarnos más de una sorpresa desagradable. Puntualmente, casi siempre para diagnosticar o solucionar un problema, nos veremos en la necesidad de realizar estas labores. Pero si poseemos los conocimientos técnicos, quizás no necesitemos el plugin.
Dicho esto, mantengo mi opinión que considero WP-Control conmo una herramienta muy útil. Tiene funcionalidades muy útiles, que en mi opinión deberían estar incorporadas de serie. Son acceder a la lista de tareas, añadir las mías y eliminar las innecesarias. A continuación veremos como incluirlas.
Gestionando el cron de WordPress
Ahora que ya sabemos lo que queremos, pasemos directamente a la acción.
1. Lista de tareas
Empecemos por ver que se cuece en nuestro sistema. Tenemos varias opciones para obtener la lista de tareas programadas
Sabiendo que las tareas programadas se guardan en wp_options, la siguiente consulta debería decirnos cuales son: "SELECT * FROM `wp_options`WHERE `option_name` LIKE '%cron%'". Pero hay dos opciones más sencillas. Podemos acceder directamente a la opción con $tareas = get_option( 'cron' ); o usando una función no documentada, pero igual de efectiva: $crons =_get_cron_array();
Prefiero utilizar la última variante, que nos da la estructura más sencilla.
El resultado es una matriz con los siguientes elementos:
- hook: Función a ejecutar. Su nombre suele estar relacionado con el plugin responsable de la tarea
- hash: Lista de ejecuciones programadas
- progr: Nombre asignado a la programación dentro de WordPress
- args: Argumentos que necesita la función asociada
- intervalo: Segundos entre cada ejecución programada
Con estos elementos podemos "aplanar" el resultado para obtener una lista simple que podamos visualizar en una tabla. El código no es compliado y el resultado final sería algo parecido a la siguiente imagen:
La tabla esta construida utilizando la librería DataTables. Este componente gratuito permite incorporar tablas interactivas en nuestros proyectos con unas pocas líneas de código. Podemos personalizar todos y cada uno de los elementos e las tablas.
Para la columna "Próxima ejecución" utilizo la función wp_next_scheduled($hook). A esta función le pasamos el hook de la programación a eliminar y nos devuelve una marca de tiempo que visualizaremos con el formato que consideremos más apropiado.
2. Eliminar tareas programadas
Este fragmento también nos muestra porqué considero necesaria la funcionalidad de eliminar tareas. No uso Jetpack, pero Woocommerce suele instalarlo sus servicios. He borrado el plugin, pero la tarea programada no se ha eliminado. No es el único caso, también Hyper Cache no ha hecho los deberes y deja rastros después de ser eliminado totalmente.
Por desgracia, esta es una situación que se reproduce con demasiada frecuencia para mi gusto. Por eso al gestionar el cron de WordPress poder borrar las tareas innecesarias. La función a utilizar es la siguiente:
function EliminaProgramacion($tarea) {
$timestamp=wp_next_scheduled($tarea);
wp_unschedule_event( $timestamp, $tarea);
}
En mi caso el botón utiliza AJAX para ejecutar esta función y luego recargar la tabla.
Finalmente al eliminar una tarea se borran todas sus programaciones existentes, no solo la seleccionada.
3. Añadir tareas al cron de WordPress
Solo nos queda ver como agregar nuestras propias tareas. Para ello primero tenemos que añadir nuestra programación personalizada, si fuese necesario. Para ellos utilizaremos el siguiente filtro:
function intervalos_cron_personalizados( $schedules ) {
$schedules['nombre-intervalo'] = array(
'interval' => segundos-de espera,
'display' => 'Nombre-para-visualizar-ntervalo'
);
return (array)$schedules;
}
add_filter( 'cron_schedules', 'intervalos_cron_personalizados', 10, 1 );
La función recibe una lista de programaciones en la variable $schedules y agregas las que podamos necesitar.
Un vez registrados los intervalos, añadimos la tarea
function ProgramaTarea($tarea,$intervalo,$args=[]) {
if ( ! wp_next_scheduled( $tarea ) ) { wp_schedule_event( time(), $intervalo, $tarea,$args ); }
}
La misma tarea puede ser programada varias veces. Si eso no es lo que queremos, primero comprobamos si aun no está programada mediante nuestra vieja conocida wp_next_scheduled. Si no está programa aún la agregamos indicando el intervalo a utilizar y opcionalmente los argumentos necesarios. La función wp_schedule_event recibe como argumento el momento de la primera ejecución. Si indicamos la fecha actual se ejecutara lo antes posible. También podemos programar una ejecución única, para ello utilizaremos la función wp_schedule_single_event con los mismos argumentos. Para modificar una tarea primero la eliminamos y la añadimos con la nueva programación.
Solo nos queda definir el trabajo a realizar o cuando llegue el momento no pasará nada. Por suerte basta 1 línea de código para registrar el hook. Este el el ejemplo correspondiente a la última línea mostrada en mi lista de tareas:
add_action( 'rjc_actualiza_stock', 'rjc_globomatik_actualiza_stock' );
function rjc_globomatik_actualiza_stock() { Codigo PHP de la función }
Conclusiones
Hemos visto que tenemos todo lo necesario para gestionar el cron de WordPress sin necesidad de utilizar plugins específicos, aunque hay buenas opciones en el repositorio. Pero ya que es muy probable que personalicemos nuestra instalación, con unas pocas lineas de código extra tendremos las funcionalidades que consideremos necesarias para controlar totalmente este aspecto de nuestra web.
En mi caso, necesitaba automatizar la sincronización del catálogo de la tienda. Las tareas a programar son: descargar y actualizar el catálogo, mantener el stock sincronizado y eliminar los productos no disponible.
Este es el aspecto final de la pantalla de configuración.de mi plugin. He aprovechado para eliminar las tareas innecesarias (Jetpack e Hype Cache).
Algo que no debemos olvidar es mantener un registro de la ejecución de las tareas., sobre todo si se ejecutan en segundo plano. Y solo me interesa ejecutar de inmediato mis propias tareas.
Como dato curioso la descarga y actualización del catálogo en modo interactivo usando AJAX requiere 15-16 minutos. Esto significa que el proceso no interactivo es aproximadamente un 40% más rápido para un proceso intensivo como es ese. Esos son recursos disponible para atender a posibles compradores de la tienda y a vosotros como usuarios de esta web.
Espero que esta guía os ayude a gestionar el cron de WordPress de una forma más eficaz. Y, si necesitáis mi ayuda, contad con ella.