Actions

Plugins - advanced/fr: Difference between revisions

From LimeSurvey Manual

(Created page with "Le niveau de journalisation par défaut est trace, mais vous pouvez donner un autre niveau de journalisation comme deuxième argument facultatif :")
(Created page with "<syntaxhighlight lang="php"> $this->log("Quelque chose s'est mal passé !", CLogger::LEVEL_ERROR); </syntaxhighlight>")
Line 225: Line 225:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$this->log("Something went wrong!", CLogger::LEVEL_ERROR);
$this->log("Quelque chose s'est mal passé !", CLogger::LEVEL_ERROR);
</syntaxhighlight>
</syntaxhighlight>



Revision as of 06:51, 4 October 2023

Vue d'ensemble

À partir de LimeSurvey 2.05, LimeSurvey prendra officiellement en charge les plugins. Certains plugins seront supportés par l'équipe LimeSurvey et entreront dans le noyau. Certains seront soutenus par d'autres en dehors de l'équipe LimeSurvey. Pour vous aider à les trouver, consultez les Plugins tiers disponibles et ajoutez-y votre propre plugin !

Les plugins permettent aux utilisateurs de personnaliser les fonctionnalités de leur installation tout en bénéficiant de mises à jour logicielles régulières.

Cette documentation est destinée aux développeurs qui étendent LimeSurvey pour leur propre usage ou pour leurs clients ; les utilisateurs finaux ne seront pas aidés par cette documentation.

Les plugins doivent implémenter l'interface iPlugin. Nous vous recommandons d'étendre votre classe de plugin à partir de la classe PluginBase.

Les plugins sont développés autour d'un mécanisme event.

Paramètres du plugin

En étendant, vous bénéficiez des fonctionnalités communes requises par les plugins que nous avons déjà implémentés pour vous. L'une de ces fonctions est l'implémentation de la fonction getPluginSettings. Cette fonction doit renvoyer un tableau décrivant les options de configuration pour l'utilisateur.

L'exemple de plugin expose un seul paramètre configurable, le message qu'il affichera.

protected $settings = array(
 'logo' => array(
 'type' => 'logo',
 'path' => 'assets/logo.png'
 ) ,

'message' => array(
 'type' => 'string',
 'label' => 'Message'
 )
);

Le tableau contient un nom pour chaque paramètre sous forme de clé. Les valeurs sont des tableaux contenant les métadonnées requises.

Les types pris en charge sont :

  • logo
  • int (nombre entier)
  • chaîne (alphanumérique)
  • texte
  • html
  • pertinence
  • info
  • mot de passe
  • date!
  • sélectionner

Outre le type, un certain nombre d'autres clés sont disponibles :

  • label, définit une étiquette
  • par défaut, définit une valeur à afficher si aucune valeur n'est spécifiée (uniquement pour les paramètres globaux, pas pour les paramètres d'enquête)
  • current, définit la valeur actuelle.
  • readOnly : affiché les paramètres en lecture seule
  • htmlOptions, les htmlOptions de la partie d'entrée (voir le manuel Yii [[1]])
  • pluginOptions, pour quelques paramètres (html ou select) : définissez l'option du widget
  • labelOptions : htmlOptions du label
  • controlOptions : htmlOptions du wrapper de label et input

Vous pouvez trouver un exemple de plugin utilisant tous les paramètres réels sur exampleSettings

Lire et écrire les paramètres du plugin

Il est possible de lire et d'écrire les paramètres du plugin directement à partir du code de votre plugin.

Exemple:

$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);

Vous pouvez obtenir une valeur par défaut si le paramètre est nul :

$mySetting = $this->get('mySetting', null, null, 10); // 10 est la valeur par défaut

Événements

Les plugins s'abonnent aux événements et peuvent interagir avec LimeSurvey lorsque l'événement est déclenché. Pour une liste des événements actuellement disponibles, consultez Événements du plugin.

API

Les plugins ne doivent étendre LimeSurvey que via son API "publique". Cela signifie qu’utiliser directement les classes trouvées dans le code source est une mauvaise pratique. Bien que nous ne puissions pas vous y obliger, vous risquez d'avoir un plugin défectueux à chaque mise à jour mineure que nous effectuons.

Dans la mesure du possible, interagissez avec LimeSurvey uniquement via les méthodes décrites ici. Idem pour les événements.

L'objet API est disponible via $this->api lors de l'extension depuis PluginBase, sinon vous pouvez l'obtenir à partir de l'instance PluginManager qui est transmise au constructeur de vos plugins.

De nouvelles fonctions peuvent être ajoutées à l'objet API sur demande.

Extension de formulaire (New in 6 )

Présentation

Le système d'extension de formulaire est un moyen plus général d'étendre les formulaires dans le noyau de LimeSurvey sans ajouter de nouvel événement pour chaque formulaire.

Il se compose des éléments suivants :

  • Un module global appelé FormExtensionService
  • Une bibliothèque de classes d'entrée que les plugins peuvent ajouter à l'initialisation du module ci-dessus
  • Un widget, ainsi que moteurs de rendu personnalisés, utilisés dans les fichiers de vue LimeSurvey

Chaque formulaire est identifié par une chaîne de position, comme<form name><dot><tab name> . Exemple : globalsettings.general ou globalsettings.security .

L'objectif d'un système basé sur des classes sans HTML est de libérer les auteurs de plugins de l'œuvre pour qu'ils mettent à jour le code HTML lorsque le code HTML principal change. Néanmoins, l'auteur peut utiliser le type RawHtmlInput si nécessaire.

Une chose que vous ne pouvez pas faire dans ce système est d'ajouter de « nouveaux onglets de formulaire ».

Exemple

Pour ajouter une nouvelle entrée à un formulaire à partir d'un plugin, utilisez le code suivant de votre fonction init() :

TODO : Enregistrer dans les paramètres du plugin au lieu de global

// En haut du fichier
utilisez LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
utilisez LimeSurvey\Libraries\FormExtension\SaveFailedException;

// À l'intérieur de init()
Yii::app()->formExtensionService->add(
 'globalsettings.general',
 new TextInput([
 'name' => 'myinput', 
 'label' => 'Label',
 'disabled' => true,
 'tooltip' => 'Moo moo moo',
 'help' => 'Un texte d'aide', 
 'save' => function($request, $connection) {
 $value = $request->getPost('myinput');
 if ($value === 'une valeur invalide') {
 throw new SaveFailedException("Impossible d'enregistrer l'entrée personnalisée 'myinput'");
 } else {
 SettingGlobal::setSetting('myinput', $value);
 }
 } ,
 'load' => function () {
 return getGlobalSetting('myinput');
 }
 ])
);

Validation

La validation de la saisie se fait dans la fonction save (voir exemple ci-dessus). Si la valeur publiée n'est pas valide, lancez une SaveFailedException et un message flash d'avertissement sera affiché à l'utilisateur.

Formulaires pris en charge

Les formulaires suivants peuvent être étendus :

  • globalsettings.general (New in 6.0.0 )

Si vous souhaitez ajouter la prise en charge d'un autre formulaire principal, vous devez appliquer la modification suivante dans une pull-request :

Dans le fichier de vue, ajoutez :

 <?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?> 
... plus HTML
<?= FormExtensionWidget::render(
    App()-> formExtensionService->getAll('globalsettings.security'),
 nouveau DefaultBaseRenderer()
); ?>

Vous devrez peut-être créer une nouvelle classe de rendu basée sur DefaultBaseRenderer , si le formulaire HTML est différent des autres formulaires. Vous devrez peut-être également étendre la classe de rendu par défaut avec des types d'entrée non encore ajoutés.

La deuxième modification que vous devez effectuer est d'ajouter un appel à la classe de service d'extension de formulaire dans l'action du contrôleur qui enregistre le formulaire :

$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);

C'est ça!

Localisation (New in 3 )

Il est possible pour les plugins d'ajouter leurs propres fichiers de paramètres régionaux. Le format de fichier utilisé est .mo, identique aux traductions principales. Les fichiers doivent être stockés dans

<plugin root folder>/lieu/<language> /<language> .mo

où "<language> " est un mot de deux lettres comme "de" ou "fr".

Pour utiliser le fichier de paramètres régionaux spécifique, utilisez la fonction plugin gT :

$this->gT("Un texte de plugin à traduire");

Si la chaîne donnée ne peut pas être trouvée dans le fichier de paramètres régionaux spécifique au plugin, la fonction recherchera dans les fichiers de paramètres régionaux principaux. Il est donc prudent d'utiliser des chaînes telles que « Annuler » :

$this->gT("Annuler"); // Sera traduit même si "Annuler" n'est pas dans le fichier de paramètres régionaux du plugin

Si vous utilisez des vues avec votre plugin, vous devez utiliser

$plugin->gT("Traduisez-moi");

pour faire une traduction spécifique au plugin à votre avis.

Vous pouvez utiliser le fichier limesurvey.pot comme exemple de ce à quoi peut ressembler un fichier pot. Celui-ci est importé dans votre outil de traduction.

Outils

Un outil open source pour éditer les fichiers po et mo est Poedit.

Journalisation (New in 3 )

Si vous souhaitez enregistrer quelque chose depuis votre plugin, écrivez simplement

$this->log("Votre message");

Le niveau de journalisation par défaut est trace, mais vous pouvez donner un autre niveau de journalisation comme deuxième argument facultatif :

$this->log("Quelque chose s'est mal passé !", CLogger::LEVEL_ERROR);

The log file can be found in folder

<limesurvey root folder>/tmp/runtime/plugin.log

Your plugin name is automatically used as category. A nice way to see only the errors from your plugin is using grep (on Linux):

 $ tail -f tmp/runtime/plugin.log | grep <your plugin name>

More info about configuring logging in Yii 1: Optional_settings#Logging_settings.

Extension updates (New in 4 )

Since LimeSurvey version 4.0.0, there's a system in place to deal with plugin and other extension updates. To use this system, your extension config.xml file needs to include updater configuration.

<updaters>
    <updater>
        <stable>1</stable>
        <type>rest</type>
        <source>https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source>
        <manualUpdateUrl>https://somedownloadlink.com/maybegithub</manualUpdateUrl>
    </updater>
</updaters>

(The source tag above points to the LimeStore REST API, which will be used for all extensions available in our LimeStore.)

Updater tag descriptions
Tag Description
stable "1" if this source only gives you stable version numbers; "0" if the source will also provide unstable versions, like 0.3.3-beta.
type For now, only type rest is supported. It's easy to add new updater types (version checkers), like git, wget, etc.
source The URL to fetch new versions from.
manualUpdateUrl URL which the user can go to to update the latest version of the extension.
automaticUpdateUrl TODO

If you don't want to supply an updater, you should put the following text in your config XML file:

<updaters disabled="disabled">
</updaters>

This way, you tell the system that you purposefully disabled the update system, and didn't just forget to add it.

The new plugin UpdateCheck - installed and activated by default - checks for new updates for all installed extensions when a super admin logs in, asynchronously, max one time every 24 hours. If any new versions are found, a notification is pushed.

Available updates

If a new security update is found, the notification will open automatically and be styled in "danger" class.

Available security updates

You can manually check for updates by going to the plugin manager view and click on "Check updates". Note that this button is only visible if the UpdateCheck plugin is activated.

Manually check for updates

Under the hood

This section provides a brief overview over the extension updater implementation.

The extension updater is part of the ExtensionInstaller library. Below is a UML diagram for the classes related to the updater process.

Extension updater UML diagram

Program flow when Yii starts:

 Yii init
   VersionFetcherServiceLocator->init()
     Add REST version fetcher
   ExtensionUpdaterServiceLocator->init()
     Add PluginUpdater
     TODO: Add an updater for each extension type (theme, question template, ...)

Program flow when running the UpdaterCheck plugin:

 Get all updaters from ExtensionUpdaterServiceLocator
 Loop each updater
   For each updater, loop through version fetchers configured by <updater> XML
     For each version fetcher, contact remote source and get version information
 Compose all versions into a notification

The checkAll method in the UpdateCheck plugin provides an example of how to query all extensions for new versions.

Adding new version fetchers

To add a new custom version fetcher, run this during Yii initialization:

$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
  'myNewVersionFetcherType',
  function (\SimpleXMLElement $updaterXml) {
    return new MyNewVersionFetcher($updaterXml);
  }
);

Of course, the class MyNewVersionFetcher has to subclass VersionFetcher.

To use your new version fetcher, configure the type tag in the updater XML to use myNewVersionFetcherType (instead of e.g. rest).

Adding new extension updaters

To add a new custom extension updater, run this during Yii initialization:

$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
  'myNewExtensionUpdater',
  function () {
    return MyNewExtensionUpdater::createUpdaters();
  }
);

Class MyNewExtensionUpdater has to subclass ExtensionUpdater.

The top type tag in config.xml ('plugin', 'theme', ...) will control which extension updater are used for this extension. The system is not fully customizable yet, since you also need to add a custom ExtensionInstaller, menu items, etc. But in theory, and maybe in the future, it should be possible to add a new type of extension this way.

Extension installer

The extension installer library consists of two abstract classes:

  • ExtensionInstaller
  • FileFetcher

The ExtensionInstaller is subclassed for each extension type, like PluginInstaller, QuestionThemeInstaller, etc.

The FileFetcher is subclassed for each different way to fetch files. Currently, only uploaded zip files are supported, but in the future, there could be a Github or LimeStore fetcher too.

Special plugins

Available plugins

Tutorial

This step-by-step tutorial shows how to create a plugin that sends a post request on every survey response submission. The tutorial shows you how to create and save global and per-survey settings, how to register events and more.