Formation Magento 2 : Chapitre 7 – Partie B

Mise en place de la crontab

Mettez en place la crontab de l’utilisateur utilisé pour votre Magento.
Cet utilisateur ne doit pas être root, mais il doit avoir les privilèges et appartenir au groupe « www-data ».
Dans le cas présent, l’utilisateur c’est moi-même.

Si cette partie n’est pas claire pour vous, n’hésitez pas à relire l’article Installation de Magento 2 notamment la mise en place des propriétaires et des permissions du système de fichier.

Avant cela, nous devons trouver le chemin de deux fichier :
– php.ini
– l’exécutable php

Pour le premier, créez un fichier phpinfo.php à la racine de votre Magento et mettez-y :

<?php
phpinfo();

Vous pourrez-y trouver facilement le chemin du php.ini :
php_ini

Pour ma part c’est :
etc/php5/apache2/php.ini

Supprimez le fichier phpinfo.php.

Pour l’exécutable php, lancez la commande :
which php

Pour ma part c’est :
/usr/bin/php

Nous pouvons maintenant créer la crontab !
Lancez la commande :
sudo crontab -u <magento_user> -e
Mon utilisateur (magento_user) c’est : maxime

Le contenu de ma crontab est le suivant, a vous d’adatper avec le bon chemin du php.ini et de l’exécutable php :

*/1 * * * * /usr/bin/php -c etc/php5/apache2/php.ini /var/www/magento2/bin/magento cron:run >> /var/www/magento2/var/log/magento.cron.log&
*/1 * * * * /usr/bin/php -c etc/php5/apache2/php.ini /var/www/magento2/update/cron.php >> /var/www/magento2/var/log/update.cron.log&
*/1 * * * * /usr/bin/php -c etc/php5/apache2/php.ini /var/www/magento2/bin/magento setup:cron:run >> /var/www/magento2/var/log/setup.cron.log&

– */1 * * * * : Le cron est lancé toutes les minutes
– /usr/bin/php : c’est l’exécutable php
– etc/php5/apache2/php.ini : c’est le PHP ini que l’on a récupéré
– /var/www/magento2/ : c’est la racine de votre installation Magento 2
– >> : Ce qu’il y’a après c’est un fichier de log qui permet de débugguer au cas où l’une des tâches ne se passe pas comme prévu

La première commande lance les cron Magento.
Les deux suivantes concernent le « Component Manager » et le « System Upgrade » (Qui ne nous intéressent dans cette leçon).

Création d’un cron dans un module Magento 2

Maintenant que nos tâches sont planifiées, nous allons créer notre propre cron !

Créez le fichier :
app/code/Maxime/Jobs/etc/crontab.xml

Avec le contenu suivant:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="default">
        <job name="maxime_jobs_disable_jobs" instance="Maxime\Jobs\Cron\DisableJobs" method="execute">
            <!-- Every five minutes -->
            <schedule>*/5 * * * *</schedule>
            <!--<config_path>jobs/cron/schedule</config_path>-->
        </job>
    </group>
</config>

– group_id : permet de cibler les tâches à lancer, nous allons aborder ce point plus tard dans l’article
– name : le nom de notre tâche, il doit être unique
– instance : la classe qui va lancer notre tâche cron
– method : la méthode de notre classe qui sera appelée
– schedule : la périodicité de notre cron au Format Cron
– config_path : Vous pouvez mettre cette balise à la place de schedule. Cela permet de récupérer la périodicité du cron dans une configuration éditable en BO, nous allons le faire plus tard dans cet article

Nous avons déclaré une classe et une méthode, nous allons les créer !
Ajoutez le fichier :
app/code/Maxime/Jobs/Cron/DisableJobs.php

Et mettez ce contenu :

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Maxime\Jobs\Cron;

class DisableJobs
{
    /**
     * @var \Maxime\Jobs\Model\Job
     */
    protected $_job;

    /**
     * @param \Maxime\Jobs\Model\Job $job
     */
    public function __construct(
        \Maxime\Jobs\Model\Job $job
    ) {
        $this->_job = $job;
    }

    /**
     * Disable jobs which date is less than the current date
     *
     * @param \Magento\Cron\Model\Schedule $schedule
     * @return void
     */
    public function execute(\Magento\Cron\Model\Schedule $schedule)
    {
        $nowDate = date('Y-m-d');
        $jobsCollection = $this->_job->getCollection()
            ->addFieldToFilter('date', array ('lt' => $nowDate));

        foreach($jobsCollection AS $job) {
            $job->setStatus($job->getDisableStatus());
            $job->save();
        }
    }
}

Nous souhaitons maintenant tester si notre méthode fait bien son travail.
Il vous faudra attendre dans quelques article pour le savoir sur les tests unitaires.
Pour le moment considérez qu’il fonctionne 🙂

Nous allons faire d’autres tests dans la suite de la leçon, pour le moment vous pouvez continuer à le parcourir.

Vérifier les cron en attente

Vous l’aurez peut-être compris, mais Magento possède des tâches qui tournent toutes les minutes.
Dans une de ces tâches, il va vérifier tous les fichiers crontab.xml qu’il trouve, et programmer les prochains jobs à lancer.

Mais où sont-elles sauvegardées?

Ceux qui ont développé avec Magento 1 devraient le savoir, c’est la table cron_schedule

cron_schedule

On y retrouve :
– Le job code qui est mis dans le fichier xml
– Le statut de la tâche
– Le/les message(s) s’il y’en a, c’est possible qu’en cas d’erreur, des Exceptions soient dedans.
– La date de création de la tâche
– La date de programmation de la tâche
– La date à laquelle la tâche a démarré
– La date à laquelle la tâche s’est terminée (si tout se passe bien)

Les groupes de cron

Comme vous avez pu le constater, nous définissons un group_id dans notre fichier XML.
De base, Magento définit 2 groupes de cron :
– default (Magento le lance toutes les 15 minutes par défaut, donc si vous créez une tache toutes les minutes, elle ne se lancera en réalité que toutes les 15 minutes)
– index (Magento le lance toutes les minutes)

Selon votre besoin, vous pouvez très bien rattacher votre cron à l’un de ces 2 groupes.
A quoi sert la création de ces groupes ?
Cela permet de lancer des tâches cron en parallèle.

Par exemple, vous avez un cron qui va générer un flux, et celui-ci est assez long à exécuter.
Pour éviter de bloquer les autre tâches, mettez le dans un groupe spécifique, et il pourra être lancé, sans bloquer les autres cron des autres groupes.

Les 2 groupes définis par défaut dans Magento permettent donc de lancer les cron du group default, alors que l’autre groupe est en train de lancer les réindexations.

img_cron_parallel

Lancer un cron via une commande shell

Voici la commande à lancer à la racine de votre Magento :
./bin/magento magento cron:run [--group=""]

Pour lancer tous les groupes :
./bin/magento magento cron:run

Pour lancer le groupe default :
./bin/magento magento cron:run --group="default"

Pour lancer un groupe custom :
./bin/magento magento cron:run --group="maxime_jobs"

Notez que vous devrez lancer le cron 2 fois. La première va insérer les tâches à programmer dans la table cron_schedule. La deuxième va lancer les tâches programmées.

Configurer les cron dans l’admin Magento

Certains comportements du système de cron sont paramétrables dans l’admin.
Pour cela il faut se rendre dans Stores > Configuration > Advanced > System

Vous remarquerez qu’il y’a une section pour les cron :

cron_config

La première concerne le groupe default, la deuxième concerne le groupe default

Les paramètres sont les suivants :

Option Description
schedule_generate_every Détermine la fréquence, en minutes, de génération des tâches du groupe dans la table cron_schedule.
schedule_ahead_for Détermine combien de minutes à l’avance doivent être programmés les tâches dans la table cron_schedule.
schedule_lifetime Si le cron n’est pas lancé X minutes après son heure de programmation, il sera considéré comme échoué
history_cleanup_every Détermine tous les combien de minutes l’historique des tâches doit-être nettoyé dans la table cron_schedule
history_success_lifetime Détermine le nombre de minute que doivent être gardées les tâches qui ont réussies dans la table cron_schedule
history_failure_lifetime Détermine le nombre de minute que doivent être gardées les tâches qui ont échouées dans la table cron_schedule
use_separate_process Si défini à 1, chaque tâche du groupe sera lancé dans un processus séparé. Sinon les tâches du groupe seront lancées dans un même processus.

Vérifier que mon cron est programmé

J’ai fait exprès de programmer le cron toutes les 5 minutes pour vérifier facilement si la tâche s’ajoute correctement en BDD.
Pour cela, rendez-vous dans la table cron_shedule, et notre tâche doit apparaître :

custom_cron_sheduled

Si vous ne voulez pas attendre que la programmation de la crontab se lance, vous pouvez utiliser la ligne de commande :
./bin/magento magento cron:run

A chaque modification du fichier crontab.xml, n’hésitez pas à supprimer les dossier /var/cache et /var/generation pour être sûr que les modifications soient prises en compte

Créer un groupe de cron

Modifiez le crontab.xml comme ceci :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="maxime_jobs">
        <job name="maxime_jobs_disable_jobs" instance="Maxime\Jobs\Cron\DisableJobs" method="execute">
            <!-- Every five minutes -->
            <schedule>*/5 * * * *</schedule>
            <!--<config_path>jobs/cron/schedule</config_path>-->
        </job>
    </group>
</config>

Supprimez les tâches créées dans la table cron_shedule portant le job_code « maxime_jobs_disable_jobs »

Supprimez les dossier /var/cache et /var/generation

Puis relancez la commande pour lancer les cron :
./bin/magento magento cron:run

Si vous vérifiez en BDD, notre job ne sera pas programmé !

Pourquoi ? Car la configuration dans Magento concerne les groupes index et default. Notre groupe n’a pas de configuration !

Pour cela créez le fichier :
app/code/Maxime/Jobs/etc/cron_groups.xml

Mettez-y ce contenu :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/cron_groups.xsd">
    <group id="maxime_jobs">
        <schedule_generate_every>15</schedule_generate_every>
        <schedule_ahead_for>20</schedule_ahead_for>
        <schedule_lifetime>15</schedule_lifetime>
        <history_cleanup_every>10</history_cleanup_every>
        <history_success_lifetime>60</history_success_lifetime>
        <history_failure_lifetime>600</history_failure_lifetime>
        <use_separate_process>0</use_separate_process>
    </group>
</config>

On y retrouve la configuration que l’on a vu précédemment, mais cette fois-ci elle concerne le groupe que l’on vient de créer.

Supprimez les dossier /var/cache et /var/generation

Puis relancez la commande pour lancer les cron :
./bin/magento magento cron:run

Et la notre job apparaît correctement !

Mettre en configuration la périodicité

Nous allons maintenant mettre en configuration la périodicité de notre cron.
Pour cela, modifiez le fichier crontab.xml :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="maxime_jobs">
        <job name="maxime_jobs_disable_jobs" instance="Maxime\Jobs\Cron\DisableJobs" method="execute">
            <!-- Configuration expression -->
            <config_path>jobs/cron/schedule</config_path>
            <!--<schedule>*/5 * * * *</schedule>-->
        </job>
    </group>
</config>

Maintenant nous allons ajouter un nouveau champ de configuration.

Modifiez le fichier :
app/code/Maxime/Jobs/etc/adminhtml/system.xml

Et remplacez le avec ce contenu :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="jobs" translate="label" sortOrder="1000">
            <label>Jobs</label>
        </tab>
        <section id="jobs" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Jobs</label>
            <tab>jobs</tab>
            <resource>Maxime_Jobs::jobs</resource>
            <group id="department" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Department configuration</label>
                <field id="view_list" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Show job list</label>
                    <comment>Show department's job list of the viewing department</comment>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
            </group>
            <group id="cron" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
                <label>Cron configuration</label>
                <field id="schedule" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Schedule</label>
                    <comment><![CDATA[
<pre>
* * * * *
| | | | |
| | | | +---- Day of the Week   (range: 1-7, 1 standing for Monday)
| | | +------ Month of the Year (range: 1-12)
| | +-------- Day of the Month  (range: 1-31)
| +---------- Hour              (range: 0-23)
+------------ Minute            (range: 0-59)
Example: 0 0 * * * Daily at midnight
</pre>
                            ]]></comment>
                </field>
            </group>
       </section>
    </system>
</config>

Puis, modifiez le fichier :
app/code/Maxime/Jobs/etc/config.xml

Pour y mettre ceci :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <jobs>
            <department>
                <view_list>1</view_list>
            </department>
            <cron>
                <!-- Every day at midnight -->
                <schedule>0 0 * * *</schedule>
            </cron>
        </jobs>
    </default>
</config>

Par défaut nous mettons la valeur à minuit tous les jours.
Vous devez avoir l’affichage suivante dans la configuration de notre module :

cron_configuration

Mais maintenant cette valeur est modifiable selon vos besoins.
N’hésitez pas à la modifier pour vérifier que la tâche se programme correctement en BDD.

Ca sera tout pour les cron ! Prochaine étape, nous allons mettre en place notre helper !

Continuer la formation
Revenir à la partie précédente
Création d’une tâche cron avec Magento 2
Taggé sur :        

3 thoughts on “Création d’une tâche cron avec Magento 2

  • 18/04/2016 à 17:03
    Permalink

    Bonjour,
    Je guette les mises à jour de votre formation qui m’a jusqu’ici beaucoup aidée ! Je voulais savoir : pensez-vous aborder les api REST et SOAP également ?
    Merci et bonne continuation

    Répondre
    • 18/04/2016 à 17:08
      Permalink

      Oui c’est prévu mais je ne peux vraiment pas donner de visibilité sur la suite des leçons.
      Ca me prend du temps et je ne programme pas du temps pour ça, je vois au jour le jour ^^

      J’avais pensé à un système d’alerte email pour avertir les utilisateurs, mais finalement le flux RSS est suffisant (étant donné que les nouveaux articles sont quasi tous des articles de la formation) :
      http://www.maximehuran.fr/feed/

      Répondre
  • 14/12/2016 à 06:28
    Permalink

    Salut, j’ai tout suivi, même des tutos en anglais. D’abord je me retrouvais avec 128M en erreur, j’en ai bavé pour trouver comme ça marche. Pour finir, je vais enfin pour installer un module et j’ai un pending intall infini qui me met le site en maintenance…
    Sinon le « magento_user » ça équivaut à quoi exactement, au root du serveur, au login de l’admin, au root -www ??? Je ne comprends absolument rien.
    J’ai 2 fichiers php.ini, j’ai beau modifier leur memory_limit, redemarrer le serveur, ca ne change rien.

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous utilisons des cookies afin de nous assurer de vous proposer la meilleure expérience sur ce site.
Ok