# 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.

- Auteur : WordPress Développement
- Publié le : 2023-10-17
- Mis à jour le : 2023-10-17
- Catégorie : E-commerce
- URL : https://www.wpmoderne.fr/ecommerce/fatal-error-wc-data-store-migration-hpos/

## L’essentiel

- 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

`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.
