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 V2
1 à 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.
-
J’ai choisi
V2
mais ça pourrait tout aussi bien être_2_24
ou_v2
ou_2022
ou … ↩︎
1 De Jean-Christian Paul Denis -
Ah mince ça fonctionne. Tu as une faculté à faire des transitions en douceur qui me déconcerte 😀
Ce n’est pas tellement question de la lourdeur, qui ici est supportable, mais plus de combien de temps une transition reste qui me gène.
2 De Franck -
Si au bout de quelques temps (années ?) on s’aperçoit que la forme V1 n’est plus utilisée, on peut toujours désactiver le plugin proxy, voire le virer de la distribution, pas de souci avec ça.
C’est l’intérêt du plugin par rapport à du code intégré dans le cœur.
D’ailleurs si quelqu’un utilisait, dès la 2.24, que du code moderne (V2), il pourrait tout à fait désactiver ce plugin qui ne servirait à rien.
3 De Biou -
Robustesse > élégance.