# Nettoyer les pièces jointes orphelines : les repérer avant de les supprimer

> Lister les médias qui ne sont attachés à aucun contenu pour une revue manuelle du client, sans jamais lancer une suppression automatique risquée.

- Auteur : Clément Hadrot
- Publié le : 2022-11-17
- Mis à jour le : 2022-11-17
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/nettoyer-pieces-jointes-orphelines-reperer-avant-supprimer/

## L’essentiel

- post_parent à zéro ne suffit pas à repérer une vraie orpheline
- Le contenu des articles doit aussi être scanné
- Une liste pour revue reste plus sûre qu'une suppression automatique

Après six ans d'activité sur un site e-commerce, la médiathèque d'un client dépassait les huit mille fichiers, avec un hébergement qui commençait sérieusement à peser sur la facture mensuelle. Le client, plein de bonne volonté, avait déjà trouvé une extension promettant de « supprimer automatiquement les médias inutilisés » et s'apprêtait à cliquer sur le bouton fatidique un vendredi après-midi, sans sauvegarde récente. Nous l'avons arrêté à temps.

Le problème de ce genre d'automatisation, c'est qu'un média peut être utilisé sans jamais avoir été formellement attaché à un contenu via son `post_parent`. Une image insérée manuellement dans un bloc, un fichier référencé dans une option de personnalisation du thème, un logo utilisé uniquement en CSS de fond : tous ces cas échappent à une vérification naïve basée sur le seul champ d'attachement.

## Pourquoi post_parent ne suffit jamais

Une pièce jointe avec `post_parent` à zéro n'est pas nécessairement inutilisée : elle peut très bien être insérée dans le contenu d'un article via son URL, sans que WordPress n'ait jamais mis à jour ce lien de parenté après coup, notamment si l'image a été insérée depuis la médiathèque après la publication initiale de l'article.

## Construire une liste de candidats pour revue manuelle

> L'essentiel à retenir : post_parent à zéro ne suffit pas à repérer une vraie orpheline ; Le contenu des articles doit aussi être scanné ; Une liste pour revue reste plus sûre qu'une suppression automatique

Plutôt qu'une suppression automatique, la démarche la plus sûre consiste à croiser deux sources : les pièces jointes sans parent, et une recherche de leur URL dans le contenu de tous les articles publiés, avant de considérer un fichier comme réellement orphelin :

```
global $wpdb;

$sans_parent = $wpdb->get_results(
    "SELECT ID, guid FROM {$wpdb->posts}
     WHERE post_type = 'attachment' AND post_parent = 0"
);

$candidats_orphelins = array();

foreach ( $sans_parent as $piece ) {
    $nom_fichier = basename( $piece->guid );

    $utilise = $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->posts}
         WHERE post_status = 'publish'
         AND post_content LIKE %s",
        '%' . $wpdb->esc_like( $nom_fichier ) . '%'
    ) );

    if ( 0 === (int) $utilise ) {
        $candidats_orphelins[] = $piece;
    }
}

echo count( $candidats_orphelins ) . ' pièce(s) jointe(s) candidates à une suppression manuelle.';
```

Cette recherche par nom de fichier plutôt que par identifiant reste volontairement permissive : elle génère quelques faux négatifs (des médias signalés comme utilisés alors qu'ils ne le sont plus vraiment) mais évite le risque inverse, bien plus grave, de signaler comme orpheline une image réellement affichée sur le site.

## Ce qu'une telle requête ne détecte jamais

- Une image référencée dans une option de personnalisation du thème stockée sous forme sérialisée, comme un logo choisi via le Customizer.
- Un fichier appelé directement dans une feuille de style ou un fichier JavaScript du thème.
- Une image utilisée comme image à la une (`_thumbnail_id`), qui n'a pas de `post_parent` non plus et nécessite une vérification séparée sur la table `wp_postmeta`.

Compléter la requête précédente avec une vérification sur `_thumbnail_id` reste indispensable avant toute liste définitive :

```
$utilise_en_une = $wpdb->get_var( $wpdb->prepare(
    "SELECT COUNT(*) FROM {$wpdb->postmeta}
     WHERE meta_key = '_thumbnail_id' AND meta_value = %d",
    $piece->ID
) );
```

## Présenter la liste au client sans risque

> Notre règle sur ce type de nettoyage : jamais de suppression automatique en une seule opération. Une liste exportée en CSV, une sauvegarde préalable, une revue par le client lui-même sur les fichiers les plus lourds, puis une suppression manuelle en petits lots.

Pour un client qui n'a pas le temps de tout vérifier, trier la liste par poids décroissant plutôt que par date permet de traiter en priorité les quelques fichiers qui représentent l'essentiel de l'espace disque récupérable, souvent d'anciennes images non redimensionnées bien plus lourdes que la moyenne.

## En résumé

Repérer des pièces jointes orphelines demande de croiser plusieurs sources plutôt que de se fier au seul champ `post_parent`, sous peine de supprimer des médias pourtant bien utilisés. Cette démarche de nettoyage reste distincte de la régénération des tailles d'image, qui répond à un besoin différent déjà traité par ailleurs.
