Le plugin Uninstaller

Billet

La prochaine version 2.28 de Dotclear embarque un nouveau plugin nommé Uninstaller.

But

Le gestionnaire de modules, incorporé au core de Dotclear et servant à la gestion des thèmes et plugins, permet d'installer des modules avec une gestion des actions liées à l'installation à travers le fichier src/Install.php et sa classe idoine, mais lorsqu'il s'agit de désinstaller des plugins ou thèmes, la seule action effectuée est la suppression des fichiers du module. À aucun moment on ne tient compte de ce que le module a pu ajouter dans les paramètres, les tables, le cache, etc...

Ce manque est désormais comblé par le plugin Uninstaller qui va permettre d'affiner la désinstallation d'un module, en proposant des outils préétablis de suppressions. Il y a deux points de départ de ces désinstallations, soit depuis le gestionnaire de plugins|thèmes avec un bouton Désinstallation qui donnera le choix au super admin de supprimer telle ou telle partie du module, soit directement lors de l'action de suppression d'un module auquel cas des actions définies par le module lui-même seront effectuées directement sans demande de confirmation.

Plugin Uninstaller, août 2023
Interface utilisateur du plugin Uninstaller


Actions

Une tâche (Cleaner) permet d'effectuer une action ciblée, les groupes et tâches prédéfinis sont les suivants :
Caches :

  • caches.delete : Effacer le répertoire de caches créé par le module,
  • caches.empty : Vider le répertoire de caches créé par le module,

Logs :

  • logs.delete_all : Effacer les logs créés par le module,

Plugins :

  • plugins.delete : Effacer les fichiers du plugins,

Preferences :

  • preferences.delete_global : Effacer les préférences pour les utilisateurs créées par le module,
  • preferences.delete_local : Effacer les préférences globales créées par le module,
  • preferences.delete_all : Effacer les préférences globales et utilisateurs créées par le module,
  • preferences.delete_related : Effacer une préférence ciblée créé par le module,

Settings :

  • settings.delete_global : Effacer les préférences pour les blogs créées par le module,
  • settings.delete_local : Effacer les préférences globales créées par le module,
  • settings.delete_all : Effacer les préférences globales et blogs créées par le module,
  • settings.delete_related : Effacer une préférence ciblée créé par le module,

Tables :

  • tables.delete : Supprimer une table créée par le module,
  • tables.empty : Vider une table créée par le module,

Themes :

  • themes.delete : Effacer les fichiers du thème,

Vars :

  • vars.delete : Effacer ou vider le sous répertoire de DC_VAR créé par le module,

Versions :

  • versions.delete : Supprimer le numéro de version du module ne base
Intégration

Pour utiliser les fonctions de désinstallation prédéfinis, il suffit d'ajouter un fichier src\Uninstall.php contenant sa classe idoine Uninstall dans le module. Le plugin Uninstaller saura trouver et utiliser ce fichier sans déclaration supplémentaire.
La méthode addUserAction va ajouter une action avec demande de confirmation tandis que la méthode addDirectAction ajoutera une action directe lors de la suppression d'un module. Exemple complet de fichier :

<?php
declare(strict_types=1);

namespace Dotclear\Theme\monTheme;

use Dotclear\App;
use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller;

class Uninstall extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::UNINSTALL));
    }

    public static function process(): bool
    {
        // Par sécurtié, on vérifie l'existence du plugin Uninstaller, même si c'est lui qui a dû appeler ce script
        if (!self::status() || !App::plugins()->moduleExists('Uninstaller')) {
            return false;
        }

        // On récupère l'instance singleton de Uninstaller
        Uninstaller::instance()
            // Action utilisateur pour effacer les paramètres aillant l'espace de nom du module
            ->addUserAction(
                'settings',
                'delete_all',
                My::id()
            )
            // Action utilisateur pour effacer les fichiers du module
            ->addUserAction(
                'plugins',
                'delete',
                My::id()
            )
            // Action utilisateur pour effacer le numéro de version en base du module
            ->addUserAction(
                'versions',
                'delete',
                My::id()
            )
            // Action directe pour effacer les fichiers du module
            ->addDirectAction(
                'plugins',
                'delete',
                My::id()
            )
            // Action directe pour effacer le numéro de version en base du module
            ->addDirectAction(
                'versions',
                'delete',
                My::id()
            )
        ;

        // aucune action spécifique, on retourne donc false
        return false;
    }
}
Extensions

Il est possible d'aller plus loin en ajoutant des actions spécifiques qui n'existent pas dans la livraison du plugin Uninstaller.
Pour des actions avec confirmation utilisateur on va simplement compléter la classe précédente comme suit :

<?php
declare(strict_types=1);

namespace Dotclear\Theme\monTheme;

use Dotclear\App;
use Dotclear\Core\Process;
use Dotclear\Helper\Html\Form\Para;
use Dotclear\Helper\Html\Form\Checkbox;
use Dotclear\Helper\Html\Form\Label;
use Dotclear\Plugin\Uninstaller\Uninstaller;

class Uninstall extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::UNINSTALL));
    }

    public static function process(): bool
    {
        // Par sécurtié, on vérifie l'existence du plugin Uninstaller, même si c'est lui qui a dû appeler ce script
        if (!self::status() || !App::plugins()->moduleExists('Uninstaller')) {
            return false;
        }

        // ... ici les actions prédéfinies utilisateur et directes ne sont pas affichées cf exemple ci-dessus

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

            // Ici on exécute la tâche de supprimer la choucroute

        }

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

    public static function render(): void
    {
        if (!self::status()) {
            return;
        }

        // On affiche le formulaire spécial
        echo (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'),
            ])
            ->render(); 
    }
}

Il est possible d'aller encore plus loin pour créer des actions spécifiques plus poussées, il faut alors créer un Cleaner et le déclarer de la même manière que ceux du plugin Uninstaller. Voir les fichiers Prepend.php pour la déclaration d'un Cleaner et le répertoire /src/Task pour des exemples de tâches.

NOTE

Pour des raisons techniques les actions directes ne sont pas effectuées sur les modules installés en double, et ce même si le bouton Désinstaller est présent.

Les informations distillées ici sont non exhaustives et pourront être complétées à l'avenir, elles ont été écrites d'après la version 2.28 de Dotclear.

La discussion continue ailleurs

URL de rétrolien : https://dotclear.watch/trackback/406