Ce tutoriel explique comment créer un module qui ajoute une coche « Inscription à la newsletter » dans le récapitulatif de commande de Magento. Cette étape – la dernière avant paiement – est particulièrement propice pour capter l’attention de l’internaute qui est très forte à cet instant. On peut en espérer un nombre plus important d’abonnements à la newsletter. Tout client non inscrit à la newsletter se verra proposer l’inscription. A l’inverse, s’il est déjà inscrit, l’option d’inscription n’apparaîtra pas.

Dans cet exemple, nous utilisons un module appelé Soon_NewsletterCheckout. Développements réalisés et testés sur Magento CE 1.6.0.0.
Déclarer le module
Fichier /app/etc/modules/Soon_NewsletterCheckout.xml
1 2 3 4 5 6 7 8 9 | <?xml version="1.0"?> <config> <modules> <Soon_NewsletterCheckout> <active>true</active> <codePool>local</codePool> </Soon_NewsletterCheckout> </modules> </config> |
Configuration du module
Fichier /app/code/local/Soon/NewsletterCheckout/etc/config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?xml version="1.0"?> <config> <modules> <Soon_NewsletterCheckout> <version>0.1.0</version> </Soon_NewsletterCheckout> </modules> <global> <blocks> <newslettercheckout> <class>Soon_NewsletterCheckout_Block</class> </newslettercheckout> </blocks> <helpers> <newslettercheckout> <class>Soon_NewsletterCheckout_Helper</class> </newslettercheckout> </helpers> <models> <newslettercheckout> <class>Soon_NewsletterCheckout_Model</class> </newslettercheckout> </models> </global> <frontend> <events> <controller_action_predispatch_checkout_onepage_saveOrder> <observers> <newslettercheckout_session> <type>singleton</type> <class>newslettercheckout/observer</class> <method>setSubscribeSession</method> </newslettercheckout_session> </observers> </controller_action_predispatch_checkout_onepage_saveOrder> <sales_order_place_after> <observers> <newslettercheckout_subscribe> <type>singleton</type> <class>newslettercheckout/observer</class> <method>subscribe</method> </newslettercheckout_subscribe> </observers> </sales_order_place_after> </events> <translate> <modules> <Soon_NewsletterCheckout> <files> <default>Soon_NewsletterCheckout.csv</default> </files> </Soon_NewsletterCheckout> </modules> </translate> </frontend> </config> |
Explications du code
Nous plaçons un observer au moment auquel le processus de validation de commande commence (controller_action_predispatch_checkout_onepage_saveOrder) pour récupérer l’email du client si « Inscription à la newsletter » est coché.
Ceci permet de :
- garder le statut de la coche en session et ainsi la précocher automatiquement si l’enregistrement de la commande échoue et que l’internaute recommence le processus de checkout
- garantir l’inscription des internautes passant commande en mode invité. Dans l’observer, l’email sera récupéré depuis la quote plutôt que depuis le compte client qui n’existe pas si l’internaute commande pour la première fois ou qu’il commande en tant qu’invité.
- si l’internaute repasse dans le tunnel de commande, la coche « Inscription à la newsletter » aura disparu ce qui peut porter à confusion
- un internaute n’a pas forcément envie d’être inscrit à la newsletter d’une société auprès de laquelle il n’a pas encore commandé.
Nous observons ensuite l’enregistrement effectif de la commande, moment auquel nous inscrivons effectivement l’internaute à la newsletter. On pourrait choisir de réaliser l’inscription dès la validation de commande mais plusieurs raisons nous ont poussé à prendre partie pour l’inscription une fois la commande enregistrée. En effet, dans ce scénario alternatif, si la commande échoue, l’internaute sera inscrit à la newsletter.
A vous de choisir votre stratégie !
Fichier d’Observer
Fichier /app/code/local/Soon/NewsletterCheckout/Model/Observer.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class Soon_NewsletterCheckout_Model_Observer extends Mage_Core_Model_Abstract { protected $_newsletterCheckout; /** * Set subscribe option to session in order to remember checkbox * and use on order save. * * @return Soon_NewsletterCheckout_Model_Observer */ public function setSubscribeSession() { $newsletterCheckout = false; $postedSubscription = Mage::app()->getRequest()->getPost('newslettercheckout', array()); if(isset($postedSubscription['agree'])) { $this->_newsletterCheckout = Mage::helper('checkout')->getQuote()->getCustomerEmail(); } Mage::getSingleton('checkout/session')->setNewsletterCheckout($this->_newsletterCheckout); return $this; } /** * Subscribe customer to newsletter on order place * * @return Soon_NewsletterCheckout_Model_Observer */ public function subscribe() { if($email = $this->_newsletterCheckout) { Mage::getModel('newsletter/subscriber')->subscribe($email); } return $this; } } |
Fichier Helper
En plus d’être nécessaire pour gérer les traductions, le Helper nous sert à savoir si le client est déjà inscrit à la newsletter.
Fichier /app/code/local/Soon/NewsletterCheckout/Helper/Data.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Soon_NewsletterCheckout_Helper_Data extends Mage_Core_Helper_Abstract { protected $_subscription; /** * Check if current quote email is already susbcribed to newsletter * * @return bool */ public function isSubscribed() { if(null === $this->_subscription) { $subscription = Mage::getModel('newsletter/subscriber') ->loadByEmail(Mage::helper('checkout')->getQuote()->getCustomerEmail()) ->isSubscribed(); $this->_subscription = $subscription; } return $this->_subscription; } } |
Traduction
Fichier /app/locale/fr_FR/Soon_NewsletterCheckout.csv
1 | "Subscribe to newsletter","Inscription à la newsletter" |
Template
La validation de la dernière étape du tunnel de commande (review) passe par un Javascript* qu’il serait laborieux d’adapter alors qu’une solution plus simple existe : l’édition du fichier de template /checkout/onepage/agreements.phtml.
Copier dans votre thème le fichier app/design/frontend/base/default/template/checkout/onepage/agreements.phtml
Remplacer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php if (!$this->getAgreements()) return; ?> <form action="" id="checkout-agreements" onsubmit="return false;"> <ol class="checkout-agreements"> <?php foreach ($this->getAgreements() as $_a): ?> <li> <div class="agreement-content"<?php echo ($_a->getContentHeight() ? ' style="height:' . $_a->getContentHeight() . '"' : '')?>> <?php if ($_a->getIsHtml()):?> <?php echo $_a->getContent() ?> <?php else:?> <?php echo nl2br($this->htmlEscape($_a->getContent())) ?> <?php endif; ?> </div> <p class="agree"> <input type="checkbox" id="agreement-<?php echo $_a->getId()?>" name="agreement[<?php echo $_a->getId()?>]" value="1" title="<?php echo $this->htmlEscape($_a->getCheckboxText()) ?>" class="checkbox" /><label for="agreement-<?php echo $_a->getId()?>"><?php echo $this->htmlEscape($_a->getCheckboxText()) ?></label> </p> </li> <?php endforeach ?> </ol> </form> |
par
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <form action="" id="checkout-agreements" onsubmit="return false;">
<?php if(!Mage::helper('newslettercheckout')->isSubscribed()) : ?>
<div class="checkout-agreements">
<p class="agree">
<input type="checkbox" id="newslettercheckout-agree" value="1" name="newslettercheckout[agree]" title="<?php echo $this->__('Subscribe to newsletter') ?>" class="checkbox" <?php echo (Mage::getSingleton('checkout/session')->getNewsletterCheckout()) ? 'checked' : '' ?>/><label for="newslettercheckout-agree"><?php echo $this->__('Subscribe to newsletter'); ?></label>
</p>
</div>
<?php endif; ?>
<?php if (!$this->getAgreements()) return; ?>
<ol class="checkout-agreements">
<?php foreach ($this->getAgreements() as $_a): ?>
<li>
<div class="agreement-content"<?php echo ($_a->getContentHeight() ? ' style="height:' . $_a->getContentHeight() . '"' : '')?>>
<?php if ($_a->getIsHtml()):?>
<?php echo $_a->getContent() ?>
<?php else:?>
<?php echo nl2br($this->htmlEscape($_a->getContent())) ?>
<?php endif; ?>
</div>
<p class="agree">
<input type="checkbox" id="agreement-<?php echo $_a->getId()?>" name="agreement[<?php echo $_a->getId()?>]" value="1" title="<?php echo $this->htmlEscape($_a->getCheckboxText()) ?>" class="checkbox" /><label for="agreement-<?php echo $_a->getId()?>"><?php echo $this->htmlEscape($_a->getCheckboxText()) ?></label>
</p>
</li>
<?php endforeach ?>
</ol>
</form> |
Noter que la condition if (!$this->getAgreements()) est désormais encapsulée dans le formulaire car nous avons justement besoin de ce formulaire (id= »checkout-agreements ») pour envoyer dans le $_POST le statut de la coche « Inscription à la newsletter).
Noter également, pour profiter d’une CSS toute prête, l’utilisation de la classe .checkout-agreements pour le div de l’inscription à la newsletter.
Finalisation
Il suffit de rafraîchir le cache pour arriver au résultat de la copie d’écran du début de ce billet.
* selon votre version de Magento, voir le fichier template/checkout/onepage/review.phtml ou template/checkout/onepage/review/info.phtml et chercher, en bas de fichier, la ligne
review = new Review(‘getUrl(‘checkout/onepage/saveOrder’) ?>’, ‘getUrl(‘checkout/onepage/success’) ?>’, $(‘checkout-agreements’));
On voit que la validation des accords de facturation est passée en argument (‘checkout-agreement’). Nous avons donc décidé d’utiliser le fichier de template de ces « checkout-agreement » afin d’assurer le bon $_POST de la coche « Inscription à la newsletter ».
Bonsoir, et merci pour cet excellent post.
Je rencontre un petit soucis cependant avec l’extension. Lorsque j’arrive sur la dernière étape du checkout, au lieu d’être dirigé vers le récapitulatif de ma commande, je suis renvoyé vers mon panier.
Mon log php me renvoie l’erreur suivante: « PHP Fatal error: Class ‘Mage_Newslettercheckout_Helper_Data’ not found in /Applications/MAMP/htdocs/mondomaine/app/Mage.php on line 520″
Je pense donc qu’il y a un problème au moment où l’extension vérifie si l’adresse email existe déjà, puisque que quand je retire « isSubscribed()) : ?> » dans mon thème, l’erreur disparait.
A noter que j’ai essayé sous Magento CE 1.5.0.1 et CE 1.6.2, à la fois en local et sur un serveur distant.
Merci par avance pour votre aide!