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

Thèmes

HPOS activé, panier qui affiche du vide : le template thème qui lit encore l’ancien format

Un thème WooCommerce hérité continue d'appeler get_post_meta sur la commande après le passage aux tables HPOS. Voici comment repérer et corriger ces appels dans les templates.

Par WordPress Développement • 12 décembre 2022 • 5 min de lecture • Aucun commentaire
HPOS activé, panier qui affiche du vide : le template thème qui lit encore l'ancien format

get_post_meta( $order->get_id(), '_billing_email', true ) renvoie une chaîne vide dans un template cart/cart.php personnalisé, alors que l’adresse existe bel et bien dans les réglages de la commande. Le symptôme est discret : rien ne plante, aucune erreur PHP ne remonte, mais des champs disparaissent silencieusement des templates de panier et de récapitulatif de commande d’un thème enfant hérité.

C’est exactement ce qui arrive lorsque WooCommerce bascule le stockage des commandes vers les tables personnalisées HPOS (High-Performance Order Storage, disponible depuis WooCommerce 8.2 mi-2022 en version bêta) et qu’un thème continue d’interroger directement wp_postmeta par des appels de fonctions pensés pour l’ancien modèle « commande = article ».

Symptôme observé sur le terrain

Le cas typique : un thème boutique livré plusieurs années auparavant contient un fichier woocommerce/cart/cart-totals.php surchargé, avec des appels du type get_post_meta( $post->ID, '_order_total', true ) pour afficher un total personnalisé, ou des lectures de _billing_email, _shipping_method, _payment_method_title directement en base. Tant que les commandes sont stockées comme des articles du type shop_order, cela fonctionne. Dès qu’une boutique active le stockage HPOS, ces commandes ne sont plus des lignes de wp_posts : elles vivent dans wp_wc_orders et leurs métadonnées dans wp_wc_orders_meta.

Résultat concret : les champs lus via get_post_meta() renvoient une chaîne vide ou false, sans avertissement, sans notice PHP, parce que la fonction cherche un article qui n’existe simplement plus à cet identifiant dans wp_posts.

L'essentiel à retenir : HPOS déplace les métadonnées hors de wp_postmeta ; get_post_meta reste souvent fonctionnel en compatibilité, mais pas toujours ; La bonne pratique : passer par les getters de l'objet commande

Diagnostic : où chercher dans le thème

La première étape consiste à cartographier les appels problématiques. Une recherche dans les fichiers du thème sur les motifs suivants suffit généralement à isoler les zones à risque :

  • get_post_meta( $order ou get_post_meta( $post->ID dans un contexte de commande
  • update_post_meta appliqué à un identifiant de commande
  • WP_Query avec 'post_type' => 'shop_order' pour lister des commandes dans un tableau de bord thème
  • accès direct à $wpdb->postmeta via une requête SQL sur mesure

Sur un thème d’agence audité récemment, ce sont sept fichiers de templates surchargés qui contenaient ce type d’appel : le récapitulatif de commande, l’e-mail de confirmation personnalisé, un widget « dernières commandes » du compte client, et un rapport interne affiché en pied de page administrateur.

Pourquoi ça ne plante pas immédiatement

WooCommerce maintient par défaut, pendant la période de transition, un mode de compatibilité qui synchronise les données entre les tables HPOS et wp_posts/wp_postmeta. Ce mode peut masquer le problème pendant des mois, jusqu’au jour où la synchronisation est désactivée dans les réglages, ou jusqu’à ce qu’une commande créée par une extension tierce ne passe plus par ce pont de compatibilité.

Correctif : passer par les getters de l’objet commande

La correction consiste à remplacer chaque lecture directe de métadonnée par l’API orientée objet de WooCommerce, qui fonctionne indépendamment du mode de stockage choisi :

// Avant : lecture directe, fragile face à HPOS
$email = get_post_meta( $order_id, '_billing_email', true );
$total = get_post_meta( $order_id, '_order_total', true );

// Après : passe par l'objet WC_Order, compatible HPOS
$order = wc_get_order( $order_id );
if ( $order instanceof WC_Order ) {
    $email = $order->get_billing_email();
    $total = $order->get_total();
}

Pour les méta personnalisées ajoutées par le thème lui-même (par exemple une case « commande urgente » stockée sous _urgent_flag), la méthode get_meta() de l’objet commande fait le même travail que get_post_meta(), mais interroge la bonne table selon le mode actif :

$urgent = $order->get_meta( '_urgent_flag', true );
$order->update_meta_data( '_urgent_flag', 'yes' );
$order->save();

Pour les requêtes qui listent des commandes, WP_Query sur shop_order doit céder la place à wc_get_orders(), qui accepte des arguments similaires (limit, status, customer_id) mais interroge la couche de stockage réellement active.

Prévention pour les prochains projets

Trois habitudes évitent de retomber dans ce piège sur les futurs chantiers de thèmes WooCommerce :

  • Déclarer explicitement la compatibilité HPOS du thème lorsqu’il embarque des templates de commande, via le hook before_woocommerce_init et FeaturesUtil::declare_compatibility()
  • Bannir tout accès direct à wp_postmeta ou wp_posts pour des données de commande, même dans un script de maintenance ponctuel
  • Tester le thème avec HPOS activé en environnement de recette avant chaque livraison, la bascule étant désormais activée par défaut sur les nouvelles installations

Un thème qui n’accède jamais directement à wp_postmeta pour une commande survit à tous les changements de stockage internes de WooCommerce, présents et futurs.

En résumé

Le passage à HPOS ne casse rien de façon spectaculaire dans un thème ancien : il vide silencieusement des champs qui semblaient acquis. La correction est mécanique une fois les appels problématiques repérés — remplacer get_post_meta() par les getters de WC_Order — mais elle demande un audit complet des templates de commande, pas seulement du panier. Sur ce projet, l’audit des sept fichiers a pris une demi-journée ; la correction, à peine plus.

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