# register_activation_hook : les erreurs qui cassent l’activation d’une extension

> Un écran blanc au clic sur « Activer », un message d'en-têtes déjà envoyés, des règles de réécriture qui ne se génèrent jamais : le hook d'activation cache plus de pièges qu'il n'y paraît.

- Auteur : Clément Hadrot
- Publié le : 2020-01-30
- Mis à jour le : 2020-01-30
- Catégorie : Extensions
- URL : https://wpmoderne.dev.wordpress-developpement.fr/extensions/register-activation-hook-erreurs-activation/

## L’essentiel

- Le hook doit être déclaré dans le fichier principal, jamais dans un fichier inclus
- flush_rewrite_rules se place après l'enregistrement du CPT, pas avant
- Le multisite change tout : une activation peut concerner un ou tous les sites

« Ça marchait chez moi. » C'est souvent la première phrase qu'on entend quand une extension refuse de s'activer chez un client alors qu'elle fonctionnait parfaitement en local. Le hook d'activation, `register_activation_hook`, a la particularité d'être invisible en développement courant : on ne le déclenche qu'une fois, à l'installation, et on l'oublie vite jusqu'au jour où il casse tout.

Voici les quatre erreurs les plus fréquentes que j'ai vues, ou commises, autour de ce hook — avec, pour chacune, le diagnostic et le correctif.

## Le hook déclaré au mauvais endroit

**Ce qu'on voit :** l'extension s'active sans erreur visible, mais la routine d'activation ne s'exécute jamais. Aucune table créée, aucune option initialisée.

**Pourquoi c'est un problème :** `register_activation_hook()` a besoin du chemin exact du fichier principal de l'extension pour construire le hook interne qu'il écoute. Si l'appel est fait depuis un fichier inclus (une classe dans `includes/class-activator.php` par exemple) en utilisant `__FILE__` à cet endroit, WordPress calcule un mauvais chemin et le hook ne se déclenche jamais.

```
// Dans le fichier principal kaolin-reservations.php, à la racine
register_activation_hook( __FILE__, array( 'Kaolin_Activator', 'activer' ) );
```

**Quoi faire :** appelez toujours `register_activation_hook` depuis le fichier principal (celui qui porte l'en-tête de l'extension), même si la logique elle-même vit dans une classe importée. Le premier argument doit être `__FILE__` évalué dans ce fichier-là, jamais une constante recalculée ailleurs.

## Une sortie parasite avant l'activation

**Ce qu'on voit :** un message « Cannot modify header information » ou une activation qui échoue avec un écran blanc, alors que le code d'activation semble correct.

**Pourquoi c'est un problème :** tout octet envoyé avant l'appel à la fonction d'activation empêche WordPress de rediriger proprement après l'activation. Un espace avant `<?php`, une balise fermante `?>` suivie d'un retour à la ligne, ou pire, un `var_dump()` resté dans le code : tout cela produit une sortie parasite fatale à ce moment précis.

- Vérifiez qu'aucun fichier de l'extension ne commence par un BOM (byte order mark) invisible
- Supprimez la balise fermante `?>` en fin de fichier PHP : elle n'est jamais obligatoire
- Traquez les fonctions de débogage laissées par mégarde (`print_r`, `var_dump`, `echo` de test)

## flush_rewrite_rules mal placé

> L'essentiel à retenir : Le hook doit être déclaré dans le fichier principal, jamais dans un fichier inclus ; flush_rewrite_rules se place après l'enregistrement du CPT, pas avant ; Le multisite change tout : une activation peut concerner un ou tous les sites

**Ce qu'on voit :** un Custom Post Type fraîchement créé fonctionne dans l'admin, mais toutes ses pages publiques renvoient une erreur 404, même après avoir réenregistré les permaliens manuellement.

**Pourquoi c'est un problème :** `flush_rewrite_rules()` régénère les règles de réécriture à partir de ce qui est actuellement enregistré. Si on l'appelle dans le hook d'activation avant que le CPT ne soit déclaré, WordPress régénère des règles qui ne connaissent pas encore ce type de contenu.

```
function kaolin_activer() {
    kaolin_enregistrer_cpt_reservation(); // d'abord enregistrer le CPT
    flush_rewrite_rules();                 // puis seulement régénérer
}
register_activation_hook( __FILE__, 'kaolin_activer' );

add_action( 'init', 'kaolin_enregistrer_cpt_reservation' );
```

**Quoi faire :** appelez explicitement la fonction d'enregistrement du CPT à l'intérieur du hook d'activation, avant `flush_rewrite_rules()`, même si cette même fonction est déjà accrochée normalement à `init`. Et surtout, n'appelez jamais `flush_rewrite_rules()` à chaque chargement de page : c'est une opération coûteuse réservée à l'activation, la désactivation, ou un changement volontaire de structure.

## Le multisite oublié

**Ce qu'on voit :** l'extension fonctionne parfaitement sur une installation simple, mais échoue ou ne s'active qu'à moitié sur un réseau multisite, en particulier lors d'une activation réseau.

**Pourquoi c'est un problème :** lorsqu'une extension est activée à l'échelle du réseau, WordPress transmet un second paramètre au callback : `$network_wide`. Ignorer ce paramètre revient à n'initialiser qu'un seul site alors que l'administrateur pensait activer l'extension partout.

```
function kaolin_activer( $network_wide ) {
    if ( is_multisite() && $network_wide ) {
        $sites = get_sites( array( 'fields' => 'ids' ) );
        foreach ( $sites as $site_id ) {
            switch_to_blog( $site_id );
            kaolin_creer_tables();
            restore_current_blog();
        }
    } else {
        kaolin_creer_tables();
    }
}
register_activation_hook( __FILE__, 'kaolin_activer' );
```

**Quoi faire :** déclarez toujours le paramètre `$network_wide` dans la signature du callback, même si votre extension ne cible pas officiellement le multisite aujourd'hui. Un client qui migre vers un réseau plus tard vous remerciera de ne pas avoir à tout réécrire.

> Sur ce genre de bug, le réflexe qui fait gagner le plus de temps reste de désactiver puis réactiver l'extension en observant l'onglet Réseau du navigateur : la réponse HTTP de la requête d'activation contient souvent le message d'erreur PHP complet, même quand l'écran affiché reste blanc.

## Ce qu'il faut retenir

Le hook d'activation ne s'exécute qu'une fois par installation, ce qui en fait un des morceaux de code les moins testés d'une extension en développement courant. C'est précisément pour cela qu'il mérite une attention particulière : un bug ici ne se révèle souvent que chez le client, au pire moment.

Fichier principal, sortie propre, ordre d'exécution respecté, multisite anticipé : ces quatre points couvrent la grande majorité des activations qui échouent silencieusement en production.
