Prestashop : Trier les champs du formulaire de création de compte

A la suite de la création d’un précédent module, pour lequel j’ajoutais un champ dans le formulaire dans le formulaire de création de compte, j’ai pas mal été frustré de ne pas pouvoir le positionner ou je voulais dans ce formulaire.
Vous pouvez trouver le module ici : Prestashop : Ajouter un champ confirmation email sur le formulaire de création de compte
La solution que j’avais trouvé était de le faire en Javascript, mais ce n’est pas la meilleure approche, et elle peut ne pas fonctionner sur tous les sites.

Le besoin étant plus générique, j’ai donc sorti un module spécifique pour gérer ce comportement.

Fonctionnement technique

Pour ce besoin malheureusement pas d’autres possibilités que de faire un override.
La logique de gestion est gérée dans la fonction getFormat de la classe CustomerFormatter ( dans classes/form/CustomerFormatter.php ).
Cette fonction propose bien un hook additionalCustomerFormFields pour ajouter des champs spécifiques appelé ici :

// ToDo, replace the hook exec with HookFinder when the associated PR will be merged
$additionalCustomerFormFields = Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true);
 
if (is_array($additionalCustomerFormFields)) {
	foreach ($additionalCustomerFormFields as $moduleName => $additionnalFormFields) {
		if (!is_array($additionnalFormFields)) {
			continue;
		}
 
		foreach ($additionnalFormFields as $formField) {
			$formField->moduleName = $moduleName;
			$format[$moduleName . '_' . $formField->getName()] = $formField;
		}
	}
}

Mais le problème de ce hook et qu’on peut uniquement modifier les champs natifs.
Si un autre module ajoute des champs sur le formulaire on ne peut les traiter, car ils n’existent pas encore, et nous n’avons pas accès aux champs des autres modules.
La surcharge à faire est relativement facile , j’ai mis des commentaires explicatifs.

<?php
class CustomerFormatter extends CustomerFormatterCore
{
    public function getFormat()
    {
        //On récupère les données de la méthode parente avec TOUS les champs.
        $format = parent::getFormat();
        //Pour plus de flexibilité on créé un hook custom, et on passe la liste des champs dans la valeur format par référence
        //Ceci permets de le modifier directement la variable dans le hook.
        Hook::exec('actionCustomerFormatterGetFormatAfter', ['format' => &$format]);
        return $format;
    }
}

L’objectif ensuite dans ce hook va être de trier les champs selon l’ordre qu’on a choisi.
Pour cela dans le back office j’ai fait une petite interface graphique qui récupère la liste des champs.
Et qu’on peut trier automatiquement.

L’ordre défini en back office est ensuite stocké dans une configuration, avec le nom des champs sous la forme :
[« id_gender », »firstname », »lastname », »company », »siret », »email », »hhregistrationconfirmemail_email_confirmation », »password », »birthday », »optin », »ps_dataprivacy_customer_privacy »]
Et le tableau des champs est ensuite comparé et  trié selon l’ordre des champs de cette configuration.

     /**
     * Trie les champs du formulaire selon l'ordre défini
     *
     * Le tableau $fields est passé par référence pour être modifié directement
     *
     * @param array $fields
     * @param array $definedOrder
     * @return void
     */
    private function sortFormFields(array &$fields, array $definedOrder)
    {
        $orderMap = array_flip($definedOrder);
        uksort($fields, function ($a, $b) use ($orderMap) {
            $posA = isset($orderMap[$a]) ? $orderMap[$a] : PHP_INT_MAX;
            $posB = isset($orderMap[$b]) ? $orderMap[$b] : PHP_INT_MAX;
            return $posA <=> $posB;
        });
    }

Plus besoin de dépendre de tricks javascript on a donc maintenant une gestion du tri bien plus flexible !
Et la logique est relativement simple à mettre en oeuvre.
Je me pose la question est-ce que ce hook aurait un intérêt à être natif ou est-ce que c’est un besoin de niche ?
Vous pouvez télécharger le module directement sur la boutique

Télécharger le module complet ( et gratuit ) sur la boutique

Laisser un commentaire

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