Intégrer des fonctions de désinstallation

Avant l'arrivé de Dotclear 2.26 prévu pour ce mois de mai 2023, j'ai repris une partie de codes d'un de mes plugins pour en faire un plus simple qui fourni des fonctions de désinstallation aux autres modules.

A l'heure ou j'écris ces lignes le plugin Uninstaller n'est disponible que sur mon github et uniquement à partir de Dotclear 2.26-dev et PHP 8.1+. Il va permettre lorsque l'on veut supprimer un module (plugin ou thème) de le faire de manière plus complète, on va pouvoir lors de sa suppression également supprimer ses traces comme par exemples ses paramètres, ses éventuelles tables, des fichiers Var, ses Logs, etc... Tout cela de manière simplissime.
Je vous explique comment intégrer cela à vos plugins et thèmes si ils en ont besoin.

Prenons l'exemple du plugin Scronch qui sera écrit pour les dernières évolutions de Dotclear 2.26, c'est à dire qu'il utilisera l'arborescence en espace de nom, ou encore dit autrement qu'il aura un dossier src et que ces fichiers PHP commenceront par namespace Dotclear\Plugin\Scronch;. Ce plugin utilise plusieurs paramètres regroupés dans un espace de nom de paramètres portant son nom. (càd: dcCore::app()->blog->settings->Scronch ) Notre plugin va également enregistrer des logs dans la base de Dotclear, ils seront également regroupés sous son nom.

Le décor est posé. Pour ajouter des fonctions de désinstallation il faut ajouter dans le dossier src un fichier du nom de Uninstall.php qui intègrera donc la classe Uninstall, cette class devra étendre la classe dcNsProcess qui est très utilisée maintenant dans Dotclear. Comme partout la première méthode init() de cette classe va permettre de faire des testes afin de savoir si on peut l'utiliser par la suite. Puis la seconde méthode process() va permettre d'enregistrer les actions de désinstallation à mener. (Elle va également permettre de traiter d'éventuelles actions non standards, j'en reparlerais dans un deuxième exemple). Quand à la troisième méthode render() elle ne servira que si on a besoin d'ajouter un champs de formulaire. (idem on verra ça en deuxième exemple.). Donc si vous suivez, il va falloir dire dans la méthode process() que nous voulons supprimer les logs et les paramètres. Suivons le premier exemple du fichier complet de désinstallation de notre plugin Scronch :

<?php
declare(strict_types=1);

namespace Dotclear\Plugin\Scronch;

use dcCore;
use dcNsProcess;
use Dotclear\Plugin\Uninstaller\Uninstaller;

class Uninstall extends dcNsProcess
{
    public static function init(): bool
    {
        static::$init = defined('DC_CONTEXT_ADMIN');

        return static::$init;
    }

    public static function process(): bool
    {
        if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
            return false;
        }

        Uninstaller::instance()
            ->addUserAction(
                'settings',
                'delete_all',
                'Scronch'
            )
            ->addUserAction(
                'logs',
                'delete_all',
                'Scronch'
            )
            ->addUserAction(
                'plugins',
                'delete',
                'Scronch'
            )
            ->addUserAction(
                'versions',
                'delete',
                'Scronch'
            )
            ->addDirectAction(
                'settings',
                'delete_all',
                'Scronch'
            )
            ->addDirectAction(
                'logs';
                'delete_all',
                'Scronch'
            )
            ->addDirectAction(
                'plugins',
                'delete',
                'Scronch'
            )
            ->addDirectAction(
                'versions',
                'delete',
                'Scronch'
            )
        ;

        // no custom action
        return false;
    }
}

Que voit-on ici ? On va d'abord chercher le désinstalleur avec Uninstaller::instance() Puis on ajoute 4 actions qui sont effacer les paramètres, effacer les logs, effacer le plugin, effacer la version. Mais alors pourquoi y sont-ils deux fois ? Car il y a deux manières de supprimer un module, soit directement (Direct) avec un clic sur supprimer dans la liste des plugins ou thèmes et là les actions seront menées sans aucune question ! Soit en faisant appelle à l'utilisateur (User) avec une liste de choix comme dans l'exemple suivant :

sshot-uninstaller-01.jpg, avr. 2023
Capture écran - Uninstaller prompt

Je laisse seul juge le développeur si il souhaite ou non proposer les actions directes, on m'a déjà fait remarquer que nombre de gens préfère garder ces traces au cas ou il faille réinstaller le module plus tard, on pour sauvegarde... Si toutefois vous souhaitez désactiver les actions directes sur votre plateforme de blogs, il suffit de se rendre dans about:config et de mettre à oui l'entrée system => no_direct_uninstall.

Voici à l'instant T toutes les actions prédéfinies suivi de l'ID du nettoyeur et de son action :

  • effacer le dossier de cache sélectionné : caches - delete
  • vider le dossier de cache sélectionné : caches - empty
  • effacer la table de logs sélectionnée : logs - delete_all
  • supprimer le numéro de version sélectionné : versions - delete
  • supprimer le dossier VAR sélectionné : vars - delete
  • supprimer les fichiers et dossiers du thème sélectionné : themes - delete
  • supprimer les fichiers et dossiers du plugin sélectionné : plugins - delete
  • supprimer la table de base de données sélectionnée : tables - delete
  • vider la table de base de données sélectionnée : tables - empty
  • supprimer les paramètres globaux sélectionnés : settings - delete_global
  • supprimer les paramètres locaux (blog) sélectionnés : settings - delete_local
  • supprimer tous les paramètres sélectionnés : settings: -dellete_all
  • supprimer les paramètres relatifs (cf code) : settings - delete_related
  • supprimer les préférences globales sélectionnées : preferences - delete_global
  • supprimer les préférences locales (utilisateurs) sélectionnées : preferences - delete_local
  • supprimer toutes les préférences sélectionnées : preferences - dellete_all
  • supprimer les préférences relatives (cf code) : preferences - delete_related
Si cela ne suffit pas, il y a toujours des cas spéciaux, en plus de pouvoir écrire et ajouter son propre Nettoyeur, il est prévue de pouvoir utiliser un formulaire personnalisé qui s'ajoutera à la liste de la capture d'écran ci-dessus. Pour cela il suffit de modifier les méthode process() et render() comme suit :
<?php
declare(strict_types=1);

namespace Dotclear\Plugin\Scronch;

use dcCore;
use dcNsProcess;
use Dotclear\Plugin\Uninstaller\Uninstaller;

class Uninstall extends dcNsProcess
{
    public static function init(): bool
    {
        static::$init = defined('DC_CONTEXT_ADMIN');

        return static::$init;
    }

    public static function process(): bool
    {
        if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
            return false;
        }

        if (!empty($_POST['mon_action_perso']) {

                // Ici on exécute la tache de supprimer la choucroute

        }
          // on retourne true pour indiquer qu'on a un formulaire
        return true;
    }

    public static function render(): void
    {
        if (!static::$init) {
            return;
        }

        return (new Para())->items([
                (new Checkbox('mon_action_perso', true))->value(1),
                (new Label('supprimer la choucroute', Label::OUTSIDE_LABEL_AFTER))->for('mon_action_perso')->class('classic'),
        ]); 

    }
}

J'ai supprimé le code des actions prédéfinies dans l'exemple pour le rendre plus clair mais bien entendu on peut les mixer.

Voila, pour l'instant ce plugin est tout jeune et va surement évoluer, mais ces quelques lignes permettent un première approche de ce qui pourra être proposé à tous.

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

Ajouter un rétrolien

URL de rétrolien : https://chez.jcdenis.fr/trackback/59

Haut de page