Aller au contenu
WooRescueHQ

WooCommerce / HPOS

HPOS WooCommerce : problèmes fréquents avec le code personnalisé

Réponse courte

Avec HPOS comme stockage principal, les commandes vivent dans wp_wc_orders et ses tables associées, pas dans wp_posts et wp_postmeta. Le code qui lit ou écrit les commandes avec les fonctions d’articles, WP_Query ou du SQL sur les tables d’articles cesse de fonctionner, souvent en silence, en renvoyant des valeurs vides. Réécrivez-le avec l’API des commandes (wc_get_order(), wc_get_orders(), $order->get_meta(), $order->update_meta_data() puis $order->save()), mettez à jour les hooks d’administration pour le nouvel écran des commandes et déclarez la compatibilité HPOS dans vos extensions.

Symptômes

  • Les métadonnées de commande lues par le code sur mesure reviennent vides après l’activation de HPOS.
  • Des colonnes, filtres ou meta boxes personnalisés manquent dans le nouvel écran des commandes.
  • Les exports, rapports ou intégrations n’incluent plus les nouvelles commandes.
  • Les valeurs enregistrées par le code sur mesure n’apparaissent pas sur la commande, ou disparaissent à l’enregistrement suivant.
  • WooCommerce signale des extensions actives incompatibles et refuse de passer à HPOS.

Causes les plus fréquentes

Motif Pourquoi cela casse
get_post_meta( $order_id, '_my_key', true ) Lit wp_postmeta, qui n’est pas la source de vérité avec HPOS
update_post_meta( $order_id, … ) Écrit dans le stockage par articles ; HPOS ne le voit pas, ou la synchronisation l’écrase
new WP_Query( [ 'post_type' => 'shop_order' ] ) / get_posts() Interroge wp_posts, où les nouvelles commandes peuvent ne pas exister
Requêtes $wpdb sur wp_posts / wp_postmeta pour les commandes Ancien schéma codé en dur
wp_insert_post() / wp_update_post() sur des commandes Contourne les data stores des commandes
manage_edit-shop_order_columns uniquement Hooks de l’ancien écran ; l’écran HPOS en utilise d’autres
add_meta_box( …, 'shop_order' ) Mauvais identifiant d’écran pour l’écran d’édition HPOS

Diagnostic

1. Vérifiez quel stockage fait autorité

WooCommerce → Réglages → Avancé → Fonctionnalités indique si les commandes sont stockées dans les tables HPOS ou dans les anciennes tables d’articles, et si le mode de compatibilité garde les deux synchronisés. Tant que la synchronisation est active, l’ancien code peut sembler fonctionner en lecture, ce qui masque le problème jusqu’à sa désactivation.

2. Cherchez dans le code

Cherchez dans le thème, les extensions sur mesure, les mu-plugins et les extensions de snippets :

Bash
$ grep -rnE "get_post_meta|update_post_meta|delete_post_meta|wp_insert_post|wp_update_post" wp-content/themes/my-theme wp-content/plugins/my-plugin
$ grep -rnE "shop_order|wp_posts|wp_postmeta|post_type *=" wp-content/themes/my-theme wp-content/plugins/my-plugin

Chaque résultat demande une décision : touche-t-il aux commandes ? Le code des produits et des pages n’est pas concerné.

3. Vérifiez les extensions

WooCommerce liste les extensions incompatibles sur l’écran des Fonctionnalités. Pour chacune, vérifiez si une mise à jour déclare la compatibilité ; sinon, interrogez l’éditeur ou prévoyez un remplacement.

4. Testez en préproduction avec la synchronisation activée, puis désactivée

Activez HPOS en préproduction avec le mode de compatibilité, déroulez les parcours critiques (checkout, notifications de paiement, e-mails, modifications dans l’administration, exports, intégrations), puis désactivez la synchronisation et recommencez. Du code qui ne fonctionne qu’avec la synchronisation activée n’est pas compatible.

Journaux et vérifications techniques

  • L’écran des Fonctionnalités : stockage principal, état de la synchronisation, extensions incompatibles.
  • WooCommerce → État → Journaux : fatal-errors après le changement de stockage.
  • Notes et métadonnées des commandes de test, comparées avant et après le changement.
  • Comparaisons en lecture seule d’une même commande dans les deux stockages tant que la synchronisation est active.

Solutions

Lisez et écrivez les commandes via l’API des commandes

PHPmy-plugin/includes/orders.php
// Lire
$order = wc_get_order( $order_id );
if ( ! $order ) {
    return;
}
$po_number = $order->get_meta( '_po_number' );

// Écrire : rien n’est enregistré avant l’appel à save()
$order->update_meta_data( '_po_number', sanitize_text_field( $value ) );
$order->save();

// Interroger
$orders = wc_get_orders( [
    'status'     => [ 'wc-processing' ],
    'limit'      => 50,
    'meta_query' => [
        [ 'key' => '_po_number', 'compare' => 'EXISTS' ],
    ],
] );

Prenez en charge les deux écrans d’administration

PHPmy-plugin/includes/admin.php
use Automattic\WooCommerce\Utilities\OrderUtil;

// Colonnes : ancien écran et écran HPOS
add_filter( 'manage_edit-shop_order_columns', 'myplugin_add_column' );
add_filter( 'manage_woocommerce_page_wc-orders_columns', 'myplugin_add_column' );

add_action( 'manage_shop_order_posts_custom_column', function ( $column, $post_id ) {
    myplugin_render_column( $column, wc_get_order( $post_id ) );
}, 10, 2 );
add_action( 'manage_woocommerce_page_wc-orders_custom_column', function ( $column, $order ) {
    myplugin_render_column( $column, $order );
}, 10, 2 );

// Meta box sur l’écran d’édition des commandes actif
add_action( 'add_meta_boxes', function () {
    add_meta_box( 'myplugin-box', 'Bon de commande', 'myplugin_render_box', wc_get_page_screen_id( 'shop-order' ), 'side' );
} );

function myplugin_render_box( $post_or_order ) {
    $order = $post_or_order instanceof WP_Post ? wc_get_order( $post_or_order->ID ) : $post_or_order;
    // …
}

Déclarez la compatibilité dans vos propres extensions

PHPmy-plugin/my-plugin.php
add_action( 'before_woocommerce_init', function () {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    }
} );

Ce qu’il ne faut pas faire

  • Ne déclarez pas la compatibilité pour faire taire l’avertissement avant d’avoir vérifié le code.
  • Ne désactivez pas le mode de compatibilité juste après la bascule : gardez-le comme voie de retour arrière jusqu’à ce que la boutique ait fonctionné correctement un certain temps.
  • Ne « réparez » pas les valeurs manquantes en copiant des métadonnées entre tables en SQL.

Quand faire appel à un expert

Faites appel à un ingénieur quand l’audit trouve des accès aux commandes dispersés dans de nombreux fichiers, quand une extension indispensable n’a pas de version compatible, quand les données de commande diffèrent déjà entre les stockages, ou quand la boutique est assez grande pour que la migration elle-même doive être planifiée.

Questions fréquentes

Comment savoir si mon code est compatible HPOS ?

Cherchez les accès directs aux commandes : get_post_meta et update_post_meta sur des identifiants de commande, WP_Query ou get_posts avec shop_order, wp_insert_post pour des commandes et du SQL sur wp_posts ou wp_postmeta pour des commandes. Le code qui n’utilise que wc_get_order, wc_get_orders et les méthodes de l’objet commande est généralement compatible.

Pourquoi ma colonne personnalisée disparaît-elle de la liste des commandes ?

L’écran des commandes HPOS est une autre page d’administration avec d’autres hooks. Les colonnes enregistrées avec manage_edit-shop_order_columns ont aussi besoin de leurs équivalents manage_woocommerce_page_wc-orders_columns.

Dois-je déclarer la compatibilité ?

Oui, pour vos propres extensions. WooCommerce utilise cette déclaration pour décider si HPOS peut être activé. Ne la déclarez qu’après avoir vérifié le code.

Puis-je encore exécuter du SQL sur les commandes ?

Préférez wc_get_orders(). Si vous avez vraiment besoin de SQL, récupérez les noms de tables auprès de WooCommerce au lieu de coder wp_posts en dur, et gardez en tête que le schéma diffère d’un stockage à l’autre.

$ décrivez le problème

Un problème avec WooCommerce ?Demandez un diagnostic.

Dites-nous ce qui ne fonctionne pas, ce qui a changé récemment et l'impact sur votre activité. Nous examinons chaque demande et vous recommandons la marche à suivre.

Demander un diagnostic Voir les services et les tarifs

N'envoyez jamais de mots de passe, de clés API ni de données de carte via le formulaire.

Diagnostic à partir de299 €

Demander un diagnostic