



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.
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.
Le module a été développé sous la version 1.3.2.3 de Magento.
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.
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.
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.
Commentez cet article Ajouter un nouveau formulaire accessible depuis le frontend
Franchement Merci Beaucoup pour le temps que vous avez consacré pour mettre en place ce très intéressant Tuto,
sinon je suis sur Magento v1.3.2.4 et j'ai suivi à la lettre de A à Z les instructions, malheureusement en tapant l'URL:
http://localhost/monsite/brochure (je travail en localhost)
il m'affiche l'erreur 404 Not found in this server!!!!
Grand merci d'avance pour votre aide,
<routers>
<brochure>
<use>standard</use>
<args>
<module>Magentix_Brochure</module>
<frontName>brochure</frontName>
</args>
</brochure>
</routers>
Le "frontName" défini ici est "brochure", cela signifie que la page est accessible depuis l'url "/brochure". La fonction exécutée est "indexAction" du fichier "IndexController.php" (on peut accéder à la page en indiquant l'url /brochure/index/index/). Lorsque le formulaire est soumis j'exécute alors la fonction "postAction" du même fichier (soit /brochure/index/post/).
Donc dans l'URL /brochure/index/index :
- brochure : désigne le nom défini pour frontname dans le fichier de configuration (config.xml)
- index : désigne le nom du contrôleur (IndexController.php)
- index : désigne la méthode du contrôleur à exécuter (indexAction)
Par défaut c'est toujours index qui sera visé, c'est pourquoi il n'est pas nécessaire de l'indiquer dans l'url.
Avant d'exécuter la fonction spécifiée, la méthode "preDispatch" est exécutée, elle vérifie ici que le formulaire est bien activé depuis la configuration et affiche une erreur 404 si ce n'est pas le cas.
Voilà pour la petite explication ;) Donc le problème peut venir d'un des cas de figure suivant :
- Le contrôleur n'est pas déclaré dans le fichier config.xml
- La fonction indexAction du contrôleur n'existe pas
- Le formulaire est désactivé depuis la configuration (brochure/brochure/enabled)
- Le cache n'a pas été rafraichi (supprimer le contenu du dossier /var/cache pour être sûre)
J'ai tenté de reproduire ce cas en faisant un "bete" copier/coller du code propose sur cette page pour le placer dans chaque fichier.
Je vois bien le module depuis l'administration : Système > Configuration > Brochure
Mais quand je clic pour le configurer : je perds le menu de configuration a gauche (seule la liste de choix de portee de configuration s'affiche) et la page reste blanche la ou la partie administration du module devrait s'afficher
Merci d'avance
Finalement (sans autre intervention) la partie admin fonctionne
Peut-etre un pb d'acces serveur au moment de mes premiers tests (j'avais pourtant bien vide le cache)
Tout est bien qui fini bien :)
Tutorial tres utile et pedagogique, merci.
Excellent tuto ! Je recherche justement ce type de développement.
Je l'ai testé sur Magento 1.3.3.0.
L'affichage frontend se fait parfaitement.
Mais dans la partie Admin, j'ai un access denied.
Une suggestion ?
Merci
est ce qu'il est compatible avec la version 1.4.0.1 car cela m'intérésserait.
est ce qu'il est sur Magento connect.
merci
Pour Magento 1.4.0.1 il n'y aura aucun problème ;)
Excellent tuto. Néanmoins, j'ai un problème. Je n'arrive pas à recevoir la newsletter sur ma boîte mail. J'utilise un thème perso.
Pour forcer l'envoi, j'ai remplacé la ligne :
<form action="<?php echo $this->getFormAction(); ?>" id="brochureForm" method="post">
Par
<form action="http://www.monsite.com/fr/index.php/brochure/index/post/" id="brochureForm" method="post">
Rien n'y fait. Comment retrouver la bonne URL ?
Bien à vous,
Max
J'ai donc remplacé partout le mot "brochure" par "formulaire-pro'.
A l'arrivée, j'ai cette erreur qui apparait dans la partie Admin :
Fatal error: Class 'Mage_Formulaire-Pro_Helper_Data' not found in C:\xampp\htdocs\mon-site\app\Mage.php on line 520
Je pense que le problème vient du "-" entre formulaire et Pro. Ou est ce que je peux modifier ça ? dans le fichier config.xml ?
(J'utilise Magento 1.4.0.1 )
Merci si quelqu'un sait ...
François
Il vous va falloir remplacer toutes les occurrences "brochure" par "formulairepro". Le nom du module sera FormulairePro.
- Le nom du dossier contenant le module devient : app/code/local/Aze/FormulairePro/
- Le nom des classes sera :
Aze_FormulairePro_Helper_Data
Aze_FormulairePro_IndexController
- Dans les fichiers respectez les minuscules et majuscule. Pour "brochure" remplacez par "formulairepro". Pour "Brochure", remplacez par "FormulairePro"
Merci pour cet excellent tutoriel.
J'ai ajouté un champs pour envoyer un fichier (upload sur le serveur puis attaché au mail). Pas de problème de ce côté-là.
Par contre le mail ne part pas. L'exception qui se lève se situe au niveau du controller, ici :
if (!$mailTemplate->getSentSuccess()) {
throw new Exception();
}
Le formulaire de contact normal fonctionne parfaitement. Donc pas de problème d'envoi de mail niveau configuration du serveur ou autre. Enfin je crois pas ;-)
Une idée de ce qui peut faire que ça ne marche pas ? Je sèche un peu.
Merci beaucoup d'avance.
Je vais voir ce que j'ai fait de faux, mais si vous avez une piste...
Merci quand même ;-)
J'ai un Access Denied aussi (pourtant j'ai bien supprimé le config.xml et remplacé par adminhtml.xml)
J'ai aussi renommé le formulaire en prenant soin de modifier les noms correspondant.
Je suis dans une impasse...
Merci d'avance!
J'ai pourtant un second probleme, en mettant <contacts_index_index translate="label"> mon formulaire apparait bien en plus sur la page contact mais en mettant
<spaceVendor_index_index translate="label"> j'ai une erreur Fatal error: Call to a member function setFormAction() on a non-object
Merci