Depuis le passage sous la version 1.7, il n’est plus possible de récupérer l’étape dans le tunnel de commande grâce à l’URL. Avec en plus l’intégration de Symfony dans le coeur de PrestaShop, les modifications sur le tunnel de commande sont devenues plus complexes qu’auparavant, obligeant de changer la façon de faire le tunnel comparé aux modifications faites sur les versions précédentes.

Objectif

Notre objectif est de pouvoir améliorer le module Google Analytics gratuit afin d’ajouter des GTag sur le tunnel de commande PrestaShop avec un envoi unique par étape du tunnel, et ainsi faire remonter les informations sans passer par un module payant !

Solution

Récupérer la bonne variable

Afin d’accéder aux étapes du tunnel de commande, il faut pouvoir accéder à la variable $checkoutProcess, qui contient tous les éléments dont nous avons besoin.

/**
  * @var CheckoutProcess
  */
protected $checkoutProcess;

Rendre accessible la variable du tunnel

Nous créons simplement une fonction permettant de récupérer le contenu sans la modifier. C’est très important de noter qu’il faut avoir uniquement un getter, et non pas un setter. Pour donner un nom significatif, nous déclarons la nouvelle fonction getCheckoutProcess() dans la classe OrderController.

Il est très important de prendre conscience que nous mettons en place un détournement du fonctionnement de PrestaShop pour accéder à une variable qui n’est pas sensée être visible. Moins nous changeons la structure définie par PrestaShop, moins nous aurons de chances d’impacter le code et d’avoir des effets de bords.

// override/controllers/front/OrderController.php 

// Ajoute une fonction pour accéder à un paramètre de la classe
class OrderController extends OrderControllerCore
{
    public function getCheckoutProcess()
    {
        return $this->checkoutProcess;
    }
}

Récupérer l’étape en cours

Une fois $checkoutProcess accessible, nous allons pouvoir appeler la fonction getSteps() qui contient l’ensemble des étapes du tunnel de commande. Tout notre raisonnement se base sur la récupération de cette fonction native PrestaShop. Comme la fonction est déjà public, nous n’avons pas besoin de créer de nouveaux getters.

En parcourant chacune des étapes, nous pouvons ainsi récupérer l’étape en cours grâce à la fonction isCurrent(), qui retourne true si l’étape est en cours d’affichage pour l’utilisateur du site.

// Parcours les étapes pour trouver celle où l'on se trouve
$current_step = null;

foreach ($this->context->controller->;getCheckoutProcess()->getSteps() as $step) {
    if ($step->isCurrent()) {
        $current_step = $step;
        break;
    }
}

Maintenant, il ne reste plus qu’à récupérer l’étape en cours afin de pouvoir afficher du contenu.

Ajouter la fonction à l’étape souhaitée

Une fois l’étape en cours récupérée, il suffit maintenant de récupérer l’étape concernée, et d’y ajouter où non des fonctions de votre choix. En comparant la classe de l’étape, on est capable de savoir exactement à quelle étape nous sommes, et ainsi ajouter le code souhaité.

// Permet d'attribuer des fonctions à chaque step
if (isset($current_step)) {
    switch (get_class($current_step)) {
        case 'CheckoutAddressesStep':
            // function
            break;
        case 'CheckoutDeliveryStep':
            // function
            break;
        case 'CheckoutPaymentStep':
            // function
            break;
        case 'CheckoutPersonalInformationStep':
            // function
            break;
    }
}

Vous pouvez maintenant intégrer dans vos hooks des comportements différentes en fonction de l’étape où se trouve votre client dans votre tunnel de vente.

Mise en place

Pour montrer un exemple précis, j’ai mis en place ces modifications sur le module gratuit de Google Analytics. Je tiens à préciser que je n’ai pas repris intégralement le module. Il s’agit de modifier rapidement le module pour intégrer les balises dans le tunnel de commande pour en faire un exemple. A vous de modifier le code pour l’utiliser sur votre site PrestaShop. Le reste du code est écrit par le créateur du module de base.

Je ne vais pas décrire exactement le fonctionnement du module, mais simplement les quelques modifications apportées au module pour intégrer la nouvelle fonctionnalité.

Le fonctionnement est le suivant : à chaque chargement de base, le module est appelé via le hook hookDisplayHeader pour définir le code gtag à mettre dans le header de la page, et ainsi envoyer les informations vers Google Analytics.

function hookdisplayHeader($params, $back_office = false)
{
    if (Configuration::get('GA_ACCOUNT_ID')) {
        $controller_name = Tools::getValue('controller');
        $page_path = null;

        ...

        // Get order steps for displaying right path
        if ($controller_name == 'order' || $controller_name == 'orderopc') {
            $current_step = null;
            foreach ($this->context->controller->getCheckoutProcess()->getSteps() as $step) {
                if ($step->isCurrent()) {
                    $current_step = $step;
                    break;
                }
            }
            if (isset($current_step)) {
                switch (get_class($current_step)) {
                    case 'CheckoutAddressesStep':
                        $page_path = Configuration::get('GA_PATH_ADDRESSES');
                        break;
                    case 'CheckoutDeliveryStep':
                        $page_path = Configuration::get('GA_PATH_DELIVERY');
                        break;
                    case 'CheckoutPaymentStep':
                        $page_path = Configuration::get('GA_PATH_PAYMENT');
                        break;
                    case 'CheckoutPersonalInformationStep':
                        $page_path = Configuration::get('GA_PATH_PERSONAL_INFORMATION');
                        break;
                }
            }
        } elseif ($controller_name == 'cart') {
            $page_path = Configuration::get('GA_PATH_PANIER');
        }

        return $this->returnJS($page_path, $back_office);
    }
}

La fonction returnJS() permet de retourner le code JS dans le header de la page, est ainsi l’exécuter (c’est le fonctionnement de base du module). J’ai modifié la fonction pour générer le début du code gtag pour intégrer le chemin correspond à l’étape du tunnel de commande.

public function getStartTag($page_path = null, $user_id = 0)
{
    ...

    $return_js = '<script async src="https://www.googletagmanager.com/gtag/js?id=' . $gaAccountId . '"></script>
    <script data-id="itisanalytics">
    window.dataLayer = window.dataLayer || []; 
    function gtag(){dataLayer.push(arguments);} 
    gtag(\'js\', new Date());
    gtag(\'config\', \'' . $gaAccountId . '\'';

    if (isset($page_path)) {
        $return_js .= ', {\'page_path\': \'' . $page_path . '\'}';
    }

    ...
}

Pour faciliter la gestion des chemins à inclure dans les gtag, un champ par étape du tunnel de commande PrestaShop est ajouté sur le formulaire administrateur

Interface ajoutée au back du module Google Analytics

Résultats

Nous pouvons maintenant avoir les gtag dans les headers de nos pages ! Voici quelques screenshots des résultats sur un PrestaShop de test (sur la page panier et sur la page d’informations des clients).

GTag sur la page de panier PrestaShop
GTag sur la page d’informations personnelles PrestaShop

Vous pourrez accéder au module sur mon repo GitLab : https://gitlab.com/pierrebelin-modulesPS/google-analytics