Plugin proxy

Arènes de Vérone, août 2022
Arènes de Vérone

JcDenis m’a glissé une idée dans un des commentaires et j’ai essayé de mettre ça en pratique pour voir, si comme il le supposait, ça ne pouvait fonctionner.

J’ai commencé à coder ça hier, sur une branche de travail locale et contrairement à ce que je m’attendais, ça fonctionne plutôt pas mal !

Côté technique, le plugin a un fichier _prepend.php contenant ceci :

<?php
/**
 * @brief dcProxyV2, a plugin for Dotclear 2
 *
 * @package Dotclear
 * @subpackage Plugins
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
if (!defined('DC_RC_PATH')) {
    return;
}

class dcProxyV2
{
    public const SUFFIX = 'V2';

    public static function loadBehaviors(string $class, string $file)
    {
        global $__autoload;

        $__autoload[$class] = $file;

        $reflectionCore = new ReflectionClass($class);
        foreach ($reflectionCore->getMethods(ReflectionMethod::IS_STATIC) as $method) {
            dcCore::app()->addBehavior($method->name . self::SUFFIX, [$method->class, $method->name]);
        }
    }
}

dcProxyV2::loadBehaviors('dcProxyV2CoreBehaviors', __DIR__ . '/inc/class.core.behaviors.php');  // Load core stuff
dcProxyV2::loadBehaviors('dcProxyV2PublicBehaviors', __DIR__ . '/inc/class.public.behaviors.php');  // Load public stuff

if (!defined('DC_CONTEXT_ADMIN')) {
    return false;
}

dcProxyV2::loadBehaviors('dcProxyV2AdminBehaviors', __DIR__ . '/inc/class.admin.behaviors.php');  // Load admin stuff

Ce qui permet d’enregistrer tous les behaviors contenus dans les trois fichiers de classe utilisés (core, public et admin), en ajoutant V21 à la fin du nom du behavior ; tandis que dans ces fichiers on trouve simplement des fonctions de rappel statiques qui se chargent d’appeler les anciennes formes en ajoutant le ou les paramètres attendus à l’époque.

Exemple avec les behaviors du core :

<?php
/**
 * @brief dcProxyV2, a plugin for Dotclear 2
 *
 * @package Dotclear
 * @subpackage Plugins
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
if (!defined('DC_RC_PATH')) {
    return;
}

// Core behaviours

class dcProxyV2CoreBehaviors
{
    // Count: 3

    public static function coreBeforeLoadingNsFiles($that, $lang)
    {
        return dcCore::app()->callBehavior('coreBeforeLoadingNsFiles', dcCore::app(), $that, $lang);
    }
    public static function coreCommentSearch($table)
    {
        return dcCore::app()->callBehavior('coreCommentSearch', dcCore::app(), $table);
    }
    public static function corePostSearch($table)
    {
        return dcCore::app()->callBehavior('corePostSearch', dcCore::app(), $table);
    }
}

L’avantage est qu’on peut utiliser indifféremment l’ancienne ou la nouvelle version (suffixée V2) des behaviors, ça reste compatible :

dcCore::app()->callBehavior('adminBlogPreferencesForm', dcCore::app(), $blog_settings);
dcCore::app()->callBehavior('adminBlogPreferencesFormV2', $blog_settings);

Les deux lignes ont un résultat identique vu que l’appel au behavior V2 va aussi passer par un appel à la forme V1, via le plugin proxy.

Ça permet ensuite d’adapter le code aux nouvelles formes et de rester compatible avec l’éco-système existant des thèmes et plugins tiers.

Côté passage à la V2, ça devient :

//dcCore::app()->addBehavior('adminBlogPreferencesForm', ['antispamBehaviors', 'adminBlogPreferencesForm']);
dcCore::app()->addBehavior('adminBlogPreferencesFormV2', ['antispamBehaviors', 'adminBlogPreferencesForm']);

…

//public static function adminBlogPreferencesForm(dcCore $core, $settings)
public static function adminBlogPreferencesForm($settings)
{

…

}

J’ai un proof of concept qui fonctionne, mais il reste tout de même un truc, que je n’ai pas encore identifié, qui me gêne dans tout ça — la raison pour laquelle je n’ai encore rien poussé sur la branche principale du dépôt !

Le concept est robuste mais moyennement élégant je trouve.

Vous en pensez quoi vous ?

PS : Ce plugin n’est dans l’idée pas limité à la « traduction » des empreintes des fonctions de rappel des behaviors, il pourrait également servir à « patcher » d’autres parties du code, sur le même principe.


  1. J’ai choisi V2 mais ça pourrait tout aussi bien être _2_24 ou _v2 ou _2022 ou … ↩︎

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/15447

Haut de page