Plugins - avanceret
From LimeSurvey Manual
Oversigt
Fra LimeSurvey 2.05 vil LimeSurvey officielt understøtte plugins. Nogle plugins vil blive understøttet af LimeSurvey-teamet og vil gå ind i kernen. Nogle vil blive støttet af andre uden for LimeSurvey-teamet. For at hjælpe med at finde dem, tjek Tilgængelige tredjeparts plugins og tilføj dit eget plugin til det!
Plugins giver brugerne mulighed for at tilpasse funktionaliteten af deres installation, mens de stadig kan drage fordel af regelmæssige softwareopdateringer.
Denne dokumentation er beregnet til udviklere, der udvider LimeSurvey til eget brug eller til deres kunder; slutbrugere vil ikke blive hjulpet af denne dokumentation.
Plugins skal implementere grænsefladen iPlugin. Vi anbefaler at udvide din plugin-klasse fra PluginBase-klassen.
Plugins er udviklet omkring en event-mekanisme.
Plugin-indstillinger
Ved at udvide drager du fordel af den fælles funktionalitet, der kræves af plugins, som vi allerede har implementeret for dig. En af disse funktioner er implementeringen af funktionen getPluginSettings. Denne funktion skal returnere et array, der beskriver konfigurationsmulighederne for brugeren.
Eksemplet plugin afslører kun 1 konfigurerbar indstilling, meddelelsen det vil vise.
beskyttede $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
) ,
'message' => array(
'type' => 'streng',
'label' => 'Besked'
)
);
Arrayet indeholder et navn for hver indstilling som en nøgle. Værdierne er arrays, der indeholder de nødvendige metadata.
Understøttede typer er:
- logo
- int (heltal)
- streng (alfanumerisk)
- tekst
- html
- relevans
- info
- adgangskode
- dato
- vælg
Udover type er en række andre nøgler tilgængelige:
- label, definerer en etiket
- standard, definerer en værdi, der skal vise, hvis der ikke er angivet nogen værdi (kun for globale indstillinger, ikke for undersøgelsesindstillinger)
- aktuelle, definerer den aktuelle værdi.
- readOnly : vist indstillingerne som skrivebeskyttet
- htmlOptions, htmlOptions for inputdelen (se Yii manual [[1]])
- pluginOptions, for nogle indstillinger (html eller vælg) : indstil widget-indstillingen
- labelOptions : htmlOptions of the label
- controlOptions : htmlOptions of wrapper of label and input
Du kan finde et plugin-eksempel ved at bruge alle faktiske indstillinger på exampleSettings
Læs og skriv plugin-indstillinger
Det er muligt at læse og skrive plugin-indstillinger direkte fra din plugin-kode.
Eksempel:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Du kan få en standardværdi, hvis indstillingen tilfældigvis er null:
$mySetting = $this->get('mySetting', null, null, 10); // 10 er standard
Survey specific plugin settings
Two events are used to create survey specific plugin settings:
- newSurveySettings
- beforeSurveySettings
Example to disable a plugin for a specific survey:
public function init()
{
$this->subscribe('beforeSurveySettings');
$this->subscribe('newSurveySettings');
// Other events...
}
public function beforeSurveySettings()
{
$event = $this->event;
$surveyId = intval($event->get('survey'));
$event->set(
"surveysettings.{$this->id}",
[
'name' => get_class($this),
'settings' => [
'isActive' => [
'type' => 'boolean',
'label' => 'isActive',
'current' => $this->getIsActive($surveyId),
'help' => 'Activate plugin for this survey'
],
]
]
);
}
public function newSurveySettings()
{
$event = $this->event;
foreach ($event->get('settings') as $name => $value)
{
$this->set($name, $value, 'Survey', $event->get('survey'), false);
}
}
private function getIsActive(int $sid): bool
{
return (bool) $this->get('isActive', 'Survey', $sid, false);
}
Begivenheder
Plugins abonnerer på begivenheder og kan interagere med LimeSurvey, når begivenheden udløses. Se Plugin-begivenheder for en liste over tilgængelige begivenheder.
API
Plugins bør kun udvide LimeSurvey via dets "offentlige" API. Det betyder, at direkte brug af klasser fundet i kildekoden er en dårlig praksis. Selvom vi ikke kan tvinge dig til at lade være, risikerer du at have et ødelagt plugin med hver mindre opdatering, vi laver.
Så meget som muligt interagerer kun med LimeSurvey via metoder beskrevet her. Samme som for arrangementer.
API-objektet er tilgængeligt via $this->api
, når det udvides fra PluginBase, ellers kan du hente det fra PluginManager-instansen, der sendes til dine plugins' konstruktør.
Nye funktioner kan tilføjes til API-objektet efter anmodning.
<span id="Form_extension (New in 6 )">
Formularudvidelse (New in 6 )
Introduktion
Formudvidelsessystemet er en mere generel måde at udvide formularer i kerne LimeSurvey uden at tilføje en ny begivenhed for hver formular.
Den består af følgende komponenter:
- Et globalt modul kaldet FormExtensionService
- Et bibliotek af inputklasser, som plugins kan tilføje til ovenstående modulinitialisering
- En widget sammen med brugerdefinerede renderere, der bruges i LimeSurvey-visningsfilerne
Hver form er identificeret med en positionsstreng, f.eks<form name><dot><tab name> . Eksempel: globalsettings.general
eller globalsettings.security
.
Pointen bag et klassebaseret system uden HTML er at frigøre plugin-forfatterne af arbejdet til at opdatere HTML'en, når kerne-HTML'en ændres. Alligevel kan forfatteren bruge RawHtmlInput
typen, hvis det er nødvendigt.
En ting, du ikke kan gøre i dette system, er at tilføje nye formularfaner.
Eksempel
For at tilføje et nyt input til en formular fra et plugin skal du bruge følgende kode fra din init()
funktion:
TODO: Gem i plugin-indstillinger i stedet for globalt
// Øverst i filen
brug LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
brug LimeSurvey\Libraries\FormExtension\SaveFailedException;
// Inside init()
Yii::app()->formExtensionService->add(
'globalsettings.general',
new TextInput([
'name' => 'myinput',
'label' => 'Etiket',
'disabled' => sand,
'tooltip' => 'Moo moo moo',
'help' => 'Noget hjælpetekst',
'save' => funktion($request, $connection) {
$value = $request->getPost('myinput');
if ($value === 'en eller anden ugyldig værdi') {
throw new SaveFailedException("Kunne ikke gemme brugerdefineret input 'myinput'");
} ellers {
SettingGlobal::setSetting('myinput', $value);
}
} ,
'load' => funktion () {
return getGlobalSetting('myinput');
}
])
);
Validering
Validering af input udføres i save
funktionen (se eksemplet ovenfor). Hvis den bogførte værdi er ugyldig, smid en SaveFailedException
, og en advarselsmeddelelse vil blive vist til brugeren.
Understøttede formularer
Følgende formularer kan udvides:
- globalsettings.general (New in 6.0.0 )
Hvis du vil tilføje support til en anden kerneformular, skal du anvende følgende ændring i en pull-anmodning:
Tilføj i visningsfilen:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... mere HTML
<?= FormExtensionWidget::render(
App()-> formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
Du skal muligvis oprette en ny gengivelsesklasse baseret på DefaultBaseRenderer
, hvis formen HTML er anderledes end andre formularer. Du skal muligvis også udvide standardrendererklassen med inputtyper, der endnu ikke er tilføjet.
Den anden ændring, du skal gøre, er at tilføje et opkald til formularudvidelsesserviceklassen i controllerhandlingen, der gemmer formularen:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
Det er det!
<span id="Localization_ (New in 3 )">
Lokalisering (New in 3 )
Det er muligt for plugins at tilføje deres egne lokalitetsfiler. Det anvendte filformat er .mo, det samme som kerneoversættelser. Filerne skal gemmes i
<plugin root folder>/locale/<language> /<language> .mo
hvor "<language> " er et ord på to bogstaver som "de" eller "fr".
For at bruge den specifikke lokalitetsfil, brug plugin-funktionen gT:
$this->gT("En plugin-tekst, der skal oversættes");
Hvis den givne streng ikke kan findes i den plugin-specifikke lokalitetsfil, vil funktionen se i de centrale lokalitetsfiler. Så det er sikkert at bruge strenge som "Annuller":
$this->gT("Annuller"); // Vil blive oversat, selvom "Annuller" ikke er i plugin-lokalitetsfilen
Hvis du bruger visninger sammen med dit plugin, skal du bruge
$plugin->gT("Oversæt mig");
at lave plugin-specifik oversættelse i din visning.
Du kan bruge filen limesurvey.pot som et eksempel på, hvordan en pot-fil kan se ud. Dette importeres til dit oversættelsesværktøj.
Værktøj
Et open source-værktøj til at redigere po- og mo-filer er Poedit.
<span id="Logging_ (New in 3 )">
Logger (New in 3 )
Hvis du vil logge noget fra dit plugin, skal du bare skrive
$this->log("Din besked");
Standardlogningsniveauet er sporing, men du kan give et andet logniveau som et valgfrit andet argument:
$this->log("Noget gik galt!", CLogger::LEVEL_ERROR);
Logfilen kan findes i mappen
<limesurvey root folder>/tmp/runtime/plugin.log
Dit plugin-navn bruges automatisk som kategori. En god måde kun at se fejlene fra dit plugin er at bruge grep (på Linux):
$ tail -f tmp/runtime/plugin.log | grep<your plugin name>
Mere info om konfiguration af logning i Yii 1: Optional_settings#Logging_settings.
<span id="Extension_updates_ (New in 4 )">
Udvidelsesopdateringer (New in 4 )
Siden LimeSurvey version 4.0.0, er der et system på plads til at håndtere plugin og andre udvidelsesopdateringer. For at bruge dette system skal din filtypenavn config.xml inkludere opdateringskonfiguration.
<updaters>
<updater>
<stable> 1</stable>
<type> hvile</type>
<source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source>
<manualUpdateUrl> https://somedownloadlink.com/maybegithub</manualUpdateUrl>
</updater>
</updaters>
(Kildetagget ovenfor peger på LimeStore REST API, som vil blive brugt til alle tilgængelige udvidelser i vores LimeStore.)
Tag | Beskrivelse |
---|---|
stabil | "1", hvis denne kilde kun giver dig stabile versionsnumre; "0", hvis kilden også vil give ustabile versioner, såsom 0.3.3-beta .
|
type | Indtil videre understøttes kun type rest . Det er nemt at tilføje nye opdateringstyper (version checkers), som git, wget osv.
|
kilde | URL'en til at hente nye versioner fra. |
manualUpdateUrl | URL, som brugeren kan gå til for at opdatere den seneste version af udvidelsen. |
automaticUpdateUrl | TODO |
Hvis du ikke ønsker at levere et opdateringsprogram, skal du indsætte følgende tekst i din config XML-fil:
<updaters disabled="disabled">
</updaters>
På denne måde fortæller du systemet, at du målrettet har deaktiveret opdateringssystemet og ikke bare har glemt at tilføje det.
Det nye plugin UpdateCheck - installeret og aktiveret som standard - søger efter nye opdateringer til alle installerede udvidelser, når en superadministrator logger på, asynkront, maks. én gang hver 24. time. Hvis der findes nye versioner, sendes en meddelelse.
Hvis der findes en ny sikkerhedsopdatering, åbnes meddelelsen automatisk og stiles i "fare"-klassen.
Du kan manuelt søge efter opdateringer ved at gå til plugin-managervisningen og klikke på "Kontroller opdateringer". Bemærk, at denne knap kun er synlig, hvis UpdateCheck-pluginnet er aktiveret.
Under hætten
Dette afsnit giver et kort overblik over implementeringen af udvidelsesopdateringen.
Udvidelsesopdateringen er en del af ExtensionInstaller-biblioteket. Nedenfor er et UML-diagram for klasserne relateret til opdateringsprocessen.
|UML-diagram for udvidelsesopdatering
Programflow, når Yii starter:
Yii init VersionFetcherServiceLocator->init() Tilføj REST version fetcher ExtensionUpdaterServiceLocator->init() Tilføj PluginUpdater TODO: Tilføj en opdatering til hver udvidelsestype (tema, spørgsmålskabelon, ...)
Programflow, når du kører UpdaterCheck-pluginnet:
Hent alle opdateringer fra ExtensionUpdaterServiceLocator Loop hver opdatering For hver opdatering skal du gå gennem versionshentere konfigureret af<updater> XML For hver versionshenter skal du kontakte fjernkilden og få versionsoplysninger Komponer alle versioner til en notifikation
Metoden checkAll i UpdateCheck-pluginnet giver et eksempel på, hvordan man forespørger alle udvidelser for nye versioner .
Tilføjelse af nye versionshentere
For at tilføje en ny brugerdefineret versionshenter skal du køre dette under Yii-initialisering:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
funktion (\SimpleXMLElement $updaterXml) {
returner ny MyNewVersionFetcher( $updaterXml);
}
);
Selvfølgelig skal klassen MyNewVersionFetcher
underklasse VersionFetcher
.
For at bruge din nye versionshenter skal du konfigurere type
i opdateringsprogrammet XML til at bruge
myNewVersionFetcherType
(i stedet for f.eks.rest
).
Tilføjelse af nye udvidelsesopdateringer
For at tilføje en ny brugerdefineret udvidelsesopdatering skal du køre denne under Yii-initialisering:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
funktion () {
return MyNewExtensionUpdater::createUpdaters() ;
}
);
Class MyNewExtensionUpdater
skal underklasse ExtensionUpdater
.
Den øverste type
tag i config.xml ('plugin', 'theme', ...) vil kontrollere, hvilken udvidelsesopdatering der bruges til denne udvidelse. Systemet er endnu ikke helt tilpasseligt, da du også skal tilføje en tilpasset ExtensionInstaller, menupunkter osv. Men i teorien, og måske i fremtiden, skulle det være muligt at tilføje en ny type udvidelse på denne måde.
Udvidelsesinstallationsprogram
Udvidelsesinstallationsbiblioteket består af to abstrakte klasser:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller er underklassificeret for hver udvidelsestype, såsom PluginInstaller, QuestionThemeInstaller osv.
FileFetcher er underklassificeret for hver anden måde at hente filer på. I øjeblikket understøttes kun uploadede zip-filer, men i fremtiden kan der også være en Github- eller LimeStore-henter.
Særlige plugins
Tilgængelige plugins
Selvstudium
Denne trinvise selvstudie viser, hvordan man opretter et plugin, der sender en postanmodning ved hvert spørgeskemasvar indsendelse. Selvstudiet viser dig, hvordan du opretter og gemmer globale og per-survey-indstillinger, hvordan du registrerer begivenheder og mere.