Bonjour,
Merci pour les détails. Nous pourrions en effet rajouter un option pour cela. Il serait intéressant de connaître le code JS définitif.
Le code JS définitif pour le plugin Meta Pixel de Joomlamax est le suivant, en tout cas dans mon cas et avec LegalBlink cela fonctionne parfaitement:
return (function() {
try {
var m = document.cookie.match(/(?:^|;\s*)lb_csc=([^;]+)/);
if (!m) return false;
var c = JSON.parse(decodeURIComponent(m[1]));
// Cette ligne vérifie si le tableau 'level' contient la catégorie 'third_party_adv_cookies'
return !!(c && c.level && c.level.includes("third_party_adv_cookies"));
} catch (e) {
return false;
}
})();
Dans l'attente d'une solution intégrée à votre plugin (à l'image du plugin Meta Pixel de Joomlamax) j'ai essayé de l'adapter pour le faire fonctionner avec le consentement de LegalBlink, ...cela n'a pas été chose simple, n'étant pas développeur je me suis fait aider par l'IA
Petite explication préalable.
Le système de LegalBlink exige que tous les scripts de suivi soient bloqués avant le consentement de l'utilisateur.
Voici comment j'ai abordé le problème du blocage du suivi de LegalBlink pour l'appliquer à votre plugin:
Blocage (Côté Serveur / PHP): Le code PHP d'HikaShop (dans hikashop_ga4.php) a été modifié pour insérer l'attribut
type="text/plain" sur toutes les balises <script> de GA4.
Ce changement neutralise le script, l'empêchant d'être exécuté par le navigateur.
Exemple:
// Remplace addScript par addCustomTag pour ajouter les attributs de blocage pour le fichier gtag.js externe.
$doc->addCustomTag('<script type="text/plain" class="lb-third-party-stats-cookies" async src="https://www.googletagmanager.com/gtag/js?id='.$this->site_id.'"></script>'); Déblocage (Côté Client / JavaScript): Lorsque l'utilisateur clique sur "Accepter", le script JavaScript qui a été intégré s'active. Ce script recherche tous les éléments avec
type="text/plain" et les remplace dynamiquement par de nouvelles balises
<script type="text/javascript">, forçant ainsi leur exécution.
Pour avoir une vision complète du code reporté plus bas: le bloc de code PHP n'est pas un simple exemple, mais un correctif spécifique qui a été intégré: il gère l'injection conditionnelle de l'événement
begin_checkout (mais dans un état bloqué), car cet événement n'était pas tracé de manière fiable sur les pages du panier et du checkout.
Le JavaScript s'occupe ensuite de la réactivation effective du script correctement injecté.
Ce bloc de code a été injecté sur toutes les pages avant la fermeture de la balise </body> via ReReplacer.
<?php
// PHP : Correction pour l'événement manquant 'begin_checkout'
defined('_JEXEC') or die('Restricted access');
$ctrl = JFactory::getApplication()->input->getCmd('ctrl');
$view = JFactory::getApplication()->input->getCmd('view');
if ($ctrl == 'checkout' || $view == 'user' || $view == 'cart') {
// Injection de l'événement en état BLOQUÉ (type="text/plain")
echo '<script type="text/plain" class="lb-third-party-stats-cookies">gtag(\'event\', \'begin_checkout\', {});</script>';
}
?>
<script>
// JavaScript : Mécanisme de Déblocage et de Buffer des Événements
// File d'attente (buffer) pour les événements gtag() reçus AVANT le consentement
var LB_TEMP_DATALAYER_QUEUE = [];
var LB_STATS_CONSENTED = false;
var LB_STATS_CLASS = ".lb-third-party-stats-cookies"; // Classe des scripts à débloquer
function executeLegalBlinkHardFix() {
// Empêche l'exécution multiple
if (LB_STATS_CONSENTED) return;
LB_STATS_CONSENTED = true;
// 1. Déblocage : Recherche tous les scripts bloqués et les remplace par des scripts actifs
document.querySelectorAll(LB_STATS_CLASS).forEach(function(script) {
if (script.getAttribute('type') === 'text/plain') {
var newScript = document.createElement('script');
newScript.type = 'text/javascript'; // Rend le script actif
if (script.innerHTML) newScript.innerHTML = script.innerHTML;
if (script.hasAttribute('async')) newScript.setAttribute('async', 'async');
if (script.hasAttribute('src')) newScript.setAttribute('src', script.getAttribute('src'));
script.parentNode.replaceChild(newScript, script);
}
});
// 2. Exécution du Buffer : Déclenche tous les événements mis en attente
if (LB_TEMP_DATALAYER_QUEUE.length > 0) {
for (var i = 0; i < LB_TEMP_DATALAYER_QUEUE.length; i++) {
// Utilise la fonction gtag originale (gtag_temp)
window.gtag_temp.apply(null, LB_TEMP_DATALAYER_QUEUE[i]);
}
LB_TEMP_DATALAYER_QUEUE = [];
}
// 3. Restauration : Restaure la fonction gtag() d'origine
window.gtag = window.gtag_temp;
delete window.gtag_temp;
}
// Interception des événements : Enregistre la fonction gtag() originale et la remplace
window.gtag_temp = window.gtag;
window.gtag = function() {
if (LB_STATS_CONSENTED) {
// Si le consentement est donné, exécute la fonction originale immédiatement
window.gtag_temp.apply(null, arguments);
} else {
// Si pas de consentement (attente), met en mémoire tampon uniquement les événements ('event')
if (arguments[0] === 'event') {
LB_TEMP_DATALAYER_QUEUE.push(arguments);
}
// Laisse passer les commandes 'config' et 'js' car elles sont essentielles au chargement initial
if (arguments[0] === 'config' || arguments[0] === 'js') {
window.gtag_temp.apply(null, arguments);
}
}
};
// Déclenchement : Écoute l'événement de consentement de LegalBlink
document.addEventListener("legalblink_stats_consentgiven", function() {
if (typeof LegalBlink !== 'undefined' && LegalBlink.lbConsent && LegalBlink.lbConsent.level.includes("third_party_stats_cookies")) {
// Délai de 500ms pour garantir le chargement complet des autres scripts
setTimeout(executeLegalBlinkHardFix, 500);
}
});
</script>
Après tout cela, le système est validé et le suivi est opérationnel, sauf pour les événements
add_shipping_info et
add_payment_info qui semblent être visibles uniquement lorsqu'on change leur statut manuellement.
Si mes souvenirs sont bons, c'est le comportement d'origine de ces deux événements de votre plugin même sans cette implémentation...?
En comparant les deux approches, celle du plugin de Joomlamax et l'intégration pour votre plugin, même si cette dernière semble bien fonctionner (je note juste un petit doute sur la "Debug View" dans GA, mais les événements s'affichent bien dans la "Vue d'ensemble en temps réel", donc cela reste fiable), elle a nécessité la modification directe du fichier principal de votre plugin,
hikashop_ga4.php, ce qui posera problème pour les futures mises à jour.
J'ai essayé de comprendre comment le plugin de Joomlamax a géré ce problème.
Il me semble de comprendre qu'il utilise une méthode plus propre et plus simple: au lieu de bloquer un script déjà injecté, leur plugin vérifie d'abord le consentement de l'utilisateur avant même d'injecter le code dans la page.
Ceci serait l'idéal pour votre plugin, car cela éviterait d'intégrer cette solution "maison".
Désolé pour ce long post mais je pense que c'était necessaire... merci.