Formater l'adresse du client avant l'ajout de la commande

  • De le 18 juillet 2012
  • Difficulté : 2/4

Formater l'adresse du client avant l'ajout de la commande Les clients ont parfois tendance à ajouter des caractères étranges ou des majuscules mal placées lors de saisie de l'adresse postale. Si vous êtes un peu maniaque et que vous aimez les bases de données propres, il est facile de formater l'adresse avant que la commande ne soit ajoutée. (Rédigé à partir d'un Magento CE 1.7)

En rédigeant l'article Ajouter des champs personnalisés sur les adresses de facturation et de livraison, j'ai découvert un événement plutôt sympathique. Celui-ci permet d'interagir sur les objets avant leur conversion.

Par exemple, avant que la commande ne soit définitivement ajoutée, celle-ci subsiste sous forme de quote. Les objets contenus dans le quote sont ensuite convertis pour créer la commande.

La méthode chargée de la conversion des objets se nomme copyFieldset, elle se situe dans la classe Mage_Core_Helper_Data.

L'événement qu'elle contient est le suivant :

Evénement "core_copy_fieldset_{fieldset}_{aspect}"

$eventName = sprintf('core_copy_fieldset_%s_%s', $fieldset, $aspect);
Mage::dispatchEvent($eventName, array(
    'target' => $target,
    'source' => $source,
    'root'   => $root
));
  • fieldset : noeud fieldset, conversion des champs qu'il contient (ex : <sales_convert_order_address>)
  • aspect : noeud aspect, indique le type de conversion, contient le nom du champ à convertir dans l'objet cible, ou une étoile si les noms sont identiques (ex : <fax><to_order_address>*</to_order_address></fax>)
  • target : objet cible (accueil les données de l'objet source)
  • source : objet source
  • root : noeud racine, dans lequel se trouve le noeud fieldset (par défaut global)

Considérons la configuration suivante :

config.xml

<sales_convert_quote_address> <!-- fieldset -->
    <firstname> <!-- field -->
        <to_order_address>*</to_order_address> <!-- aspect -->
        <to_customer_address>*</to_customer_address> <!-- aspect -->
    </firstname>
</sales_convert_quote_address>

La copie des champs de l'objet Mage_Sales_Model_Quote_Address vers Mage_Sales_Model_Order_Address se réalise de la façon suivante :

Convert

Mage::helper('core')->copyFieldset('sales_convert_quote_address', // fieldset
                                   'to_order_address', // aspect
                                   $address, // source
                                   $orderAddress // target
                                  );

// Mage_Sales_Model_Quote_Address $address
// Mage_Sales_Model_Order_Address $orderAddress

Dans cet exemple, l'attribut firstname de l'objet $address, sera copié vers le nouvel objet $orderAddress :

Convert

echo $address->getFirstname(); // Affichera "Jean"
echo $orderAddress->getFirstname(); // null

Mage::helper('core')->copyFieldset('sales_convert_quote_address',
                                   'to_order_address',
                                   $address,
                                   $orderAddress
                                  );

echo $orderAddress->getFirstname(); // Affichera "Jean"

L'événement va donc nous permettre, via un module contenant un observer, de nettoyer l'attribut firstname du nouvel objet (donnée saisie par le client).

Convert

echo $address->getFirstname(); // "JEa;N"

/* copyFieldset */

echo $orderAddress->getFirstname(); // "Jean"

Ainsi, les données de l'adresse du client sur sa commande seront propres et correctement formatées.

Architecture du module

  • app/code/local/Magentix/FormatAddress/etc/
  • config.xml
  • app/code/local/Magentix/FormatAddress/Model/
  • Observer.php
  • app/etc/modules/
  • Magentix_FormatAddress.xml

Développement du module

Commençons par la déclaration de l'observer dans le fichier de configuration.

On souhaite interagir sur l'objet Mage_Sales_Model_Order_Address après que celui-ci ait été créé. Le fieldset correspondant est sales_convert_quote_address, l'aspect to_order_address.

L'événement sera donc : core_copy_fieldset_sales_convert_quote_address_to_order_address

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

<?xml version="1.0"?>
<config>
    <modules>
        <Magentix_FormatAddress>
            <version>0.1.0</version>
        </Magentix_FormatAddress>
    </modules>
    <global>
        <models>
            <formataddress>
                <class>Magentix_FormatAddress_Model</class>
            </formataddress>
        </models>
    </global>
    <frontend>
        <events>
            <core_copy_fieldset_sales_convert_quote_address_to_order_address>
                <observers>
                    <format_address>
                        <type>singleton</type>
                        <class>formataddress/observer</class>
                        <method>formatAddress</method>
                    </format_address>
                </observers>
            </core_copy_fieldset_sales_convert_quote_address_to_order_address>
        </events>
    </frontend>
</config>

La méthode formatAddress de l'observer se charge de formater les attributs comme bon nous semble :

app/code/local/Magentix/FormatAddress/Model/Observer.php

<?php
class Magentix_FormatAddress_Model_Observer {

    public function formatAddress($observer) {
        $address = $observer->getEvent()->getTarget();

        foreach($address->getData() as $attribute => $value) {

            // Appliquez ici les fonctions que vous souhaitez sur $value...
            // Ex : $value = mb_strtolower($value,'UTF-8');

            $address->setData($attribute,$value);

        }
    }

}

Il nous reste à activer le module :

app/etc/modules/Magentix_FormatAddress.xml

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

Il existe évidemment de nombreux autres moyens de formater les champs d'une adresse (notamment l'événement sales_convert_quote_address_to_order_address utilisé juste après celui du module), mais c'était l'occasion de découvrir de nouveaux événements plus ou moins cachés.

Le formatage que j'utilise et qui me paraît assez cohérent (peut bien sûre être amélioré...)

app/code/local/Magentix/FormatAddress/Model/Observer.php

<?php
class Magentix_FormatAddress_Model_Observer {

    public function formatAddress($observer) {
        $address = $observer->getEvent()->getTarget();

        foreach($address->getData() as $attribute => $value) {

            switch ($attribute) {
                case 'telephone':
                case 'fax':
                    $value = ($format = preg_replace('/[^0-9]/','',$value)) ? $format : $value;
                    break;

                case 'email':
                    $value = mb_strtolower($value,'UTF-8');
                    break;

                default:
                    $value = ($format = ucwords(mb_strtolower(trim(preg_replace(array('/[^a-zA-Z0-9 \-]/','/\s+/'),' ',$value)),'UTF-8'))) ? $format : $value;
                    break;
            }

            $address->setData($attribute,$value);

        }

    }

}
commentaires

Commentez cet article : Formater l'adresse du client avant l'ajout de la commande