# Empêcher la suppression accidentelle du dernier compte administrateur

> Sur un site géré par une seule personne, perdre son unique compte administrateur par erreur peut coûter cher. Un blocage par code élimine ce risque précis.

- Auteur : Clément Hadrot
- Publié le : 2026-04-09
- Mis à jour le : 2026-04-09
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/empecher-suppression-accidentelle-dernier-compte-administrateur/

## L’essentiel

- map_meta_cap intercepte la capacité avant l'exécution réelle
- count_users donne le nombre exact d'administrateurs restants
- Le blocage doit couvrir la suppression individuelle et la suppression groupée

Un gérant de commerce qui administre seul son site vitrine WordPress avait, un jour, supprimé par erreur son propre compte administrateur en pensant nettoyer un compte de test créé lors de la mise en ligne initiale. Sans autre compte administrateur, il s'est retrouvé bloqué hors de son propre tableau de bord, une situation résolue uniquement grâce à un accès direct à la base de données par son hébergeur.

Sur les sites gérés par une seule personne ou une petite équipe, ce scénario n'est pas si rare : un ménage de comptes obsolètes qui va un cran trop loin. La parade consiste à intercepter la capacité de suppression au niveau le plus bas possible, avant même que l'écran de confirmation ne s'affiche, pour empêcher techniquement la suppression du dernier compte administrateur du site.

## Le bon point d'interception : map_meta_cap

Le filtre `map_meta_cap` transforme une capacité « méta » (comme `delete_user`, appliquée à un utilisateur précis) en capacités concrètes vérifiées ensuite par WordPress. C'est le bon endroit pour retirer la capacité effective de suppression quand la cible est le dernier administrateur restant, plutôt que d'intercepter après coup une action déjà entamée :

```
add_filter( 'map_meta_cap', function ( $capacites, $cap, $id_utilisateur_courant, $args ) {
    if ( 'delete_user' !== $cap && 'delete_users' !== $cap ) {
        return $capacites;
    }

    $id_cible = $args[0] ?? 0;

    if ( commerce_est_dernier_administrateur( $id_cible ) ) {
        $capacites[] = 'do_not_allow';
    }

    return $capacites;
}, 10, 4 );
```

Ajouter la pseudo-capacité `do_not_allow` à la liste retournée fait échouer toute vérification ultérieure de `current_user_can()` sur cette action précise, quelle que soit par ailleurs la capacité réelle de la personne qui tente la suppression — y compris un autre administrateur, ce qui est le comportement recherché ici.

## Déterminer si la cible est le dernier administrateur

> L'essentiel à retenir : map_meta_cap intercepte la capacité avant l'exécution réelle ; count_users donne le nombre exact d'administrateurs restants ; Le blocage doit couvrir la suppression individuelle et la suppression groupée

```
function commerce_est_dernier_administrateur( int $id_utilisateur ) {
    $utilisateur = get_userdata( $id_utilisateur );

    if ( ! $utilisateur || ! in_array( 'administrator', (array) $utilisateur->roles, true ) ) {
        return false;
    }

    $comptage = count_users();
    $nombre_administrateurs = $comptage['avail_roles']['administrator'] ?? 0;

    return $nombre_administrateurs <= 1;
}
```

La fonction native `count_users()` renvoie un tableau détaillé du nombre d'utilisateurs par rôle, sans qu'il soit nécessaire de lancer une requête personnalisée sur la table des utilisateurs. Le test `<= 1` plutôt que `=== 1` couvre par prudence un cas limite où le comptage serait à zéro, bien que ce cas ne devrait normalement jamais se produire sur un site fonctionnel.

### Couvrir aussi la suppression groupée

L'écran `Utilisateurs` propose une action groupée de suppression, qui appelle la même capacité `delete_users` mais sur plusieurs identifiants à la fois. Le filtre ci-dessus la couvre déjà, puisque `map_meta_cap` est invoqué pour chaque utilisateur ciblé individuellement par WordPress en interne lors du traitement d'une action groupée — un point qui mérite tout de même d'être vérifié par un test manuel, les comportements internes pouvant varier selon la version du cœur utilisée.

## Afficher un message clair plutôt qu'un blocage muet

Sans message explicite, la ligne du compte concerné disparaîtrait simplement des cases sélectionnables sans qu'aucune explication ne soit donnée, ce qui pourrait sembler être un bug. Un message d'avertissement directement sur la ligne du compte protégé clarifie la situation :

```
add_filter( 'user_row_actions', function ( $actions, WP_User $utilisateur ) {
    if ( commerce_est_dernier_administrateur( $utilisateur->ID ) ) {
        unset( $actions['delete'] );
        $actions['protection'] = '<span style="color:#8a6d1e;">Dernier administrateur, suppression désactivée</span>';
    }

    return $actions;
}, 10, 2 );
```

## Et si l'on veut vraiment supprimer ce compte ?

Le blocage ne doit jamais être permanent et absolu : un gérant qui change réellement de prestataire technique doit pouvoir transférer son rôle d'administrateur avant suppression. La bonne pratique reste de toujours créer et vérifier un second compte administrateur au préalable — cette protection empêche justement de sauter cette étape par erreur, elle n'empêche jamais une suppression légitime une fois un second administrateur en place.

- Ne comptez que les comptes réellement actifs (pas ceux placés en attente d'activation), sous peine de faux positifs sur le comptage.
- Testez le comportement avec un compte super-administrateur sur un réseau multisite, où la logique de rôles diffère légèrement.
- Documentez cette protection dans la documentation interne du site, pour qu'un futur développeur ne la découvre pas par surprise en cherchant pourquoi une suppression échoue silencieusement.

> Sur tous les sites gérés par une seule personne, je recommande systématiquement ce type de garde-fou technique en complément d'une bonne pratique organisationnelle : la vigilance humaine finit toujours par faillir un jour, un blocage au niveau du code ne connaît pas la fatigue de fin de journée.

## Ce qu'il faut retenir

Ce garde-fou tient en quelques lignes, s'appuie entièrement sur des fonctions natives de WordPress, et élimine un risque précis mais aux conséquences potentiellement lourdes : la perte d'accès complète à son propre site faute d'un second compte administrateur disponible. C'est le genre de protection qui ne coûte presque rien et qu'on regrette systématiquement de ne pas avoir mise en place avant l'incident.
