Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

Mettre à jour une extension privée hors WordPress.org : serveur de mises à jour

Une extension vendue sous licence à des cabinets d'architecture ne peut pas transiter par WordPress.org. Comment lui offrir malgré tout le confort d'une mise à jour en un clic ?

Par WordPress Développement • 16 septembre 2021 • 4 min de lecture • Aucun commentaire
Mettre à jour une extension privée hors WordPress.org : serveur de mises à jour

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

L'essentiel à retenir : WordPress interroge un transient précis pour savoir si une mise à jour existe ; plugin-update-checker évite de réimplémenter tout le protocole à la main ; Une vérification de licence doit conditionner l'accès au paquet, pas seulement l'affichage

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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

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

Voir tous ses articles

Dans la même veine

À lire aussi