Le WordPress d'aujourd'hui, décodé pour les développeurs

E-commerce

Comprendre l’ordre d’exécution des hooks woocommerce_ quand deux extensions se chevauchent

Deux extensions modifient le même prix et le résultat dépend de l'ordre d'exécution des hooks. Voici comment la priorité WordPress fonctionne réellement et comment l'inspecter avec WP_Hook.

Par WordPress Développement • 28 avril 2020 • 4 min de lecture • Aucun commentaire
Comprendre l'ordre d'exécution des hooks woocommerce_ quand deux extensions se chevauchent

Pourquoi une remise de 10 % appliquée par une extension de fidélité se calcule-t-elle parfois sur le prix déjà réduit par un coupon, et parfois sur le prix plein ? La réponse tient en un mot : la priorité des hooks. Sur une boutique WooCommerce qui accumule plusieurs extensions de tarification, chacune accrochée à des filtres comme woocommerce_product_get_price ou woocommerce_calculated_total, l’ordre d’exécution détermine le résultat final, et cet ordre n’a rien d’aléatoire même s’il semble parfois imprévisible depuis l’extérieur.

Ce billet explique la mécanique de priorité de WordPress, comment deux extensions peuvent entrer en conflit sur le même filtre, et surtout comment inspecter concrètement ce qui est accroché à un hook donné sur une installation en production, sans deviner.

Le fonctionnement réel de add_action et add_filter

La signature de add_filter( $hook, $callback, $priority = 10, $accepted_args = 1 ) fixe deux paramètres qui gouvernent tout : la priorité, un entier qui peut être négatif, et le nombre d’arguments acceptés par le callback. Deux hooks enregistrés à la même priorité s’exécutent dans leur ordre d’enregistrement, c’est-à-dire dans l’ordre où les fichiers PHP des extensions sont chargés, lui-même dépendant de l’ordre alphabétique des dossiers dans wp-content/plugins sauf dépendance explicite déclarée.

Le cas concret : deux extensions sur le même filtre de prix

L'essentiel à retenir : La priorité par défaut d'un hook WordPress est 10, pas 0 ; Deux callbacks à la même priorité s'exécutent dans l'ordre d'enregistrement ; WP_Hook permet d'inspecter les callbacks réellement accrochés

Imaginons une extension « Club Argenté » qui retire 5 % du prix via woocommerce_product_get_price à la priorité 10, et une extension de coupons personnalisés qui applique un second rabais sur le même filtre, également à la priorité 10. Si l’extension de coupons est activée après celle du club, elle s’exécute en second et rabote un prix déjà réduit : le rabais final n’est donc pas de 5 % + X %, mais un cumul multiplicatif. Changer l’ordre d’activation change le résultat affiché au client, sans qu’aucune ligne de code n’ait été modifiée.

Forcer l’ordre avec la priorité

La correction la plus propre consiste à documenter explicitement quelle extension doit passer en premier, puis à fixer des priorités éloignées l’une de l’autre, par exemple 5 pour la première réduction et 20 pour la seconde, plutôt que de compter sur l’ordre d’activation :

add_filter( 'woocommerce_product_get_price', 'club_argente_reduire_prix', 5, 2 );
add_filter( 'woocommerce_product_get_price', 'coupon_maison_reduire_prix', 20, 2 );

Inspecter ce qui est réellement accroché avec WP_Hook

Depuis WordPress 4.7, chaque hook est représenté par une instance de la classe WP_Hook, accessible via les tableaux globaux $wp_filter. Pour lister tous les callbacks accrochés à woocommerce_product_get_price, avec leur priorité :

global $wp_filter;
if ( isset( $wp_filter['woocommerce_product_get_price'] ) ) {
    foreach ( $wp_filter['woocommerce_product_get_price']->callbacks as $priority => $callbacks ) {
        foreach ( $callbacks as $callback ) {
            error_log( sprintf( 'Priorité %d : %s', $priority, print_r( $callback['function'], true ) ) );
        }
    }
}

Ce petit script, exécuté temporairement dans un plugin de débogage ou via WP-CLI avec wp eval-file, révèle immédiatement l’ensemble des extensions accrochées et leur ordre réel, sans avoir à relire le code source de chacune.

Les pièges à connaître

  • Une priorité négative est autorisée et s’exécute avant la priorité 10 par défaut
  • Retirer un hook avec remove_filter() exige de connaître exactement la priorité et le nombre d’arguments utilisés à l’enregistrement
  • Un callback anonyme (closure) ne peut pas être retiré depuis une autre extension, faute de référence identique

Sur nos projets, dès qu’une tarification personnalisée touche à plus d’une extension, nous documentons systématiquement dans un commentaire la priorité choisie et pourquoi, pour éviter qu’un futur correctif ne la déplace sans comprendre l’enchaînement.

Pour aller plus loin

La priorité des hooks n’est pas un détail d’implémentation : c’est un contrat implicite entre extensions qui partagent la même boutique. Documenter cet ordre, et savoir l’inspecter via WP_Hook plutôt que de le deviner à coups de tests manuels, transforme un débogage de plusieurs heures en une vérification de quelques minutes.

Laisser un commentaire

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

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi