# Protéger un fournisseur référencé d’une suppression tant qu’un produit est actif

> Une fiche fournisseur supprimée par erreur cassait des fiches produit publiées sur une place de marché B2B. Le filtre pre_delete_post bloque désormais la suppression tant qu'un produit y reste rattaché.

- Auteur : WordPress Développement
- Publié le : 2023-05-26
- Mis à jour le : 2023-05-26
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/proteger-fournisseur-suppression-produit-actif/

## L’essentiel

- pre_delete_post permet de bloquer une suppression avant qu'elle ne se produise
- La vérification porte sur les produits publiés, pas sur les brouillons
- Un message d'erreur explicite plutôt qu'un blocage silencieux

« Fournisseur introuvable » : ce message apparaissait sur des dizaines de fiches produit d'une place de marché B2B spécialisée dans les fournitures industrielles, après qu'un administrateur avait supprimé par erreur une fiche fournisseur encore rattachée à plus de quarante produits publiés. La suppression avait fonctionné sans le moindre avertissement, WordPress ne vérifiant par défaut aucune relation entre un type de contenu et un autre.

Le correctif ne consiste pas à ajouter une confirmation supplémentaire — trop facile à valider sans lire — mais à bloquer techniquement la suppression tant qu'un produit publié reste rattaché au fournisseur. Le filtre `pre_delete_post`, disponible depuis WordPress 4.4, permet précisément d'intercepter la suppression avant qu'elle ne s'exécute.

## Intercepter la suppression avant qu'elle ne se produise

Le filtre `pre_delete_post` retourne normalement `null`, ce qui laisse la suppression suivre son cours. En retournant `false`, on l'annule complètement, à condition de le faire uniquement pour les fournisseurs concernés par la vérification.

```
add_filter( 'pre_delete_post', function ( $check, $post, $force_delete ) {
    if ( 'fournisseur' !== get_post_type( $post ) ) {
        return $check;
    }

    $produits_lies = new WP_Query( array(
        'post_type'      => 'produit',
        'post_status'    => 'publish',
        'meta_key'       => 'fournisseur_id',
        'meta_value'     => $post->ID,
        'posts_per_page' => 1,
        'fields'         => 'ids',
    ) );

    if ( $produits_lies->have_posts() ) {
        return false;
    }

    return $check;
}, 10, 3 );
```

> L'essentiel à retenir : pre_delete_post permet de bloquer une suppression avant qu'elle ne se produise ; La vérification porte sur les produits publiés, pas sur les brouillons ; Un message d'erreur explicite plutôt qu'un blocage silencieux

## Afficher un message explicite plutôt qu'un échec silencieux

Bloquer une suppression sans expliquer pourquoi frustre l'administrateur, qui répète parfois la tentative en pensant à un bug d'interface. Un message d'avertissement, affiché juste après la tentative refusée, précise le nombre de produits concernés et invite à les traiter d'abord.

```
add_action( 'admin_notices', function () {
    global $pagenow;
    if ( 'post.php' !== $pagenow || empty( $_GET['ch_suppression_bloquee'] ) ) {
        return;
    }
    printf(
        '<div class="notice notice-error"><p>Ce fournisseur ne peut pas être supprimé : %d produit(s) publié(s) y sont encore rattaché(s).</p></div>',
        absint( $_GET['ch_suppression_bloquee'] )
    );
} );
```

La redirection vers cette notice se fait dans le même filtre, juste avant de retourner `false`, en ajoutant le paramètre à l'URL de retour vers la liste des fournisseurs.

## Pourquoi ne pas vérifier uniquement dans l'interface d'administration

Une vérification placée uniquement au niveau du bouton de suppression, en JavaScript, serait contournable par n'importe quelle requête directe adressée à `wp-admin/post.php` avec l'action `delete`. Le filtre `pre_delete_post` agit au niveau de la fonction `wp_delete_post()` elle-même, ce qui couvre également les suppressions déclenchées par un script, une tâche planifiée ou une commande WP-CLI.

```
wp post delete 482 --force
```

Cette commande, exécutée sans passer par l'interface d'administration, respecte tout de même le blocage, puisqu'elle appelle en interne la même fonction `wp_delete_post()` filtrée par notre code.

## Distinguer produit publié et produit en brouillon

La vérification porte volontairement sur le statut `publish` uniquement. Un produit en brouillon, encore en cours de préparation, ne doit pas empêcher la suppression d'un fournisseur devenu obsolète : c'est un choix assumé, qui laisse aux équipes la liberté de nettoyer leurs fournisseurs inactifs sans être bloquées par des ébauches jamais publiées.

- Un produit en corbeille ne compte pas non plus dans la vérification, puisqu'il n'est de toute façon plus visible publiquement.
- Un produit programmé pour publication future est en revanche traité comme un produit publié, car il deviendra visible sans passage supplémentaire par l'administrateur.
- La vérification s'exécute à chaque tentative de suppression, jamais en tâche de fond, afin de rester exacte au moment précis de la décision.

> Une relation entre deux types de contenu qui n'est jamais vérifiée techniquement finit toujours, tôt ou tard, par être rompue par erreur.

## En résumé

Le filtre `pre_delete_post` couvre en une quinzaine de lignes un risque qui, sur cette place de marché, s'était déjà matérialisé une fois de façon coûteuse. Ce chantier ne traite volontairement pas la fusion de fiches fournisseurs en doublon, un problème différent qui touche à la déduplication plutôt qu'à la protection contre la suppression, et qui mérite son propre outil de résolution.
