bandeau_mail copie

Magento – Inscription à la newsletter au passage de commande

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.

Inscription à la newsletter à la dernière étape du tunnel du checkout

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

<?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

<?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é.

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.

      • 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é.

A vous de choisir votre stratégie !

Fichier d’Observer

Fichier /app/code/local/Soon/NewsletterCheckout/Model/Observer.php

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

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

"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

<?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


<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 ».

E-Commerce, Magento
  • Cyril dit :

    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! 🙂

    • Hervé dit :

      Bonjour,

      Le problème vient du fait que Magento ne trouve pas le helper. Et donc, en effet, si vous supprimez « isSubscribed() » – méthode qui précisément est présente dans le helper – Magento ne cherche plus à instancier le Helper, donc pas d’erreur.

      Je vous invite donc à vérifier que vous avez bien implémenté notre tutorial, en respectant la casse, l’arborescence des fichiers, etc. afin de garantir que Magento trouve bien le Helper.

Laisser un commentaire

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