# self_admin_url() : un lien d’administration valable aussi en multisite

> admin_url() fabrique un lien qui ne change pas selon le contexte d'affichage. self_admin_url() sait, elle, distinguer réseau, profil personnel et site.

- Auteur : WordPress Développement
- Publié le : 2026-10-22
- Mis à jour le : 2026-09-30
- Catégorie : Extensions
- URL : https://www.wpmoderne.fr/extensions/self-admin-url-multisite/

## L’essentiel

- self_admin_url() détecte le contexte réseau ou profil personnel
- Elle retombe sur admin_url() dans un site simple
- Une notice partagée entre plusieurs contextes doit s'appuyer dessus

`self_admin_url()` renvoie un lien différent selon l'endroit d'où on l'appelle, alors que sa signature ne contient qu'un chemin et un schéma. C'est précisément ce comportement contextuel qui la rend utile en multisite, et son absence dans le code d'une extension qui affiche la même notice à plusieurs endroits du réseau produit un symptôme classique : un lien « Configurer l'extension » qui pointe systématiquement vers l'administration du site principal, même quand l'administrateur consulte l'écran réseau ou son profil personnel.

Le réflexe le plus répandu consiste à utiliser `admin_url()` partout, sans distinction. Cette fonction fonctionne parfaitement sur un site WordPress classique. Le problème apparaît uniquement lorsque la même notice, le même callback ou la même extension s'exécute aussi bien dans l'administration réseau que dans l'administration d'un site individuel — un cas fréquent pour toute extension activée réseau.

## Ce que fait exactement self_admin_url()

Le cœur de WordPress distingue trois contextes d'administration en multisite : l'administration d'un site (`is_network_admin()` et `is_user_admin()` tous deux faux), l'administration réseau (`is_network_admin()` vrai) et l'administration du profil personnel partagé, dite « user admin » (`is_user_admin()` vrai, écrans accessibles depuis my-sites.php notamment). `self_admin_url()` vérifie ce contexte et redirige son résultat en conséquence :

```
function self_admin_url( $path = '', $scheme = 'admin' ) {
    if ( is_network_admin() ) {
        return network_admin_url( $path, $scheme );
    } elseif ( is_user_admin() ) {
        return user_admin_url( $path, $scheme );
    } else {
        return admin_url( $path, $scheme );
    }
}
```

Autrement dit, appeler `self_admin_url( 'options-general.php?page=mon-extension' )` depuis un callback qui s'exécute pendant que l'administrateur consulte `wp-admin/network/` renverra une URL sous `wp-admin/network/options-general.php...`, alors que `admin_url()` aurait renvoyé une URL sous le site actuellement « courant », qui peut n'avoir aucun rapport avec l'écran réellement affiché.

## Le cas concret : une notice partagée entre deux hooks

> L'essentiel à retenir : self_admin_url() détecte le contexte réseau ou profil personnel ; Elle retombe sur admin_url() dans un site simple ; Une notice partagée entre plusieurs contextes doit s'appuyer dessus

Une extension activée sur l'ensemble d'un réseau enregistre souvent sa notice d'administration à la fois sur `admin_notices` (affichage dans chaque site) et sur `network_admin_notices` (affichage dans l'écran réseau). Si le même callback génère le lien avec `admin_url()`, le lien reste identique dans les deux contextes et pointe vers le site qui était « courant » au moment de la génération, ce qui n'a souvent aucun sens depuis l'écran réseau :

```
function ma_notice_reglages() {
    $lien = self_admin_url( 'admin.php?page=mon-extension-reglages' );
    printf(
        '<p>Pensez à <a href="%s">terminer la configuration</a>.</p>',
        esc_url( $lien )
    );
}
add_action( 'admin_notices', 'ma_notice_reglages' );
add_action( 'network_admin_notices', 'ma_notice_reglages' );
```

## Une différence qui ne saute pas aux yeux en test manuel

Le piège tient à la façon dont ce bug se révèle : en environnement de développement mono-site, `admin_url()` et `self_admin_url()` produisent exactement le même résultat, puisque les fonctions `is_network_admin()` et `is_user_admin()` renvoient toutes deux faux hors multisite. Le défaut ne se manifeste qu'une fois l'extension déployée sur un réseau réel, généralement remonté par un client qui signale « le lien de la notice m'envoie sur le mauvais site » sans qu'il soit toujours facile de reproduire le problème sur un poste de développement classique.

> Une fonction qui se comporte différemment selon son contexte d'appel n'est pas imprévisible : elle rend simplement explicite une distinction que le code appelant avait ignorée.

C'est également une source d'erreur dans les tests automatisés : un test qui simule uniquement le contexte d'un site individuel ne détectera jamais la régression, puisque le comportement de `self_admin_url()` n'y diffère pas de celui d'`admin_url()`. Seul un test qui force `is_network_admin()` à vrai, ou une vérification manuelle depuis l'écran réseau, révèle la différence.

## Quand ne pas s'en préoccuper

Sur un site WordPress qui ne fait pas partie d'un réseau multisite, les deux fonctions sont strictement équivalentes : il n'y a aucune raison de remplacer `admin_url()` par `self_admin_url()` dans une extension conçue pour un usage exclusivement mono-site. La distinction n'a de valeur que pour du code réellement partagé entre plusieurs contextes d'administration, ce qui concerne principalement les extensions activées réseau, ou tout code exécuté par un hook susceptible de se déclencher aussi bien dans l'administration réseau que dans celle d'un site.

## Ce qui reste hors périmètre

La construction explicite d'un lien réseau avec `network_admin_url()` répond à un besoin différent : celui où l'on souhaite toujours pointer vers l'administration réseau, quel que soit le contexte d'appel, par exemple pour un lien affiché uniquement dans un écran destiné aux super-administrateurs. Le choix entre les deux dépend d'une question simple : le lien doit-il suivre le contexte d'affichage, ou toujours viser un endroit fixe ?

- Utiliser self_admin_url() dès qu'un même callback génère un lien dans plusieurs contextes d'administration.
- Conserver admin_url() pour tout code strictement lié à un site précis, hors ambiguïté de contexte.
- Tester manuellement depuis l'écran réseau avant de valider une notice partagée sur un projet multisite.
- Ne jamais supposer qu'un test sur un site simple couvre le comportement réseau.

self_admin_url() ne remplace pas admin_url() dans l'absolu : elle répond à une contrainte précise, celle d'un lien qui doit rester cohérent avec l'écran depuis lequel il est généré. Ignorer cette nuance sur un projet multisite produit exactement le symptôme décrit ici : un lien qui semble correct en développement et se révèle faux uniquement en production, sur le réseau réel.
