Plugins - advanced/hu: Difference between revisions
From LimeSurvey Manual
Maren.fritz (talk | contribs) Created page with "=== Példa ===" |
Maren.fritz (talk | contribs) Created page with "Ha egy beépülő modulból új bemenetet szeretne hozzáadni egy űrlaphoz, használja az alábbi kódot <code>init()</code> függvényből:" |
||
Line 110: | Line 110: | ||
=== Példa === | === Példa === | ||
Ha egy beépülő modulból új bemenetet szeretne hozzáadni egy űrlaphoz, használja az alábbi kódot <code>init()</code> függvényből: | |||
TODO: Save in plugin settings instead of global | TODO: Save in plugin settings instead of global |
Revision as of 08:12, 11 October 2023
Áttekintés
A LimeSurvey 2.05-től kezdve a LimeSurvey hivatalosan is támogatja a bővítményeket. Egyes beépülő modulokat a LimeSurvey csapata támogatni fog, és bekerülnek a magba. Néhányat mások is támogatnak a LimeSurvey csapatán kívül. A keresés megkönnyítése érdekében nézze meg az Elérhető harmadik féltől származó beépülő modulokat, és adja hozzá saját bővítményét!
A beépülő modulok lehetővé teszik a felhasználók számára, hogy testreszabják telepítésük funkcionalitását, miközben továbbra is élvezhetik a rendszeres szoftverfrissítések előnyeit.
Ez a dokumentáció azoknak a fejlesztőknek szól, akik saját vagy ügyfeleik számára bővítik a LimeSurveyt; ez a dokumentáció nem segít a végfelhasználóknak.
A beépülő moduloknak megvalósítaniuk kell a iPlugin felületet. Javasoljuk, hogy bővítse ki beépülő modulját a PluginBase osztályból.
A beépülő modulok egy event mechanizmus köré épülnek.
Beépülő modul beállításai
A bővítés révén élvezheti az általunk már megvalósított bővítmények által megkövetelt közös funkciók előnyeit. Az egyik ilyen funkció a getPluginSettings függvény megvalósítása. Ennek a függvénynek egy tömböt kell visszaadnia, amely leírja a felhasználó konfigurációs beállításait.
A példabővítmény csak 1 konfigurálható beállítást tesz közzé, az üzenetet, amely megjelenik.
protected $settings = array(
'logo' => array(
'type' => 'logo',
'útvonal' => 'assets/logo.png'
) ,
'message' => array(
'type' => 'string',
'label' => 'Üzenet'
)
);
A tömb minden beállításhoz kulcsként egy nevet tartalmaz. Az értékek a szükséges metaadatokat tartalmazó tömbök.
A támogatott típusok a következők:
- logó
- int (egész szám)
- string (alfanumerikus)
- szöveg
- html
- relevancia
- info
- jelszó
- dátum
- válasszon
A típuson kívül számos más billentyű is elérhető:
- label, meghatároz egy címkét
- alapértelmezett, meghatároz egy értéket, amely megmutatja, ha nincs megadva érték (csak a globális beállításoknál, nem a felmérési beállításoknál)
- aktuális, az aktuális értéket határozza meg.
- readOnly : a beállítások csak olvashatóként jelennek meg
- htmlOptions, a beviteli rész htmlOpciói (lásd Yii kézikönyv [[1]])
- pluginOptions, for néhány beállítás (html vagy válasszon) : állítsa be a widget opciót
- labelOptions : htmlA címke beállításai
- controlOptions : htmlA címke és a bemenet burkolójának beállításai
Az összes tényleges beállítást használó beépülő modul példáját itt találja: exampleSettings
Beépülő modul beállításainak olvasása és írása
A beépülő modul beállításai közvetlenül a beépülő modul kódjából olvashatók és írhatók.
Példa:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Alapértelmezett értéket kaphat, ha a beállítás nulla:
$mySetting = $this->get('mySetting', null, null, 10); // A 10 az alapértelmezett
Események
A beépülő modulok előfizetnek az eseményekre, és interakcióba léphetnek a LimeSurvey szolgáltatással, amikor az esemény elindul. Az aktuálisan elérhető események listáját tekintse meg a Plugin events oldalon.
API
A beépülő modulok csak a „nyilvános” API-n keresztül bővíthetik ki a LimeSurvey-t. Ez azt jelenti, hogy a forráskódban található osztályok közvetlen használata rossz gyakorlat. Bár nem kényszeríthetjük rá, hogy ne tegye meg, minden kisebb frissítésnél fennáll annak a kockázata, hogy elromlik a plugin.
Amennyire csak lehetséges, csak a itt leírt módszerekkel lépjen kapcsolatba a LimeSurvey-vel. Ugyanaz, mint a rendezvényeknél.
Az API-objektum $this->api
keresztül érhető el, ha a PluginBase-ből bővíti, ellenkező esetben a beépülő modulok konstruktorának átadott PluginManager-példányból szerezheti be.
Kérésre új funkciókat lehet hozzáadni az API objektumhoz.
Űrlapkiterjesztés (New in 6 )
Bevezetés
Az űrlapkiterjesztési rendszer egy általánosabb módja az űrlapok kiterjesztésének a központi LimeSurveyben anélkül, hogy minden űrlaphoz új eseményt adna hozzá.
A következő összetevőkből áll:
- Egy globális modul FormExtensionService
- bemeneti osztályok könyvtára, amelyet a pluginek hozzáadhatnak a fenti modul inicializálásához
- Egy widget, valamint egyéni megjelenítők, amelyeket a LimeSurvey nézetfájlokban használnak
Minden űrlapot egy ''pozíciós karakterlánc azonosít, pl<form name><dot><tab name> . Példa: globalsettings.general
vagy globalsettings.security
.
A HTML nélküli osztályalapú rendszer mögött az a lényeg, hogy fel kell szabadítani a munka beépülő moduljait a HTML frissítésére, amikor az alapvető HTML megváltozik. Ennek ellenére a szerző használhatja a RawHtmlInput
típust, ha szükséges.
Egy dolog, amit ebben a rendszerben nem tehet meg, az "új űrlaplapok" hozzáadása.
Példa
Ha egy beépülő modulból új bemenetet szeretne hozzáadni egy űrlaphoz, használja az alábbi kódot init()
függvényből:
TODO: Save in plugin settings instead of global
// At top of file
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 moo moo',
'help' => 'Some help text',
'save' => function($request, $connection) {
$value = $request->getPost('myinput');
if ($value === 'some invalid value') {
throw new SaveFailedException("Could not save custom input 'myinput'");
} else {
SettingGlobal::setSetting('myinput', $value);
}
},
'load' => function () {
return getGlobalSetting('myinput');
}
])
);
Validation
Validation of the input is done in the save
function (see example above). If the posted value is invalid, throw a SaveFailedException
, and a warning flash message will be shown to the user.
Supported forms
The following forms can be extended:
- globalsettings.general (New in 6.0.0 )
If you want to add support for another core form, you need to apply the following change in a pull-request:
In the view file, add:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... more HTML
<?= FormExtensionWidget::render(
App()->formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
You might have to create a new renderer class based on DefaultBaseRenderer
, if the form HTML is different than other forms. You might also need to extend the default renderer class with input types not yet added.
The second change you have to do is add a call to the form extension service class in the controller action that saves the form:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
That's it!
Localization (New in 3 )
It's possible for plugins to add their own locale files. File format used is .mo, same as core translations. The files must be stored in
<plugin root folder>/locale/<language>/<language>.mo
where "<language>" is a two letter word like "de" or "fr".
To use the specific locale file, use the plugin function gT:
$this->gT("A plugin text that needs to be translated");
If the given string can't be found in the plugin specific locale file, the function will look in the core locale files. So it's safe to use strings like "Cancel":
$this->gT("Cancel"); // Will be translated even if "Cancel" is not in the plugin locale file
If you are using views together with your plugin, you should use
$plugin->gT("Translate me");
to do plugin specific translation in your view.
You can use the limesurvey.pot file as an example of how a pot file can look like. This is imported into your translation tool.
Tools
One open-source tool to edit po- and mo-files is Poedit.
Logging (New in 3 )
If you want to log something from your plugin, just write
$this->log("Your message");
The default logging level is trace, but you can give another log level as an optional second argument:
$this->log("Something went wrong!", 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.)
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.
If a new security update is found, the notification will open automatically and be styled in "danger" class.
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.
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.
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.