Tâches Cron : souhaitez un joyeux anniversaire à vos clients
- Par Magentix le 19/10/2009
- Difficulté : 3/4
Ce module d'exemple va nous permettre d'appréhender l'utilisation des tâches Cron sous Magento. Une méthode exécutée quotidiennement expédiera un e-mail si la date du jour correspond à la date d'anniversaire du client.
Magento exécute automatiquement et périodiquement un certain nombre de scripts via les tâches Cron : mise à jour des règles de prix catalogue, envoi des newsletters, génération du fichier sitemap ou encore nettoyage des logs.
La plateforme nous permet de programmer facilement de nouvelles tâches personnalisées directement depuis les fichiers XML de configuration. Pour exécuter ces tâches configurées, il suffit de faire régulièrement appel au fichier cron.php situé à la racine du site. Ainsi, lors de la configuration du fichier contrab sur le serveur, on indique simplement le chemin vers ce fichier :
Exécution du fichier cron.php toutes les 15 minutes
* / 15 * * * * /home/site/www/cron.php
Un tutoriel sur la configuration de crontab sous l'interface Webmin a été rédigé par Gabriiiel sur Fragento : Mise en place d'une tâche cron Magento via Webmin.
A défaut de pouvoir configurer le service crontab sur votre serveur, vous pouvez accéder au fichier depuis votre navigateur : http://www.example.com/cron.php. A mettre en page de démarrage par exemple... ou à exécuter depuis un Web Service externe (Ex : Webcron).
Afin de mettre en pratique la configuration d'une nouvelle tâches Cron, nous allons développer un module d'exemple. Une méthode se chargera d'envoyer un e-mail aux utilisateurs dont c'est l'anniversaire.
Pour que les clients puissent saisir leur date de naissance, activons l'option depuis la configuration :
Système > Configuration > Clients > Configuration client > Options de nom et d'adresse > Afficher la date de naissance.
Architecture du module
- app/code/local/Magentix/HappyBirthday/etc/
- config.xml
- system.xml
- app/code/local/Magentix/HappyBirthday/Helper/
- Data.php
- app/code/local/Magentix/HappyBirthday/Model/
- Observer.php
- app/locale/fr_FR/template/email/
- happybirthday.html
- app/etc/modules/
- Magentix_HappyBirthday.xml
Développement du module
Commençons par déclarer le nouveau module depuis le fichier Magentix_HappyBirthday.xml :
app/etc/modules/Magentix_HappyBirthday.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_HappyBirthday>
<active>true</active>
<codePool>local</codePool>
</Magentix_HappyBirthday>
</modules>
</config>
L'extension expédie un e-mail aux internautes. Nous nous servirons du puissant moteur de template mail de Magento. Le fichier happybirthday.html correspond à notre template mail par défaut. Par la suite, les fichiers de configurations du module permettront d'activer la personnalisation du template depuis la gestion des e-mails transactionnels de l'administration. Veillez à ce que l'encodage du fichier soit en UTF-8.
app/locale/fr_FR/template/email/happybirthday.html
<!--@subject Joyeux anniversaire @-->
<p>Bonjour {{var name}},</p>
<p>Toute l'équipe de <strong>Magentix</strong> vous souhaite un très bon anniversaire !</p>
<p>A très vite sur magentix.fr ! <br /> <a href="http://www.magentix.fr">http://www.magentix.fr</a></p>
Notre classe Magentix_HappyBirthday_Helper_Data restera très basique...
app/code/local/Magentix/HappyBirthday/Helper/Data.php
<?php
class Magentix_HappyBirthday_Helper_Data extends Mage_Core_Helper_Abstract {
}
Attaquons ensuite la méthode de la classe Magentix_HappyBirthday_Model_Observer chargée de récupérer les clients dont c'est l'anniversaire et d'expédier le message. C'est cette méthode que l'on appellera automatiquement une fois par jour via la nouvelle tâche Cron :
app/code/local/Magentix/HappyBirthday/Model/Observer.php
<?php
class Magentix_HappyBirthday_Model_Observer {
const XML_PATH_EMAIL_TEMPLATE = 'happybirthday/email/email_template';
const XML_PATH_EMAIL_SENDER = 'happybirthday/email/sender_email_identity';
public function sendMail($schedule) {
$customers = Mage::getModel('customer/customer')
->getCollection()
->addAttributeToSelect('firstname')
->addAttributeToSelect('lastname')
->addAttributeToFilter('dob',array('like'=>'%-'.date('m-d').' %'))
->load();
foreach($customers as $c) {
$mailTemplate = Mage::getModel('core/email_template');
$mailTemplate->setDesignConfig(array('area' => 'frontend'))
->sendTransactional(
Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE),
Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER),
$c->getEmail(),
$c->getName(),
array('name' => $c->getName())
);
}
}
}
Nous pouvons enfin éditer les fichiers de configuration. Notre tâche Cron se déclare en quelques lignes depuis le fichier config.xml. On y indique la périodicité d'exécution du script et le nom de la méthode de l'observer (ici sendMail) :
app/code/local/Magentix/HappyBirthday/etc/config.xml
<config>
<!-- ... -->
<crontab>
<jobs>
<happybirthday_send_mail>
<schedule><cron_expr>0 4 * * *</cron_expr></schedule>
<run><model>happybirthday/observer::sendMail</model></run>
</happybirthday_send_mail>
</jobs>
</crontab>
</config>
La méthode sera donc exécutée quotidiennement à 04h00.
Les autres déclarations des fichiers de configuration servent à la gestion du module et du template mail Happy Birthday depuis l'administration, et indiquent à Magento les classes du module :
app/code/local/Magentix/HappyBirthday/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_HappyBirthday>
<version>1.0</version>
</Magentix_HappyBirthday>
</modules>
<global>
<models>
<happybirthday>
<class>Magentix_HappyBirthday_Model</class>
</happybirthday>
</models>
<helpers>
<happybirthday>
<class>Magentix_HappyBirthday_Helper</class>
</happybirthday>
</helpers>
<resources>
<happybirthday_setup>
<setup>
<module>Magentix_HappyBirthday</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</happybirthday_setup>
</resources>
<template>
<email>
<happybirthday_email_email_template translate="label" module="happybirthday">
<label>Happy Birthday</label>
<file>happybirthday.html</file>
<type>html</type>
</happybirthday_email_email_template>
</email>
</template>
</global>
<adminhtml>
<acl>
<resources>
<admin>
<children>
<system>
<children>
<config>
<children>
<happybirthday translate="title" module="happybirthday">
<title>HappyBirthday</title>
</happybirthday>
</children>
</config>
</children>
</system>
</children>
</admin>
</resources>
</acl>
</adminhtml>
<default>
<happybirthday>
<email>
<recipient_email><![CDATA[hello@example.com]]></recipient_email>
<sender_email_identity>general</sender_email_identity>
<email_template>happybirthday_email_email_template</email_template>
</email>
</happybirthday>
</default>
<crontab>
<jobs>
<happybirthday_send_mail>
<schedule><cron_expr>0 4 * * *</cron_expr></schedule>
<run><model>happybirthday/observer::sendMail</model></run>
</happybirthday_send_mail>
</jobs>
</crontab>
</config>
app/code/local/Magentix/HappyBirthday/etc/system.xml
<config>
<sections>
<happybirthday translate="label" module="happybirthday">
<label>Happy Birthday</label>
<tab>general</tab>
<frontend_type>text</frontend_type>
<sort_order>101</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<email translate="label">
<label>Email Options</label>
<frontend_type>text</frontend_type>
<sort_order>50</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<sender_email_identity translate="label">
<label>Email Sender</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_email_identity</source_model>
<sort_order>20</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</sender_email_identity>
<email_template translate="label">
<label>Email Template</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_email_template</source_model>
<sort_order>30</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</email_template>
</fields>
</email>
</groups>
</happybirthday>
</sections>
</config>
Pour tester le module en local ou sur un serveur de pré-production je vous conseille de définir la périodicité d'exécution du script à chaque fois que le cron est lancé (* * * * *) puis d'accéder au fichier cron.php depuis le navigateur.
J'ai utilisé votre tutorial pour créer un module qui envoie un mail lors de l'annulation d'une commande, l'envoie des emails fonctionne très bien avec votre méthode, mais j'ai cependant un problème.
Dans mon template email, j'ai des images. Je récupère les url des images avec un snippet de ce genre :
<img src="{ {skin url="images/img_auchan/fioul/spacer.gif" } }" alt="" height="20"/>.
Ca fonctionne bien pour les templates des emails de base, mais pour celui que j'ai ajouté, l'URL générée n'est pas correcte.
En effet, je travaille avec le design "enterprise/mondesign" mais les URL que magento me génère sont du type "base/default". Encore une fois, ce problème ne se pose pas avec les emails de base, j'ai la bonne URL pour les images.
J'ai comparé le code d'envoi d'email pour la confirmation de commande, mais je ne vois pas de différence qui justifie cette non prise en compte du design.
Vous auriez une idée de l'origine du problème?
Merci.
PS: j'utilise souvent votre site, c'est l'une des meilleures sources francophone sur Magento. :-)
En effet, plutôt étrange qu'il ne prenne pas en compte le design courant pour l'envoie du mail. J'exécuterai quelques tests pour vérifier...
Je me permets de vous demander conseil après avoir utilisé un temps ce module bien pratique.
Nous avons changer d'hébergeur il y a quelques mois, chez ce dernier, lorsque nous utlisions ce module, le mail à destination du client lui etait envoyé 5 ou 6 fois dans la même minute. Notre hebergeur et nous même n'avions pas réussi à comprendre pourquoi, et nous avons décidé de mettre le module en sommeil. Dernièrement , nous avons changé d'hebergeur et en essayant de réactiver ce module, nous nous sommes aperçu d'une erreur lors du lancement manuel du fichier cron.php.
Lorsque nous executons le fichier cron.php ( http://www.domaine.com/cron.php ), nous avons l'erreur suivante :
Fatal error: Uncaught exception 'Exception' with message 'Warning: simplexml_load_string() [<a href='function.simplexml-load-string'>function.simplexml-load-string</a>]: Entity: line 8: parser error : Opening and ending tag mismatch: Mesmodules_Homegabarit line 5 and Mesmodules_Rayons in /var/www/html/virtualdomains/13120/domaine.com/www/lib/Varien/Simplexml/Config.php on line 510' in /var/www/html/virtualdomains/13120/domaine.com/www/app/code/core/Mage/Core/functions.php:239 Stack trace: #0 [internal function]: mageCoreErrorHandler(2, 'simplexml_load_...', '/var/www/html/v...', 510, Array) #1 /var/www/html/virtualdomains/13120/domaine.com/www/lib/Varien/Simplexml/Config.php(510): simplexml_load_string('<?xml version="...', 'Mage_Core_Model...') #2 /var/www/html/virtualdomains/13120/domaine.com/www/lib/Varien/Simplexml/Config.php(498): Varien_Simplexml_Config->loadString('<?xml version="...', 'Mage_Core_Model...') #3 /var/www/html/virtualdomains/13120/domaine.com/www/app/code/core/Mage/Core/Model/Config.php(625): Va in /var/www/html/virtualdomains/13120/domaine.com/www/app/code/core/Mage/Core/functions.php on line 239
Je vous avoue que le code n'est pas notre spécialité, et ce genre de configuration encore moins !
Auriez vous une piste sur laquelle nous orienter pour régler ce problème ?
Est ce à l'hébergeur de s'en occuper ?
A nous de configurer quelque chose en particulier ?
D'avance merci.
Tes commentaires m'ont mis sur une piste, et effectivement, un module n'etait pas déclaré convenablement !
J'ai modifié la déclaration de ce module (dont j'ignore l'utilité et le rendu, incroyable !), et le lancement du cron.php ne pose plus de problème.
En revanche, en configuration "test", c'est à dire en lançant le cron manuellement, sans y preciser de jour ni d'heure...je ne reçois pas le mail (coté client).
Dois je me pencher sur un nouveau problème ?
Le processus d'envoi est bien lancé, mais malgré un parametrage * * * * * dans la config' du XML, les mails ne sont pas envoyés "en live", mais vers 2h du matin...
Effectivement la bonne nouvelle est que le module fonctionne parfaitement.
Nous allons refaire un est demain pour voir si l'heure d'envoi est différente...je ferai un retour ici...croisons les doigts ;)
Merci
- " Pour lancer l'exécution de mes taches, je lance le cron.php manuellement (http://www.xxxxxxxxxxxx.com.cron.php). J'ai programmé le module "Happy Birthday" pour un envoi des emails à 12h (midi). Dois je lancer le cron avant ou apres 12h ? Y'a t il une importance dans l'heure à laquelle j'execute le cron (par exemple si je le lance à 14h, les emails programmés pour 12h seront ils quand même pris en compte) ? "
Fin de la question idiote, mais qui méritait que je la pose ;)
Merci
Bon je reviens aux nouvelles suite à mon test.
J'ai configuré le config.xml du module Happy Birthday pour un envoi à 12h.
Cette nuit, j'ai lancé la tache cron manuellement vers 2h.
A 12h les mails n'étaient pas partis.
J'ai alors modifié le config.xml en lui assignant un : * * * * * + vidé le cache...
J'ai relancé la tache cron croyant que le mails allaient partir "dans l'instant"...et bien non, toujours pas de mails à l'horizon.
Je vais surveiller les boites mails pour voir si ils partent dans la journée, et si oui, à quelle heure.
Je ne sais pas trop d'où peut venir le hic. De mon cron.php ? De mon config.xml ? De mon hebergeur ? J'ai peu de notions concernant les serveurs :s ça n'aide pas, mais on va bien finir pas trouver une solution ! ;)
Merci pour ce module très intéressant :)
Je cherche à envoyer plusieurs mails de relance à mes clients, je me suis donc inspiré de ce module pour faire un mail de relance.
Cependant je souhaiterais en envoyer plusieurs différents et j'ai un peu de mal à voir où cela se passe et quoi modifier dans les différents fichiers. Si vous aviez des indications (sans pour autant faire le boulot à ma place hein...) à me donner je vous en serais très reconnaissant !
Merci d'avance,