vendredi 25 septembre 2026

À propos

Contact

Tips

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.

Par Clément Hadrot • 9 avril 2026 • 5 min de lecture • Aucun commentaire
Empêcher la suppression accidentelle du dernier compte administrateur

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.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi