Ajouter un nouveau formulaire accessible depuis le frontend

  • De le 01 janvier 2010
  • Difficulté : 4/4

Ajouter un nouveau formulaire accessible depuis le frontend Il peut être utile d'intégrer à Magento un formulaire, du même type que le formulaire de contact mais avec champs personnalisés. Cet article explique comment développer un module qui intégrera un nouveau formulaire sur le frontend, avec configuration depuis l'administration et gestion du gabarit e-mail.

Besoin

Pour le développement de notre module nous imaginerons qu'il nous faut ajouter à notre e-commerce un formulaire de demande de brochure, à envoyer au client par courrier. Le client accède à une page ou il renseigne ses coordonnées : nom, prénom, adresse... Un mail où figure les informations saisie est alors envoyé à l'administrateur.

Prérequis

Le module a été développé sous la version 1.3.2.3 de Magento.

Architecture du module

  • app/code/local/Magentix/Brochure/controllers/
  • IndexController.php
  • app/code/local/Magentix/Brochure/Helper/
  • Data.php
  • app/code/local/Magentix/Brochure/etc/
  • config.xml
  • system.xml
  • app/design/frontend/default/default/layout/
  • brochure.xml
  • app/design/frontend/default/default/template/brochure/
  • form.phtml
  • app/locale/fr_FR/
  • Magentix_Brochure.csv
  • app/locale/fr_FR/template/email/
  • brochure_form.html
  • app/etc/modules/
  • Magentix_Brochure.xml

Développement du module

Nous commercerons, après avoir créé l'architecture complète du module, par déclarer son existence :

app/etc/modules/Magentix_Brochure.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Magentix_Brochure>
            <active>true</active>
            <codePool>local</codePool>
        </Magentix_Brochure>
    </modules>
</config>

Dans cet exemple le formulaire sera constitué de 3 champs : nom, adresse et téléphone. Les champs nom et adresse seront obligatoires, téléphone sera facultatif.

Nous allons maintenant créer le formulaire depuis le fichier template form.phml, définir sa structure dans le layout défini par brochure.xml, éditer le template de mail par défaut brochure_form.html, et enfin définir les traductions dans le fichier de langue Magentix_Brochure.csv.

Dans le layout, on indique notamment la structure de page à utiliser : 1 column, 2 columns with right bar... Ainsi que le chemin vers le fichier template à utiliser et contenant le code HTML du formulaire :

app/design/frontend/default/default/layout/brochure.xml

<?xml version="1.0"?>
<layout version="0.1.0">
        <default></default>
        <brochure_index_index>
                <reference name="root">
                        <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
                        <action method="setHeaderTitle" translate="title" module="brochure"><title>Brochure</title></action>
                </reference>
                <reference name="content">
                        <block type="core/template" name="brochureForm" template="brochure/form.phtml"/>
                </reference>
        </brochure_index_index>
</layout>

Le template contiendra nos 3 champs et le bouton de validation. Une vérification JavaScript des champs obligatoires est possible par l'instanciation de la classe JavaScript VarienForm. Les champs vérifiés sont ceux dont la classe CSS contient required-entry (ajoutez "validate-email" pour vérifier la cohérence d'une adresse e-mail).

app/design/frontend/default/default/template/brochure/form.phtml

<div id="messages_product_view"><?php echo $this->getMessagesBlock()->getGroupedHtml() ?></div>

<form action="<?php echo $this->getFormAction(); ?>" id="brochureForm" method="post">

   <div class="input-box">
      <label for="name"><?php echo $this->__('Name') ?> <span class="required">*</span></label><br />
      <input name="name" id="name" title="<?php echo $this->__('Name') ?>" value="<?php echo $this->htmlEscape(Mage::helper('brochure')->getUserName()) ?>" class="required-entry input-text" type="text" />
   </div>

   <div class="input-box">
      <label for="address"><?php echo $this->__('Address') ?> <span class="required">*</span></label><br />
      <input name="address" id="address" title="<?php echo $this->__('Address') ?>" value="" class="required-entry input-text" type="text" />
   </div>

   <div class="input-box">
      <label for="telephone"><?php echo $this->__('Telephone') ?> </label><br />
      <input name="telephone" id="telephone" title="<?php echo $this->__('Telephone') ?>" value="" class="input-text" type="text" />
   </div>

    <div class="button-set">
        <p class="required"><?php echo $this->__('* Required Fields') ?></p>
        <button class="form-button" type="submit"><span><?php echo $this->__('Submit') ?></span></button>
    </div>
</form>

<script type="text/javascript">
   var magazineForm = new VarienForm('brochureForm', true);
</script>

Nous allons ensuite éditer le fichier de langue Magentix_Brochure.csv afin d'indiquer les traductions des termes employés dans le formulaire :

app/locale/fr_FR/Magentix_Brochure.csv

"* Required Fields","* Champs obligatoires"
"Submit","Envoyer"
"Name","Nom"
"Address","Adresse"
"Telephone","Telephone"

Les informations recueillies seront envoyés par e-mail. Dans Magento, la structure du mail envoyé est définie par un gabarit, que l'on pourra éditer depuis l'administration dans la gestion des Emails transactionnels. Le fichier brochure_form.html correspond au "gabarit par défaut pour la locale".

L'encodage du fichier doit être UTF-8, autrement le mail envoyé sera vide.

app/locale/fr_FR/template/email/brochure_form.html

<!--@subject Demande de brochure@-->

Nom : {{var data.name}}

Adresse : {{var data.address}}

Telephone : {{var data.telephone}}

Nous allons maintenant nous attaquer au controller et définir les différentes actions : l'action à exécuter par défaut indexAction() dans laquelle on récupère le bloc brochureForm précédemment créé, et l'action postAction() exécuté lorsque le formulaire est soumis, avec récupération du POST, vérifications des champs, sélection du template mail, envoie de l'e-mail et affichage d'un message "succès" ou "erreur" à l'internaute. La fonction preDispatch() permet l'affichage d'une page d'erreur 404 si le formulaire brochure est désactivé depuis l'administration :

app/code/local/Magentix/Brochure/controllers/IndexController.php

<?php

class Magentix_Brochure_IndexController extends Mage_Core_Controller_Front_Action {

    const XML_PATH_EMAIL_RECIPIENT  = 'brochure/email/recipient_email';
    const XML_PATH_EMAIL_SENDER     = 'brochure/email/sender_email_identity';
    const XML_PATH_EMAIL_TEMPLATE   = 'brochure/email/email_template';
    const XML_PATH_ENABLED          = 'brochure/brochure/enabled';

    public function preDispatch() {
        parent::preDispatch();

        if( !Mage::getStoreConfigFlag(self::XML_PATH_ENABLED) ) {
            $this->norouteAction();
        }
    }

    public function indexAction() {
        $this->loadLayout();
        $this->getLayout()->getBlock('brochureForm')->setFormAction( Mage::getUrl('*/*/post') );

        $this->_initLayoutMessages('customer/session');
        $this->_initLayoutMessages('catalog/session');
        $this->renderLayout();
    }

    public function postAction() {
        $post = $this->getRequest()->getPost();
        if ($post) {
            $translate = Mage::getSingleton('core/translate');
            /* @var $translate Mage_Core_Model_Translate */
            $translate->setTranslateInline(false);
                        
            try {
                $postObject = new Varien_Object();
                $postObject->setData($post);

                $error = false;

                if (!Zend_Validate::is(trim($post['name']) , 'NotEmpty')) $error = true;
                if (!Zend_Validate::is(trim($post['address']) , 'NotEmpty')) $error = true;

                if ($error) throw new Exception();

                $mailTemplate = Mage::getModel('core/email_template');
                /* @var $mailTemplate Mage_Core_Model_Email_Template */
                $mailTemplate->setDesignConfig(array('area' => 'frontend'))
                    /* L'adresse de réponse est ici l'adresse de l'expéditeur définie dans l'administration */
                    ->setReplyTo(Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER))
                    ->sendTransactional(
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE),
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER),
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_RECIPIENT),
                        null,
                        array('data' => $postObject)
                    );

                if (!$mailTemplate->getSentSuccess()) {
                    throw new Exception();
                }

                $translate->setTranslateInline(true);

                Mage::getSingleton('customer/session')->addSuccess(Mage::helper('brochure')->__('Your inquiry was submitted'));
                                
                $this->_redirect('*/*/');

                return;
            } catch (Exception $e) {
                $translate->setTranslateInline(true);

                Mage::getSingleton('customer/session')->addError(Mage::helper('brochure')->__('Unable to submit your request. Please, try again later'));
                $this->_redirect('*/*/');
                return;
            }

        } else {
            $this->_redirect('*/*/');
        }
    }
}

Dans notre Helper, la fonction getUserName() utilisée dans le fichier template form.phtml permet de récupérer le nom du client depuis la session ouverte si celui-ci est déjà connecté. Le champ "nom" du formulaire sera pré-rempli. On peut développer une fonction pour chaque élément associé au customer que l'on souhaite récupérer : prénom, e-mail, adresse...

app/code/local/Magentix/Brochure/Helper/Data.php

<?php

class Magentix_Brochure_Helper_Data extends Mage_Core_Helper_Abstract {
    public function getUserName() {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) return '';

        $customer = Mage::getSingleton('customer/session')->getCustomer();
        return trim($customer->getLastname());
    }
}

Pour finir, il ne reste plus qu'à éditer nos fichiers de configuration config.xml et system.xml :

app/code/local/Magentix/Brochure/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Magentix_Brochure>
            <version>1.0</version>
        </Magentix_Brochure>
    </modules>
    <frontend>
        <routers>
            <brochure>
                <use>standard</use>
                <args>
                    <module>Magentix_Brochure</module>
                    <frontName>brochure</frontName>
                </args>
            </brochure>
        </routers>
        <translate>
            <modules>
                <Magentix_Brochure>
                    <files>
                    <default>Magentix_Brochure.csv</default>
                    </files>
                </Magentix_Brochure>
            </modules>
        </translate>
        <layout>
            <updates>
            <brochure>
                <file>brochure.xml</file>
            </brochure>
            </updates>
        </layout>
    </frontend>
    <global>
        <helpers>
            <brochure>
            <class>Magentix_Brochure_Helper</class>
            </brochure>
        </helpers>
        <template>
            <email>
            <brochure_email_email_template translate="label" module="brochure">
                <label>Brochure Form</label>
                <file>brochure_form.html</file>
                <type>text</type>
            </brochure_email_email_template>
            </email>
        </template>
    </global>
    <adminhtml>
        <translate>
            <modules>
            <Magentix_Brochure>
                <files>
                <default>Magentix_Brochure.csv</default>
                </files>
            </Magentix_Brochure>
            </modules>
        </translate>
        <acl>
            <resources>
            <admin>
                <children>
                <system>
                    <children>
                    <config>
                        <children>
                        <brochure translate="title" module="brochure">
                            <title>Brochure Section</title>
                        </brochure>
                        </children>
                    </config>
                    </children>
                </system>
                </children>
            </admin>
        </resources>
        </acl>
    </adminhtml>
    <default>
        <brochure>
            <brochure>
            <enabled>1</enabled>
            </brochure>
            <email>
            <recipient_email><![CDATA[hello@example.com]]></recipient_email>
            <sender_email_identity>custom2</sender_email_identity>
            <email_template>brochure_email_email_template</email_template>
            </email>
        </brochure>
    </default>
</config>

app/code/local/Magentix/Brochure/etc/system.xml

<?xml version="1.0"?>
<config>
  <sections>
    <brochure translate="label" module="brochure">
      <label>Brochure</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>
        <brochure translate="label">
          <label>Accept our brochure</label>
          <frontend_type>text</frontend_type>
          <sort_order>10</sort_order>
          <show_in_default>1</show_in_default>
          <show_in_website>1</show_in_website>
          <show_in_store>1</show_in_store>
          <fields>
            <enabled translate="label">
              <label>Enable Brochure</label>
              <frontend_type>select</frontend_type>
              <source_model>adminhtml/system_config_source_yesno</source_model>
              <sort_order>10</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>1</show_in_store>
            </enabled>
          </fields>
        </brochure>
        <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>
            <recipient_email translate="label">
              <label>Send Emails To</label>
              <frontend_type>text</frontend_type>
              <sort_order>10</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>1</show_in_store>
            </recipient_email>
            <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>
    </brochure>
  </sections>
</config>

Le nouveau formulaire est maintenant accessible depuis l'URL http://www.site.com/brochure.

Il ne reste plus qu'à configurer le module depuis l'administration : Système > Configuration > Brochure.

Administration du formulaire

Il est également possible d'ajouter un gabarit de mail pour le formulaire Brochure dans la gestion des Emails transactionnels. Si ce gabarit existe, il sera envoyé à la place du gabarit par défaut brochure_form.html.

Administration du formulaire

Vous pouvez enfin continuer l'édition du fichier de traduction Magentix_Brochure.csv afin de le compléter avec l'ensemble des termes utilisés dans ce module.

commentaires

Commentez cet article : Ajouter un nouveau formulaire accessible depuis le frontend