Actions

Plugins

From LimeSurvey Manual

Revision as of 08:24, 2 August 2023 by Maren.fritz (talk | contribs) (Created page with "<syntaxhighlight lang="xml"> <updaters> <updater> <stable> 1</stable> <type> ausruhen</type> <source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</sourc...")

Übersicht

Ab LimeSurvey 2.05 unterstützt LimeSurvey offiziell Plugins. Einige Plugins werden vom LimeSurvey-Team unterstützt und in den Kern integriert. Einige werden von anderen außerhalb des LimeSurvey-Teams unterstützt. Um sie leichter zu finden, sehen Sie sich die Verfügbare Plugins von Drittanbietern an und fügen Sie Ihr eigenes Plugin hinzu!

Mit Plugins können Benutzer die Funktionalität ihrer Installation anpassen und gleichzeitig von regelmäßigen Software-Updates profitieren.

Diese Dokumentation richtet sich an Entwickler, die LimeSurvey für den eigenen Gebrauch oder für ihre Kunden erweitern; Endbenutzern wird diese Dokumentation nicht weiterhelfen.

Plugins müssen die Schnittstelle iPlugin implementieren. Wir empfehlen, Ihre Plugin-Klasse von der Klasse PluginBase zu erweitern.

Plugins werden rund um einen Event-Mechanismus entwickelt.

Plugin-Einstellungen

Durch die Erweiterung profitieren Sie von der allgemeinen Funktionalität, die von Plugins benötigt wird, die wir bereits für Sie implementiert haben. Eine dieser Funktionen ist die Implementierung der getPluginSettings-Funktion. Diese Funktion muss ein Array zurückgeben, das die Konfigurationsoptionen für den Benutzer beschreibt.

Das Beispiel-Plugin stellt nur eine konfigurierbare Einstellung bereit, nämlich die angezeigte Meldung.

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

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

Das Array enthält für jede Einstellung einen Namen als Schlüssel. Die Werte sind Arrays, die die erforderlichen Metadaten enthalten.

Unterstützte Typen sind:

  • logo
  • int (ganzzahlige Zahl)
  • string (alphanumerisch)
  • text
  • html
  • relevant
  • info
  • passwort
  • datum! N!* auswählen

Neben dem Typ stehen noch eine Reihe weiterer Schlüssel zur Verfügung:

  • label, definiert eine Beschriftung.
  • default, definiert einen Wert, der angezeigt wird, wenn kein Wert angegeben ist (nur für globale Einstellungen, nicht für Umfrageeinstellungen).
  • current, definiert den aktuellen Wert.
  • readOnly: Zeigt die Einstellungen als schreibgeschützt an
  • htmlOptions, die htmlOptions des Eingabeteils (siehe Yii-Handbuch [[1]])
  • PluginOptions, für Einige Einstellungen (HTML oder Select): Legen Sie die Widget-Option fest
  • labelOptions: htmlOptions des Labels
  • controlOptions: htmlOptions des Wrappers von Label und Eingabe

Ein Plugin-Beispiel mit allen tatsächlichen Einstellungen finden Sie unter exampleSettings

Plugin-Einstellungen lesen und schreiben

Es ist möglich, Plugin-Einstellungen direkt aus Ihrem Plugin-Code zu lesen und zu schreiben.

Beispiel:

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

Sie können einen Standardwert erhalten, wenn die Einstellung zufällig null ist:

$mySetting = $this->get('mySetting', null, null, 10); // 10 ist Standard

Ereignisse

Plugins abonnieren Ereignisse und können mit LimeSurvey interagieren, wenn das Ereignis ausgelöst wird. Eine Liste der derzeit verfügbaren Ereignisse finden Sie unter Plugin-Ereignisse.

API

Plugins sollten LimeSurvey nur über seine „öffentliche“ API erweitern. Dies bedeutet, dass die direkte Verwendung von im Quellcode gefundenen Klassen eine schlechte Praxis ist. Obwohl wir Sie nicht zwingen können, dies nicht zu tun, riskieren Sie bei jedem kleineren Update, das wir durchführen, ein defektes Plugin.

Interagieren Sie mit LimeSurvey so weit wie möglich nur über die beschriebenen Methoden hier. Gleiches wie bei Veranstaltungen.

Das API-Objekt ist über $this->api verfügbar, wenn es von PluginBase erweitert wird. Andernfalls können Sie es von der PluginManager-Instanz abrufen, die an den Konstruktor Ihres Plugins übergeben wird.

Auf Anfrage können dem API-Objekt neue Funktionen hinzugefügt werden.

Formularerweiterung (New in 6 )

Einführung

Das Formularerweiterungssystem ist eine allgemeinere Möglichkeit, Formulare im Kern von LimeSurvey zu erweitern, ohne für jedes Formular ein neues Ereignis hinzuzufügen.

Es besteht aus folgenden Komponenten:

  • Ein globales Modul namens 'FormExtensionService
  • Eine Bibliothek von 'Eingabeklassen, die Plugins zur obigen Modulinitialisierung hinzufügen können
  • Ein 'Widget, zusammen mit Benutzerdefinierte Renderer, die in den LimeSurvey-Ansichtsdateien verwendet werden

Jedes Formular wird durch eine „Positionszeichenfolge“ identifiziert, z<form name><dot><tab name> . Beispiel: globalsettings.general oder globalsettings.security .

Der Sinn eines klassenbasierten Systems ohne HTML besteht darin, die Plugin-Autoren von der Arbeit zu befreien, damit sie den HTML-Code aktualisieren können, wenn sich der Kern-HTML-Code ändert. Dennoch kann der Autor bei Bedarf den Typ RawHtmlInput verwenden.

Eine Sache, die Sie in diesem System nicht tun können, ist das Hinzufügen „neuer Formularregisterkarten“.

Beispiel

Um einem Formular über ein Plugin eine neue Eingabe hinzuzufügen, verwenden Sie den folgenden Code aus Ihrer init() Funktion:

TODO: In den Plugin-Einstellungen statt global speichern

// Am Anfang der Datei
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;

// Inside init()
Yii::app()->formExtensionService->add(
 'globalsettings.general',
 new TextInput([
 'name' => 'myinput', 
 'label' => 'Label',
 'disabled' => true,
 'tooltip' => 'Moo muh muh',
 'help' => 'Einige Hilfetexte', 
 'save' => function($request, $connection) {
 $value = $request->getPost('myinput');
 if ($value === 'irgendein ungültiger Wert') {
 throw new SaveFailedException("Die benutzerdefinierte Eingabe 'myinput' konnte nicht gespeichert werden");
 } else {
 SettingGlobal::setSetting('myinput', $value);
 }
 } ,
 'load' => function () {
 return getGlobalSetting('myinput');
 }
 ])
);

Validierung

Die Validierung der Eingabe erfolgt in der save (siehe Beispiel oben). Wenn der gepostete Wert ungültig ist, lösen Sie eine SaveFailedException aus und dem Benutzer wird eine Warnmeldung angezeigt.

Unterstützte Formulare

Folgende Formen können erweitert werden:

  • globalsettings.general (New in 6.0.0 )

Wenn Sie Unterstützung für ein anderes Kernformular hinzufügen möchten, müssen Sie die folgende Änderung in einem Pull-Request anwenden:

Fügen Sie in der Ansichtsdatei Folgendes hinzu:

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

Möglicherweise müssen Sie eine neue Renderer-Klasse basierend auf DefaultBaseRenderer erstellen, wenn sich der HTML-Code des Formulars von anderen Formularen unterscheidet. Möglicherweise müssen Sie auch die Standard-Renderer-Klasse um Eingabetypen erweitern, die noch nicht hinzugefügt wurden.

Die zweite Änderung, die Sie vornehmen müssen, ist das Hinzufügen eines Aufrufs der Formularerweiterungsdienstklasse in der Controller-Aktion, die das Formular speichert:

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

Das ist es!

Lokalisierung (New in 3 )

Es ist für Plugins möglich, ihre eigenen Gebietsschemadateien hinzuzufügen. Das verwendete Dateiformat ist .mo, dasselbe wie bei Kernübersetzungen. Die Dateien müssen in gespeichert werden

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

Wo "<language> „ist ein aus zwei Buchstaben bestehendes Wort wie „de“ oder „fr“.

Um die spezifische Gebietsschemadatei zu verwenden, verwenden Sie die Plugin-Funktion gT:

$this->gT("Ein Plugin-Text, der übersetzt werden muss");

Wenn die angegebene Zeichenfolge in der Plugin-spezifischen Gebietsschemadatei nicht gefunden werden kann, sucht die Funktion in den Kerngebietsschemadateien. Daher ist es sicher, Zeichenfolgen wie „Abbrechen“ zu verwenden:

$this->gT("Abbrechen"); // Wird übersetzt, auch wenn „Abbrechen“ nicht in der Plugin-Gebietsschemadatei enthalten ist

Wenn Sie Ansichten zusammen mit Ihrem Plugin verwenden, sollten Sie verwenden

$plugin->gT("Übersetze mich");

um aus Ihrer Sicht eine Plugin-spezifische Übersetzung durchzuführen.

Sie können die Datei limesurvey.pot als Beispiel dafür verwenden, wie eine Pot-Datei aussehen kann. Dies wird in Ihr Übersetzungstool importiert.

Werkzeuge

Ein Open-Source-Tool zum Bearbeiten von Po- und Mo-Dateien ist [2].

Protokollierung (New in 3 )

Wenn Sie etwas von Ihrem Plugin protokollieren möchten, schreiben Sie einfach

$this->log("Ihre Nachricht");

Die Standardprotokollierungsstufe ist „trace“, Sie können jedoch eine andere Protokollierungsstufe als optionales zweites Argument angeben:

$this->log("Etwas ist schiefgelaufen!", CLogger::LEVEL_ERROR);

Die Protokolldatei finden Sie im Ordner

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

Ihr Plugin-Name wird automatisch als Kategorie verwendet. Eine gute Möglichkeit, nur die Fehler Ihres Plugins anzuzeigen, ist die Verwendung von grep (unter Linux):

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

Weitere Informationen zum Konfigurieren der Protokollierung in Yii 1: Optional_settings#Logging_settings.

Erweiterungsaktualisierungen (New in 4 )

Seit LimeSurvey Version 4.0.0 gibt es ein System für den Umgang mit Plugin- und anderen Erweiterungsaktualisierungen. Um dieses System verwenden zu können, muss Ihre Erweiterungsdatei config.xml die Updater-Konfiguration enthalten.

<updaters> 
<updater> 
<stable> 1</stable> 
<type> ausruhen</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.