# is_admin, wp_doing_ajax, REST_REQUEST : savoir où votre code s’exécute

> Ces fonctions et constantes indiquent si le code s'exécute en admin, en AJAX, en REST, en cron ou en CLI, avec des pièges fréquents à éviter.

- Auteur : Clément Hadrot
- Publié le : 2024-08-28
- Mis à jour le : 2024-08-28
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/is-admin-wp-doing-ajax-rest-request-ou-execute-code/

## L’essentiel

- Cinq contextes distincts à détecter correctement
- is_admin ne signifie pas ce qu'on croit souvent
- Un même hook peut s'exécuter dans plusieurs contextes

Une extension qui enregistre un script uniquement destiné au site public, mais qui se retrouve chargé aussi dans l'éditeur de blocs, provoque presque toujours le même type de bug : un script qui entre en conflit avec l'interface d'administration. La cause est souvent la même, une condition `is_admin()` mal comprise, utilisée pour détecter autre chose que ce qu'elle indique réellement.

WordPress s'exécute dans plusieurs contextes bien distincts, et connaître les fonctions et constantes qui les distinguent évite une bonne partie des bugs de portée liés aux hooks.

## is_admin() : administration, pas privilèges

La confusion la plus répandue consiste à croire que `is_admin()` vérifie si l'utilisateur courant est administrateur. Ce n'est pas son rôle : cette fonction indique simplement si la requête courante cible une page de l'interface d'administration (`/wp-admin/`), quel que soit le rôle de la personne connectée, y compris un simple abonné qui accède à son profil.

```
if ( is_admin() ) {
    // On est dans /wp-admin/, pas forcément un administrateur
}

// Pour vérifier réellement les droits :
if ( current_user_can( 'manage_options' ) ) {
    // Ici, on vérifie une capacité, pas un contexte
}
```

Autre piège fréquent : une requête AJAX déclenchée depuis l'administration (via `admin-ajax.php`) renvoie également `true` pour `is_admin()`, ce qui surprend souvent lors de l'écriture d'un gestionnaire AJAX.

## wp_doing_ajax() : distinguer l'AJAX du reste

Introduite pour clarifier justement ce cas, la fonction `wp_doing_ajax()` retourne `true` dès que la requête passe par `admin-ajax.php`, qu'elle soit initiée depuis le site public ou l'administration :

> L'essentiel à retenir : Cinq contextes distincts à détecter correctement ; is_admin ne signifie pas ce qu'on croit souvent ; Un même hook peut s'exécuter dans plusieurs contextes

```
add_action( 'init', function () {
    if ( wp_doing_ajax() ) {
        return; // Ne pas charger de scripts inutiles pendant une requête AJAX
    }
} );
```

## REST_REQUEST : le contexte de l'API REST

Lorsque la requête transite par l'API REST de WordPress, la constante `REST_REQUEST` est définie et vaut `true`. Elle n'existe pas avant que le point d'entrée REST ne soit atteint, ce qui impose de toujours la tester avec `defined()` avant de la lire :

```
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
    // Requête passée par wp-json/
}
```

## wp_doing_cron() et WP_CLI : les contextes serveur

Deux autres contextes complètent ce tableau : les tâches planifiées, détectables via `wp_doing_cron()`, et la ligne de commande, détectable via la constante `WP_CLI`, définie uniquement lorsque le code s'exécute via WP-CLI :

```
if ( wp_doing_cron() ) {
    // Exécution via wp-cron.php, pas de session utilisateur active
}

if ( defined( 'WP_CLI' ) && WP_CLI ) {
    // Exécution en ligne de commande, souvent sans limite de temps d'exécution classique
}
```

## Un exemple qui combine plusieurs contextes

Une extension qui envoie une notification par courriel lors de la publication d'un article ne doit s'exécuter ni en CLI lors d'un import massif, ni en AJAX lors d'un enregistrement automatique :

```
add_action( 'save_post', function ( $post_id, $post, $update ) {
    if ( defined( 'WP_CLI' ) && WP_CLI ) {
        return; // Éviter d'envoyer des centaines de courriels lors d'un import WP-CLI
    }

    if ( wp_doing_ajax() && ! isset( $_POST['publier_notification'] ) ) {
        return;
    }

    // Envoi de la notification
}, 10, 3 );
```

## Tableau récapitulatif

| Contexte | Détection |
| --- | --- |
| Interface d'administration | is_admin() |
| Requête AJAX | wp_doing_ajax() |
| API REST | defined( 'REST_REQUEST' ) && REST_REQUEST |
| Tâche planifiée (cron) | wp_doing_cron() |
| Ligne de commande | defined( 'WP_CLI' ) && WP_CLI |

> Un même hook peut être déclenché dans plusieurs contextes à la fois : penser qu'un hook « ne s'exécute que côté public » est une hypothèse à vérifier, jamais à supposer.

## Ce que ces fonctions ne couvrent pas

Elles ne disent rien de l'ordre d'exécution des hooks entre eux, ni des priorités appliquées à un même hook par différentes extensions : c'est un sujet distinct, qui relève de la compréhension du cycle de chargement de WordPress plutôt que de la détection de contexte.

## En résumé

Cinq fonctions et constantes suffisent à couvrir la quasi-totalité des contextes d'exécution que rencontre une extension WordPress. Les connaître et les tester systématiquement avant d'exécuter un traitement lourd ou sensible évite des bugs difficiles à reproduire, car ils ne se manifestent que dans un contexte précis, rarement testé manuellement.
