vendredi 25 septembre 2026

À propos

Contact

E-commerce

Antipatterns d’e-mails : dupliquer WC_Email sans en hériter sur WooCommerce

Copier-coller la classe d'un e-mail WooCommerce plutôt que d'en hériter semble plus rapide sur le moment, mais transforme chaque mise à jour en corvée de rattrapage.

Par Clément Hadrot • 9 avril 2024 • 5 min de lecture • Aucun commentaire
Antipatterns d'e-mails : dupliquer WC_Email sans en hériter sur WooCommerce

Un nouveau statut de commande personnalisé, « en attente de vérification manuelle », méritait son propre e-mail de notification. Le développeur précédent sur ce projet avait résolu le problème de la façon la plus rapide possible : copier le fichier class-wc-email-customer-processing-order.php, le renommer, changer quelques chaînes de texte, et l’enregistrer comme nouvelle classe indépendante. Sur le moment, ça fonctionne. Deux ans plus tard, ça devient un problème silencieux.

Ce genre de raccourci est l’un des antipatterns les plus fréquents rencontrés en audit de code WooCommerce, précisément parce qu’il ne provoque aucune erreur immédiate. Le bug qu’il installe est un bug de dérive, pas un bug de croissance de complexité, ce qui le rend difficile à justifier en priorité auprès d’un client pressé.

Ce qu’on voit dans le code

La classe copiée-collée redéfinit intégralement des méthodes comme get_content_html(), trigger() ou encore la déclaration des propriétés $id, $title, $description, alors que la classe parente WC_Email et sa sous-classe d’origine fournissent déjà toute cette mécanique. Le fichier copié pèse souvent 150 à 200 lignes, dont l’essentiel n’a jamais été modifié par rapport à l’original.

// Ce qu'on trouve trop souvent
class WC_Email_Verification_Manuelle {
    public $id = 'verification_manuelle';
    public $title = 'Vérification manuelle requise';
    // ... 180 lignes copiées de class-wc-email-customer-processing-order.php
}

Pourquoi c’est un problème

La classe WC_Email et ses sous-classes natives évoluent à chaque version mineure de WooCommerce : correctifs de sécurité sur l’échappement des données injectées dans le template, ajustements de compatibilité avec PHP 8, ajout de nouveaux filtres. Une classe copiée-collée ne reçoit aucune de ces mises à jour automatiquement, puisqu’elle ne partage plus aucun lien de code avec l’original — elle est figée à l’état du jour où elle a été dupliquée.

L'essentiel à retenir : Copier une classe WC_Email fige son code à la version du jour ; Chaque correctif de sécurité du cœur doit être réappliqué à la main ; L'héritage garde la compatibilité avec les futures versions

Sur un projet audité récemment, cette dérive avait fini par créer une incohérence visible : l’e-mail dupliqué affichait encore l’ancien pied de page de la boutique, supprimé du thème d’e-mail officiel WooCommerce deux mises à jour plus tôt, simplement parce que la classe copiée ne recevait plus aucun des changements de style appliqués via woocommerce_email_footer et consorts.

Ce qu’il faut faire à la place

La bonne pratique consiste à créer une classe qui étend une classe d’e-mail existante la plus proche du besoin, ou directement WC_Email si le cas est vraiment nouveau, puis à ne redéfinir que ce qui change réellement : le constructeur pour l’identifiant et le déclencheur, éventuellement get_default_subject() et get_default_heading().

class WC_Email_Verification_Manuelle extends WC_Email {
    public function __construct() {
        $this->id          = 'verification_manuelle';
        $this->title       = 'Vérification manuelle requise';
        $this->description = 'Envoyé quand une commande passe en vérification manuelle.';
        $this->template_html  = 'emails/verification-manuelle.php';
        $this->template_plain = 'emails/plain/verification-manuelle.php';

        add_action( 'woocommerce_order_status_en-attente-verif', array( $this, 'trigger' ) );

        parent::__construct();
    }

    public function trigger( $order_id ) {
        $this->object = wc_get_order( $order_id );
        if ( $this->is_enabled() && $this->get_recipient() ) {
            $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
        }
    }
}

L’enregistrement, une étape souvent oubliée aussi

Même correctement écrite en héritage, la classe doit être déclarée auprès de WooCommerce via le filtre woocommerce_email_classes, sans quoi elle n’apparaît jamais dans la liste des e-mails configurables de l’administration et ne bénéficie pas du cycle de vie standard, y compris l’activation ou la désactivation par l’utilisateur.

  1. Créer la classe en héritant de WC_Email ou d’une sous-classe existante
  2. L’enregistrer via add_filter( 'woocommerce_email_classes', ... )
  3. Fournir un template HTML et un template texte brut dans le thème ou le plugin
  4. Tester le rendu avec l’aperçu d’e-mail natif de WooCommerce

Hériter d’une classe n’est pas une contrainte académique : c’est un contrat implicite qui dit « je continuerai de bénéficier de vos correctifs ». Le rompre pour gagner dix minutes coûte toujours plus cher, plus tard.

Quoi faire si l’antipattern est déjà en production

La migration inverse est simple mais demande de la rigueur : comparer méthode par méthode la classe copiée avec l’originale actuelle, identifier ce qui a réellement été personnalisé, puis reconstruire une classe en héritage qui ne redéfinit que ces différences. C’est souvent l’occasion de découvrir que 90 % du code copié n’avait jamais été modifié et pouvait simplement disparaître.

En résumé

Dupliquer une classe WC_Email plutôt que d’en hériter est l’un des antipatterns les plus insidieux de l’écosystème WooCommerce : indolore au moment de l’écrire, coûteux à chaque montée de version future. L’héritage n’est pas seulement une bonne pratique de conception, c’est une assurance de maintenance à moyen terme.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi