Contrairement à d’autres plateformes l’exécution et la planification des tâches cron sur prestashop n’a rien d’intuitif pour l’utilisateur de l’administration ou pour le développeur.
C’est assez dommage sachant qu’elles sont indispensables pour faire tourner correctement une boutique et pour raffraichir entre autre les indexes de recherches ou de la navigation à facettes.

Nous allons voir ensemble comment gérer les cron ( ou tâches planifiées ) sur la dernière version 1.7 de Prestashop. ( La logique est la même pour les anciennes versions )

Installation du module cronjobs

Prestashop propose un module gratuit “cronjobs“qui est inclu nativement pour les versions antérieures, mais celui-ci n’est plus trouvable sur la version 1.7
Sa seule limite, et que la granularité des tâches est d’une heure, ce qui est amplement suffisant pour l’essentiel des sites e-commerce basiques.

Pour l’installer il faut récupérer le code sur github : https://github.com/PrestaShop/cronjobs

Une fois le module installé dans sa configuration, il faut choisir le mode “Expert” car le mode basique qui permettait de lancer des crons via un service proposé par Prestashop, n’est plus fonctionnel c’est malheureusement inutile d’essayer de l’utiliser 🙁

Cronjobs prestashop

Le mode expert nous donne l’url à définir dans la crontab de notre serveur ( je reviendrais ultérieurement sur la configuration sur un hébergement OVH mutualisé ) .
Cette url se chargera ensuite d’exécuter l’ensemble des tâches planifiées que nous allons définir.

Ajout d’url basiques

Nous pouvons ensuite ajouter les différentes urls nécessaires au bon fonctionnement de notre boutique

  • mise à jour de la navigation à facettes
  • mise à jour des sitemaps

Via l’interface qui est proposée nativement par le module

Ajouter tâche cron

Ajout des tâches cron d’un module

Jusque la ce module fait aussi bien que l’autre module très utilisé pour les tâches crons  ( http://www.prestatoolbox.fr/modules-gratuits/115-crontab.html)
Mais pour moi le gros avantage du module natif prestashop et qu’il est possible d’ajouter automatiquement des tâches crons via des modules 🙂

Pour faire cela c’est très simple, pour l’exemple nous allons réaliser un module hh_cronuser qui souhaite exécuter une tâche planifiée toutes les heures.

Pour cela il suffit de respecter les pré-requis suivants :

  • le module doit implémenter le hook actionCronJob
  • le module doit définir sa périodicité via une fonction getCronFrequency

Pour l’ensemble du fonctionnement vous pouvez voir les commentaires dans le code complet du module ci-dessous :

class Hh_CronUser extends Module {
 
    public function __construct() {
        $this->author = 'hhennes';
        $this->name = 'hh_cronuser';
        $this->tab = 'administration';
        $this->version = '0.1.0';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('HH Cron User');
        $this->description = $this->l('HH Sample Module with cron possibilities');
        $this->dependencies = array('cronjobs'); // Dépendance à mettre en place si obligatoire
    }
 
    /**
     * Installation du module
     * @return boolean
     */
    public function install() {
        if (!parent::install() || !$this->registerHook('actionCronJob') // Hook à implémenter 
        ) {
            return false;
        }
 
        return true;
    }
 
    /**
     * Hook d'exécution de la crontab
     */
    public function hookActionCronJob() {
 
        //Exemple basique on va créer un fichier de log et insérer un contenu dès que la tache cron est appellée
        $fp = fopen(dirname(__FILE__) . '/cron.log', 'a+');
        fputs($fp, 'CALLED at ' . date('Y-m-d H:i:s'));
        fclose($fp);
 
        //Exemple plus avancé, on souhaite effectuer des taches différentes en fonction de l'heure
        $hour = date('H');
 
        switch ($hour) {
            case 07:
                //Lancement des actions du matin
                break;
 
            case 12:
                //Lancement des actions du midi
                break;
            case 18:
                //Lancement des actions du soir
                break;
            default:
                //Action par défaut
                break;
        }
    }
 
    /**
     * Information sur la fréquence des taches cron du module
     * Granularité maximume à l'heure
     */
    public function getCronFrequency() {
        return array(
            'hour' => -1, // -1 equivalent à * en cron normal
            'day' => -1, 
            'month' => -1,
            'day_of_week' => -1
        );
    }
 
}

Lors de l’installation de notre module celui-ci va automatiquement enregistré sa tâche planifiée à la fréquence souhaitée, comme vous pouvez le voir sur la capture suivante :

Crontab module

Vous remarquez qu’il n’est possible d’enregistrer qu’une seule tâche par module, mais en cas de nécessité de plusieurs tâches à des moments différents vous pouvez toujours lancer le module toutes les heures et gérer la logique et les horaires directement dans le module comme dans mon exemple 🙂

Cas spécifique hébergement mutualisé ovh :

Chez ovh un certain nombre de restriction s’appliquent et il n’est pas possible de saisir la commande données dans le module.

Pour contourner cela nous allons donc créer un fichier “cron.php” que nous allons placer dans la racine du dossier d’administration de prestashop avec le contenu suivant :

 

<?php
/**
 * Lancement des scripts cron
 * Utilise le module prestashop cronjobs
 * Permets de planifier les tâches via l'administration
 * Lancer ce script à minima toutes les heures
 */
ini_set('display_errors','on');
include dirname(__FILE__) . '/../config/config.inc.php';
$link = new Link();
$shop_url = $link->getBaseLink();
$admin_dir = basename(dirname(__FILE__));
$cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN');
$cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token;
echo Tools::file_get_contents($cronUrl);

Dans le manager OVH il faudra ensuite appeller l’url http://www.votre-site.com/admin-dir/cron.php toutes les heures pour que les taches crons s’exécutent 🙂