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

E-commerce

Fatal error WC_Data_Store après une migration vers le HPOS

Une extension maison qui interrogeait encore les tables de commandes legacy plante après activation du stockage haute performance. Voici la bascule à faire.

Par WordPress Développement • 17 octobre 2023 • 4 min de lecture • Aucun commentaire
Fatal error WC_Data_Store après une migration vers le HPOS

Fatal error: Uncaught Exception: Invalid data store. Le message est apparu dans les journaux le lendemain de l’activation du HPOS (High-Performance Order Storage) sur une boutique gérant plusieurs milliers de commandes mensuelles, jusque-là stables sur le mode de stockage historique basé sur wp_posts.

L’extension incriminée était une extension maison de gestion de garanties prolongées, développée plusieurs années avant l’introduction du HPOS, qui interrogeait directement la table wp_posts avec post_type = 'shop_order' pour récupérer la liste des commandes à traiter chaque nuit via une tâche cron.

Ce que change réellement le HPOS

Le HPOS déplace les données de commande vers des tables dédiées (wp_wc_orders, wp_wc_order_operational_data, wp_wc_order_meta), optimisées pour ce cas d’usage précis plutôt que pour un usage générique de type article de blog. Une fois HPOS activé, wp_posts ne contient plus les commandes courantes ; une requête post_type = 'shop_order' sur cette table renvoie un ensemble vide ou incohérent, selon le mode de synchronisation configuré.

C’est précisément ce qui s’est produit ici : la tâche cron de l’extension de garanties récupérait une liste vide, ne traitait plus aucune commande — sans lever d’erreur immédiatement — jusqu’à ce qu’un appel ultérieur de l’extension tente de charger un objet commande via un identifiant devenu invalide dans le nouveau schéma, provoquant la fatale.

Diagnostic : remonter du symptôme à la cause

L'essentiel à retenir : Le HPOS change la source de vérité, pas seulement le nom des tables ; Toute requête SQL directe sur wp_posts pour les commandes doit disparaître ; WC_Data_Store::load() reste le point d'entrée correct quel que soit le mode de stockage

La pile d’appels de l’exception pointait vers WC_Data_Store::load( 'order' ), appelée en interne par WooCommerce, mais avec un identifiant de commande introuvable dans le nouveau magasin de données. En remontant la pile jusqu’au code de l’extension, la ligne fautive s’est révélée être un appel direct à $wpdb->get_results() ciblant wp_posts, dont le résultat servait ensuite à instancier des objets WC_Order via wc_get_order( $post_id ) — une pratique qui fonctionnait par coïncidence avant le HPOS, puisque l’identifiant de commande et l’identifiant de post coïncidaient alors nécessairement.

La bascule vers l’abstraction recommandée

La correction ne consiste pas à adapter la requête SQL à la nouvelle structure de tables — ce qui recréerait la même fragilité à la prochaine évolution du schéma — mais à passer entièrement par l’API de requêtage WooCommerce agnostique au mode de stockage, wc_get_orders() :

$commandes = wc_get_orders( array(
    'status' => array( 'wc-processing', 'wc-completed' ),
    'limit'  => -1,
    'meta_key'   => '_garantie_a_traiter',
    'meta_value' => 'oui',
) );

foreach ( $commandes as $commande ) {
    // Traitement de la garantie via l'objet WC_Order, jamais via $wpdb direct.
    $commande->update_meta_data( '_garantie_traitee', 'oui' );
    $commande->save();
}

Cette fonction native fonctionne indifféremment que le site utilise le HPOS ou le mode de compatibilité posts, car WooCommerce route la requête vers le bon magasin de données en interne, via WC_Data_Store::load(), sans que le code de l’extension n’ait à connaître le détail du schéma sous-jacent.

Vérifier avant de généraliser la correction

  • Rechercher dans le code de chaque extension maison toute occurrence de post_type combinée à shop_order ou shop_order_refund.
  • Rechercher également les jointures SQL directes sur wp_postmeta filtrées par un post_id supposé être une commande.
  • Remplacer systématiquement par wc_get_orders(), wc_get_order() et les méthodes de l’objet WC_Order.
  • Tester la tâche cron concernée manuellement, en mode synchrone, avant de la remettre en tâche planifiée.

Conseil maison : toute extension écrite avant l’existence du HPOS mérite un audit de ses requêtes SQL directes avant d’activer ce mode de stockage, même si l’extension semble fonctionner sans erreur au premier abord. Les pannes de ce type apparaissent souvent avec un délai, une fois qu’une tâche planifiée a silencieusement cessé de trouver des données.

En résumé

La fatal error WC_Data_Store après une migration HPOS signale presque toujours un accès direct aux anciennes tables, contournant l’abstraction WooCommerce. La correction durable passe par wc_get_orders() et les méthodes de l’objet WC_Order, jamais par une adaptation ponctuelle de la requête SQL au nouveau schéma. La procédure de migration HPOS elle-même, avec ses étapes de synchronisation progressive, reste un sujet distinct de ce correctif d’extension.

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