# HPOS et un thème qui imprime les factures : un post meta mal relu

> Après la bascule HPOS, un template d'impression de facture codé à la main continue d'interroger les anciennes tables de commande. Diagnostic du symptôme et correctif.

- Auteur : WordPress Développement
- Publié le : 2022-12-09
- Mis à jour le : 2022-12-09
- Catégorie : Thèmes
- URL : https://www.wpmoderne.fr/themes/hpos-theme-factures-post-meta-mal-relu/

## L’essentiel

- get_post_meta() ne fonctionne plus comme source fiable après HPOS
- WC_Order::get_meta() reste compatible quel que soit le mode de stockage
- Un template codé à la main doit être audité ligne par ligne après la bascule

`Warning: get_post_meta() returned empty on order #4821` : ce message, ou son équivalent silencieux sous forme de champ vide sur une facture imprimée, apparaît sur certains projets quelques semaines après la bascule vers le stockage des commandes à haute performance (HPOS) de WooCommerce, activé mi-2022. Les commandes existent bien, les données sont là, mais le template d'impression de facture codé à la main pour ce projet n'affiche plus les informations attendues.

Le symptôme touche spécifiquement les templates personnalisés qui interrogent directement les métadonnées de commande avec les fonctions génériques de WordPress, plutôt qu'avec les méthodes dédiées fournies par l'objet commande de WooCommerce.

## Symptôme

Une facture générée pour une commande passée après la bascule HPOS affiche des champs vides : adresse de facturation manquante, numéro de TVA absent, alors que ces informations sont bien visibles et correctes dans l'écran d'administration de la commande. Le problème ne touche que les commandes créées ou modifiées après le passage au nouveau mode de stockage ; les commandes plus anciennes, elles, continuent de s'afficher correctement.

## Diagnostic

Le template d'impression de facture, écrit sur mesure pour ce projet avant la généralisation de HPOS, interrogeait directement les métadonnées de commande avec la fonction générique `get_post_meta()`, en traitant l'identifiant de commande comme un identifiant d'article classique :

```
$numero_tva = get_post_meta( $commande_id, '_numero_tva_client', true );
```

> L'essentiel à retenir : get_post_meta() ne fonctionne plus comme source fiable après HPOS ; WC_Order::get_meta() reste compatible quel que soit le mode de stockage ; Un template codé à la main doit être audité ligne par ligne après la bascule

Avant HPOS, les commandes WooCommerce étaient stockées comme des articles classiques dans la table `wp_posts`, avec leurs métadonnées dans `wp_postmeta`. Ce code fonctionnait alors parfaitement, puisque `get_post_meta()` interroge précisément cette table. Après activation du stockage HPOS, les commandes sont enregistrées dans des tables dédiées, distinctes de `wp_posts`, et leurs métadonnées ne transitent plus systématiquement par `wp_postmeta`. La fonction `get_post_meta()` continue de s'exécuter sans erreur PHP, mais elle ne trouve tout simplement rien à l'endroit où elle cherche, d'où un champ vide sans message d'erreur explicite.

## Correctif

La correction consiste à remplacer chaque appel à `get_post_meta()` concernant une commande par l'utilisation de l'objet commande WooCommerce lui-même, via `wc_get_order()`, puis sa méthode `get_meta()`, compatible quel que soit le mode de stockage actif, HPOS ou tables historiques :

```
$commande = wc_get_order( $commande_id );
$numero_tva = $commande ? $commande->get_meta( '_numero_tva_client' ) : '';
```

Cette méthode interroge la bonne source de données de façon transparente, sans que le template n'ait à connaître le mode de stockage réellement actif sur l'installation. C'est précisément l'objectif de la compatibilité HPOS annoncée par l'équipe WooCommerce : les développeurs qui utilisent les méthodes de l'objet commande plutôt que les fonctions génériques de WordPress n'ont rien à changer lors de la bascule.

## Auditer l'ensemble du template

Ce correctif ponctuel a révélé la nécessité d'un audit complet du template d'impression de facture, écrit plusieurs années avant la bascule HPOS et jamais revu depuis :

- Chaque appel à `get_post_meta()` concernant une commande a été recherché et remplacé
- Les accès directs à des propriétés de l'objet `WP_Post` de la commande ont également été vérifiés
- Les requêtes SQL personnalisées, si elles existaient, auraient nécessité une réécriture bien plus lourde
- Le fichier a été retesté sur une commande créée après la bascule, pas seulement sur une commande antérieure encore en cache

## Une donnée qui n'a jamais été perdue

Point important pour rassurer l'équipe cliente au moment du diagnostic : aucune donnée n'avait été perdue lors de la bascule HPOS. Les informations de facturation existaient bien, correctement enregistrées dans les nouvelles tables dédiées aux commandes. Seul le template d'impression, resté figé sur une méthode d'accès obsolète, lisait la mauvaise source. Ce point mérite d'être clairement communiqué : le problème est un bug d'affichage, pas une perte de données.

> Après toute bascule HPOS, la meilleure méthode reste de rechercher systématiquement, dans l'ensemble du code personnalisé du projet, toute occurrence de `get_post_meta`, `get_post` ou de requêtes SQL directes portant sur une commande. Un template qui semblait fonctionner parfaitement peut cacher une dépendance silencieuse à l'ancien mode de stockage.

## En résumé

Un template de facture codé à la main, qui interroge les métadonnées de commande via `get_post_meta()` plutôt que via les méthodes de l'objet commande WooCommerce, cesse de fonctionner correctement après la bascule vers le stockage HPOS. Le correctif reste simple une fois le diagnostic posé : passer par `wc_get_order()` et sa méthode `get_meta()`, compatible quel que soit le mode de stockage réellement actif sur l'installation.
