Un cabinet d’architecture a fait développer une extension de gestion de projets qu’il a ensuite proposée, sous licence, à d’autres cabinets partenaires. Cette extension ne pouvait évidemment pas être publiée sur WordPress.org : elle était payante, réservée à un public restreint, et intégrait des éléments propriétaires. Restait un problème concret : comment offrir à ses clients le même confort qu’une extension du répertoire officiel, avec une notification et un bouton « Mettre à jour » dans l’admin ?
Le mécanisme interne que WordPress interroge
Chaque fois que l’admin WordPress vérifie les mises à jour disponibles, il construit un objet stocké dans le transient update_plugins, en interrogeant WordPress.org pour chaque extension installée. Le filtre pre_set_site_transient_update_plugins permet d’intercepter cette construction et d’y injecter ses propres informations de version.
add_filter( 'pre_set_site_transient_update_plugins', 'kaolin_verifier_mise_a_jour' );
function kaolin_verifier_mise_a_jour( $transient ) {
if ( empty( $transient->checked ) ) {
return $transient;
}
$info_distante = kaolin_recuperer_infos_version();
if ( $info_distante && version_compare( KAOLIN_PROJETS_VERSION, $info_distante->version, '<' ) ) {
$transient->response[ plugin_basename( __FILE__ ) ] = $info_distante;
}
return $transient;
}
Écrire ce mécanisme entièrement à la main est possible, mais fastidieux : il faut aussi gérer l’écran de détail de la mise à jour (plugins_api), le téléchargement sécurisé du paquet, et l’invalidation correcte du cache. C’est du code qui se ressemble d’un projet à l’autre, ce qui en fait un candidat naturel pour une bibliothèque partagée.
plugin-update-checker : éviter de tout réécrire

La bibliothèque open source plugin-update-checker, largement utilisée dans l’écosystème des extensions commerciales, implémente ce protocole de bout en bout. Elle s’intègre en quelques lignes, à condition d’exposer soi-même un point de terminaison qui renvoie un fichier de métadonnées au format attendu.
require plugin_dir_path( __FILE__ ) . 'vendor/plugin-update-checker/plugin-update-checker.php';
use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
$kaolin_maj = PucFactory::buildUpdateChecker(
'https://updates.kaolin-projets.test/metadata.json',
__FILE__,
'kaolin-gestion-projets'
);
Le fichier metadata.json exposé par le serveur de mise à jour contient les informations attendues par le protocole : numéro de version, URL du paquet ZIP, notes de version, exigences de compatibilité.
{
"name": "Kaolin Gestion de Projets",
"version": "2.3.0",
"download_url": "https://updates.kaolin-projets.test/paquets/kaolin-gestion-projets-2.3.0.zip",
"requires": "5.6",
"tested": "5.8",
"sections": {
"changelog": "<h4>2.3.0</h4><ul><li>Correction d'un bug d'export PDF</li></ul>"
}
}
Sécuriser l’accès au paquet par une licence
Exposer un fichier ZIP à une URL fixe et prévisible serait une erreur : n’importe qui découvrant l’URL pourrait télécharger l’extension sans jamais avoir payé de licence. La bonne pratique consiste à générer une URL de téléchargement temporaire, ou à exiger une clé de licence en paramètre, vérifiée côté serveur avant de livrer le paquet.
$kaolin_maj->addQueryArgFilter( function ( $query_args ) {
$query_args['licence_key'] = get_option( 'kaolin_licence_key' );
$query_args['site_url'] = home_url();
return $query_args;
} );
Côté serveur, chaque requête de vérification ou de téléchargement doit valider la clé de licence transmise, son état d’activation, et idéalement le nombre de sites déjà associés à cette licence, avant de répondre avec les informations de version ou le fichier lui-même.
Ce que le client final ne voit jamais, mais qui compte
Pour les cabinets partenaires utilisateurs de cette extension, tout se passe exactement comme avec une extension classique du répertoire officiel : une notification apparaît dans l’admin, le changelog s’affiche dans la fenêtre de détail habituelle, et un clic suffit à mettre à jour. Cette transparence, obtenue grâce à pre_set_site_transient_update_plugins et à plugin-update-checker, a considérablement réduit le nombre de demandes de support liées à des versions obsolètes de l’extension en circulation chez les clients.
Un mécanisme de mise à jour invisible pour l’utilisateur final est un mécanisme réussi : le client ne doit jamais avoir à se demander comment installer la nouvelle version manuellement.
Pour aller plus loin
Distribuer une extension en dehors de WordPress.org ne prive pas ses utilisateurs du confort natif de mise à jour, à condition d’implémenter soi-même, ou via une bibliothèque éprouvée comme plugin-update-checker, le même protocole que celui utilisé en interne par WordPress. C’est un investissement initial non négligeable, largement rentabilisé dès que le nombre de sites clients dépasse la dizaine.