Un champ personnalisé ACF ajouté sur les variations d’un produit — une référence fournisseur interne, dans ce cas précis — s’enregistrait correctement à la création, puis disparaissait au premier enregistrement suivant du produit parent. Le champ redevenait vide dans l’éditeur ACF, sans message d’erreur, sans rien dans les journaux.
Le champ était de type texte, rattaché à un groupe ACF ciblant l’emplacement Variation produit, une configuration standard largement documentée par ACF pour WooCommerce. Rien d’exotique dans la configuration du champ lui-même.
Reproduire le symptôme pas à pas
La reproduction a nécessité plusieurs essais avant d’isoler la séquence exacte : le champ se vidait uniquement quand le produit parent était enregistré via l’écran d’édition rapide des variations (« Enregistrer les modifications » en bas du panneau Variations), et jamais quand la variation était modifiée seule via une requête wc/v3/products/{id}/variations/{variation_id} de l’API REST. Cette distinction a orienté le diagnostic vers l’écran d’administration plutôt que vers ACF lui-même.
Diagnostic : deux hooks save qui se marchent dessus

L’écran d’édition des variations WooCommerce déclenche, à l’enregistrement du produit parent, la fonction WC_AJAX::save_variations(), qui reconstruit chaque variation en appelant WC_Product_Variation::save(). Cette reconstruction repose sur les données postées dans le tableau variable_post_id, traitées dans une boucle qui recrée l’objet variation avant de le sauvegarder.
ACF, de son côté, s’accroche à acf/save_post pour écrire ses champs, avec une priorité par défaut de 10. Le problème : dans cette version de WooCommerce, la sauvegarde des variations via l’écran d’admin déclenchait acf/save_post une première fois pendant la boucle de reconstruction, avant que WooCommerce n’ait fini d’attribuer l’ID définitif de la variation dans certains cas de variations nouvellement créées le même jour. ACF écrivait alors sa valeur sur un ID de variation qui allait être remplacé juste après par la suite du traitement WooCommerce, provoquant la perte du champ.
Le correctif : forcer l’ordre d’exécution
La solution ne consiste pas à modifier ACF ni WooCommerce, mais à retarder explicitement l’écriture du champ personnalisé jusqu’à ce que WooCommerce ait terminé sa propre sauvegarde, en s’accrochant à un hook plus tardif et spécifique aux variations : woocommerce_save_product_variation, qui se déclenche après que l’ID définitif de la variation est stable.
add_action( 'woocommerce_save_product_variation', function( $variation_id, $i ) {
if ( isset( $_POST['reference_fournisseur'][ $i ] ) ) {
update_field( 'reference_fournisseur', sanitize_text_field( $_POST['reference_fournisseur'][ $i ] ), $variation_id );
}
}, 20, 2 );
Ce hook natif WooCommerce a remplacé la dépendance à acf/save_post pour ce champ précis, sans désactiver ACF pour les autres emplacements (produit simple, catégories), où le comportement par défaut restait fiable.
Pourquoi ce bug n’apparaît pas systématiquement
Ce conflit ne se manifestait que sur des variations créées et modifiées dans la même session d’édition, avant que le cache d’objets WordPress n’ait eu l’occasion de stabiliser les identifiants. Sur une variation existante depuis plusieurs jours, simplement rééditée, le bug ne se reproduisait pas : c’est ce qui a rendu le diagnostic initial plus long que prévu, l’équipe ayant d’abord soupçonné un souci de cache navigateur.
- Symptôme : champ vide après enregistrement du produit parent.
- Terrain favorable : variation nouvellement créée, modifiée dans la foulée.
- Terrain neutre : variation ancienne, modifiée isolément via l’API REST.
Conseil maison : pour tout champ personnalisé qui doit survivre à un enregistrement de variation WooCommerce, préférez toujours
woocommerce_save_product_variationàacf/save_post. C’est plus verbeux à écrire, mais l’ordre d’exécution est garanti par WooCommerce lui-même, pas par une priorité de hook fragile.
Prévention
Avant d’ajouter un champ ACF sur des variations produit, la checklist désormais appliquée : tester l’enregistrement sur une variation fraîchement créée dans la même session, pas seulement sur une variation existante rééditée le lendemain ; vérifier le comportement à la fois depuis l’écran d’administration classique et depuis l’API REST ; et documenter, dans le code, pourquoi ce hook spécifique a été choisi plutôt que le hook générique ACF, pour que la prochaine personne qui touche ce fichier ne revienne pas en arrière par erreur.
En résumé
Un champ ACF qui se vide sur une variation WooCommerce n’est presque jamais un bug d’ACF isolé : c’est le symptôme d’une course entre deux systèmes de sauvegarde qui ne se coordonnent pas nativement. S’accrocher directement aux hooks de variation propres à WooCommerce, plutôt qu’aux hooks génériques d’ACF, élimine la classe entière de ce problème.