Automatización de procesos en PrestaShop con cron jobs
Introducción: El Desafío de la Gestión Manual en Ecommerce
Gestionar una tienda online con PrestaShop implica una serie de tareas repetitivas que, si se realizan manualmente, consumen horas de trabajo y son propensas a errores humanos. Actualizar precios, sincronizar el stock con un proveedor, enviar boletines, procesar devoluciones o regenerar miniaturas de imágenes son solo algunos ejemplos. Aquí es donde la automatización de procesos en PrestaShop se convierte en un pilar fundamental para escalar el negocio.
La solución más robusta, flexible y económica para lograr esta automatización es el uso de cron jobs. Un cron job es una tarea programada en un servidor Unix/Linux que ejecuta un script o comando en un intervalo de tiempo definido (cada minuto, hora, día, etc.). En el contexto de un ecommerce, los cron jobs son el motor invisible que mantiene la tienda sincronizada, actualizada y optimizada sin intervención manual.
Este artículo técnico está diseñado para SysAdmins y desarrolladores que buscan implementar una automatización sólida en PrestaShop. Exploraremos desde la configuración básica de cron jobs hasta la creación de scripts avanzados para la sincronización de inventario y otras tareas críticas.
Fundamentos de los Cron Jobs en un Entorno PrestaShop
Antes de sumergirnos en los scripts, es crucial entender cómo interactúa PrestaShop con el sistema de cron.
¿Qué es un Cron Job en el Contexto de PrestaShop?
Un cron job ejecuta un comando PHP que, a su vez, puede llamar a un controlador de PrestaShop, ejecutar un script personalizado o invocar un módulo. PrestaShop ya incluye un sistema de cron interno básico, pero para tareas complejas (como la sincronización inventario o la actualización masiva de datos), es mucho más fiable y eficiente usar los cron del sistema operativo.
[INFO] El cron interno de PrestaShop se basa en que un usuario visite una URL específica (cron.php?token=...). Si tu tienda tiene poco tráfico, este mecanismo puede fallar. Los cron jobs del servidor son la opción profesional.
Configuración Básica de un Cron Job
La mayoría de los paneles de control (cPanel, Plesk, o directo desde SSH) permiten configurar cron jobs. La sintaxis clásica es:
* * * * * /usr/bin/php /ruta/absoluta/a/tu/tienda/cron.php >/dev/null 2>&1
* * * * *: Representa el momento de ejecución (minuto, hora, día del mes, mes, día de la semana).*significa "cada"./usr/bin/php: Ruta al binario de PHP./ruta/absoluta/a/tu/tienda/cron.php: Script a ejecutar.>/dev/null 2>&1: Redirige la salida a un agujero negro para no saturar el log del servidor. Para depuración, usa>> /var/log/prestashop-cron.log 2>&1.
Para ejecutar un script cada hora, usarías 0 * * * *.
Automatización de Tareas Comunes con Scripts Personalizados
Aquí es donde la magia ocurre. Crearemos scripts PHP que se ejecutan fuera del contexto web (CLI) para mayor rendimiento y seguridad. Estos scripts PrestaShop deben cargar el núcleo de la tienda para acceder a sus clases (Db, Product, StockAvailable, etc.).
Script Base para Cargar el Core de PrestaShop
Crea un archivo, por ejemplo /scripts/custom_cron.php, con el siguiente contenido:
<?php
// Script base para cron jobs personalizados en PrestaShop
define('_PS_ADMIN_DIR_', '/ruta/a/tu/admin');
require_once(_PS_ADMIN_DIR_.'/../config/config.inc.php');
require_once(_PS_ADMIN_DIR_.'/../init.php');
// Desactivar límite de tiempo para procesos largos
set_time_limit(0);
// A partir de aquí, puedes usar todas las clases de PrestaShop
echo "Cron iniciado: " . date('Y-m-d H:i:s') . "\n";
?>
Ejemplo 1: Sincronización de Inventario con un Proveedor Externo
La sincronización inventario es una de las tareas más críticas. Un cron job puede ejecutar un script que descargue un CSV de un proveedor, lo procese y actualice el stock en PrestaShop.
<?php
// ... (incluir el script base anterior)
// 1. Descargar el archivo de stock del proveedor (ejemplo FTP o HTTP)
$remoteFile = 'ftp://user:pass@ftp.proveedor.com/stock.csv';
$localFile = _PS_ROOT_DIR_.'/var/tmp/stock_proveedor.csv';
if (!copy($remoteFile, $localFile)) {
echo "Error al descargar el archivo de stock.\n";
exit(1);
}
// 2. Procesar el CSV (asumiendo columnas: referencia, cantidad)
if (($handle = fopen($localFile, "r")) !== FALSE) {
$header = fgetcsv($handle, 1000, ","); // Saltar cabecera
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$reference = pSQL($data[0]);
$quantity = (int)$data[1];
// Buscar el producto por referencia
$id_product = Db::getInstance()->getValue(
'SELECT id_product FROM '._DB_PREFIX_.'product WHERE reference = "'.$reference.'"'
);
if ($id_product) {
// Actualizar el stock (para todas las combinaciones/atributos)
StockAvailable::setQuantity($id_product, null, $quantity);
echo "Producto $reference actualizado a $quantity unidades.\n";
} else {
echo "Producto con referencia $reference no encontrado.\n";
}
}
fclose($handle);
unlink($localFile); // Limpiar archivo temporal
}
echo "Sincronización de inventario completada.\n";
?>
[TIP] Para tiendas con catálogos muy grandes (más de 10,000 productos), es recomendable procesar los datos en lotes de 500 para no saturar la memoria del servidor.
Ejemplo 2: Actualización Masiva de Precios Basada en Reglas
Imagina que necesitas aplicar un descuento del 10% a todos los productos de una categoría específica cada mes.
<?php
// ... (incluir el script base)
$id_category = 5; // ID de la categoría objetivo
$discount_percent = 0.10; // 10%
// Obtener todos los IDs de producto de la categoría
$products = Db::getInstance()->executeS(
'SELECT id_product FROM '._DB_PREFIX_.'category_product WHERE id_category = '.(int)$id_category
);
foreach ($products as $product) {
$id_product = (int)$product['id_product'];
// Obtener el precio base sin impuestos
$base_price = Product::getPriceStatic($id_product, false, null, 2, null, false, true);
// Calcular nuevo precio
$new_price = $base_price * (1 - $discount_percent);
// Actualizar en la base de datos directamente (más rápido que usar ObjectModel)
Db::getInstance()->update(
'product',
array('price' => (float)$new_price),
'id_product = '.$id_product
);
echo "Producto ID $id_product: precio actualizado a $new_price.\n";
}
// Importante: Limpiar la caché de PrestaShop después de cambios masivos
Tools::clearSmartyCache();
Tools::clearXMLCache();
Media::clearCache();
echo "Actualización de precios completada.\n";
?>
Automatización de Tareas de Mantenimiento del Sistema
No todo son ventas e inventario. Los cron jobs son vitales para la salud técnica de la tienda. Estas tareas de mantenimiento previenen la degradación del rendimiento y aseguran la estabilidad.
Regeneración de Miniaturas y Limpieza de Caché
Con el tiempo, las imágenes generadas por PrestaShop pueden corromperse o quedar huérfanas. Un cron job puede regenerarlas en horas de bajo tráfico.
# Ejemplo de cron job para regenerar miniaturas cada domingo a las 3:00 AM
0 3 * * 0 /usr/bin/php /ruta/a/tu/tienda/admin/regenerate.php >/dev/null 2>&1
PrestaShop ya incluye regenerate.php en la carpeta admin, pero puede no ser suficiente. Un script personalizado podría iterar sobre todos los productos y forzar la regeneración.
Limpieza de Sesiones y Tablas Temporales
Las sesiones de clientes y las tablas temporales pueden crecer desmesuradamente.
<?php
// ... (incluir script base)
// Limpiar sesiones antiguas (más de 7 días)
Db::getInstance()->execute(
'DELETE FROM '._DB_PREFIX_.'guest WHERE last_visit_date < DATE_SUB(NOW(), INTERVAL 7 DAY)'
);
Db::getInstance()->execute(
'DELETE FROM '._DB_PREFIX_.'connections WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY)'
);
// Optimizar tablas de la base de datos (cuidado en producción)
$tables = Db::getInstance()->executeS('SHOW TABLES');
foreach ($tables as $table) {
$tableName = current($table);
Db::getInstance()->execute('OPTIMIZE TABLE `'.$tableName.'`');
}
echo "Limpieza de base de datos completada.\n";
?>
[WARNING] La optimización de tablas puede bloquear la tabla durante su ejecución. Realízala en horas de muy bajo tráfico (ej. 4:00 AM).
Integración con Módulos y APIs Externas
La verdadera potencia de la automatización PrestaShop radica en la integración con servicios externos. Un cron job puede actuar como un puente entre tu tienda y un ERP, un CRM, o un sistema de logística.
Sincronización Bidireccional con un ERP
Supongamos que tu ERP expone una API REST. Un script puede:
- Exportar pedidos nuevos desde PrestaShop hacia el ERP.
- Importar estados de envío desde el ERP hacia PrestaShop.
<?php
// ... (incluir script base)
// 1. Obtener pedidos en estado "Pendiente de enviar al ERP" (ID estado = 10)
$orders = Db::getInstance()->executeS(
'SELECT id_order, reference, total_paid_tax_incl FROM '._DB_PREFIX_.'orders WHERE current_state = 10'
);
foreach ($orders as $orderData) {
// Llamada a la API del ERP (ejemplo con cURL)
$ch = curl_init('https://mi-erp.com/api/orders');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($orderData));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer token123'));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 201) {
// Marcar pedido como enviado al ERP
Db::getInstance()->update('orders', array('current_state' => 11), 'id_order = '.$orderData['id_order']);
echo "Pedido {$orderData['id_order']} enviado al ERP.\n";
} else {
echo "Error al enviar pedido {$orderData['id_order']} al ERP.\n";
}
}
?>
Automatización de Campañas de Email Marketing
Puedes crear un script que, cada hora, revise si hay clientes que cumplen ciertos criterios (abandono de carrito, cumpleaños, etc.) y los agregue a una lista de Mailchimp o ActiveCampaign.
Monitoreo, Logging y Buenas Prácticas
Implementar cron jobs sin un sistema de monitoreo es como volar a ciegas. Es fundamental registrar la actividad y saber cuándo algo falla.
Implementar un Sistema de Logs
Modifica el script base para que escriba en un archivo de log con rotación.
<?php
// ... (incluir script base)
$logFile = _PS_ROOT_DIR_.'/var/logs/cron_custom.log';
$message = date('Y-m-d H:i:s') . " - Tarea iniciada.\n";
// Escribir en el log
file_put_contents($logFile, $message, FILE_APPEND);
// ... (lógica del script)
$message = date('Y-m-d H:i:s') . " - Tarea finalizada correctamente.\n";
file_put_contents($logFile, $message, FILE_APPEND);
?>
Notificaciones de Error
Si un script falla, queremos saberlo inmediatamente. Integra notificaciones por email o Slack.
<?php
function sendAlert($subject, $body) {
mail('admin@tutienda.com', '[Cron Error] ' . $subject, $body);
// O enviar a Slack usando webhook
}
// En caso de error crítico:
if ($error) {
sendAlert('Fallo en sincronización de inventario', 'Error: ' . $error);
exit(1);
}
?>
Buenas Prácticas Esenciales
- Usa rutas absolutas en los comandos cron. No asumas rutas relativas.
- Ejecuta los scripts con el usuario correcto (normalmente el mismo que ejecuta el servidor web, ej.
www-data). - Prueba los scripts manualmente antes de programarlos. Ejecútalo desde la terminal:
php /ruta/al/script.php. - Asegura los scripts: Coloca los scripts personalizados fuera del directorio web público (
wwwohtdocs) para que no sean accesibles vía HTTP. Si deben estar dentro, protégelos con.htaccess. - Controla el tiempo de ejecución: Usa
set_time_limit(0)en scripts largos, pero monitorea el consumo de CPU y RAM.
Ejemplo de Configuración Completa en un Servidor
Para finalizar, veamos un ejemplo real de las entradas en el crontab de un servidor que gestiona una tienda PrestaShop de alto tráfico.
# Editar crontab: crontab -e
# Variables de entorno (importante)
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Sincronización de inventario con proveedor (cada hora)
0 * * * * /usr/bin/php /var/www/scripts/sync_stock.php >> /var/log/prestashop/sync_stock.log 2>&1
# Actualización de precios dinámicos (cada 30 minutos)
*/30 * * * * /usr/bin/php /var/www/scripts/update_prices.php >> /var/log/prestashop/update_prices.log 2>&1
# Limpieza de sesiones y optimización de BD (todos los días a las 4:00 AM)
0 4 * * * /usr/bin/php /var/www/scripts/cleanup_db.php >> /var/log/prestashop/cleanup_db.log 2>&1
# Regeneración de miniaturas (cada domingo a las 3:00 AM)
0 3 * * 0 /usr/bin/php /var/www/tienda/admin/regenerate.php >/dev/null 2>&1
# Envío de boletines a través de módulo (cada día a las 10:00 AM)
0 10 * * * /usr/bin/php /var/www/tienda/modules/newsletter/cron.php >/dev/null 2>&1
# Exportación de pedidos al ERP (cada 15 minutos)
*/15 * * * * /usr/bin/php /var/www/scripts/export_orders.php >> /var/log/prestashop/export_orders.log 2>&1
Conclusión: La Automatización como Ventaja Competitiva
La automatización de procesos en PrestaShop mediante cron jobs no es un lujo, sino una necesidad para cualquier tienda que busque escalar de
