Dodaci
From LimeSurvey Manual
Pregled
LimeSurvey ima mogućnost dodavanja funkcionalnosti putem dodataka. LimeSurvey se već isporučuje s velikim brojem osnovnih dodataka. Pogledajte i naš popis dodataka trećih strana i možda u budućnosti dodajte vlastiti dodatak na njega!
Dodaci omogućuju korisnicima prilagodbu funkcionalnosti njihove instalacije, uz zadržavanje mogućnosti redovitih ažuriranja softvera.
Ova je dokumentacija namijenjena programerima koji proširuju LimeSurvey za vlastite potrebe ili za potrebe svojih klijenata; krajnjim korisnicima ova dokumentacija neće biti od pomoći.
Dodaci moraju implementirati sučelje iPlugin. Preporučujemo da klasu svog dodatka izvedete iz klase PluginBase.
Dodaci se razvijaju oko mehanizma događaja.
Postavke dodatka
Proširivanjem koristite zajedničku funkcionalnost koju dodaci zahtijevaju, a koju smo već implementirali za vas. Jedna od tih funkcija je implementacija funkcije getPluginSettings. Ta funkcija mora vratiti niz koji opisuje opcije konfiguracije za korisnika.
Primjer dodatka izlaže samo jednu postavku koju je moguće konfigurirati, a to je poruka koju će prikazati.
protected $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
),
'message' => array(
'type' => 'string',
'label' => 'Message'
)
);
Niz sadrži naziv svake postavke kao ključ. Vrijednosti su nizovi koji sadrže potrebne metapodatke.
Podržani tipovi su:
- logo
- int (cijeli broj)
- string (alfanumerički)
- text
- html
- relevance
- info
- password
- date
- select
Osim tipa (type), dostupan je i niz drugih ključeva:
- label, definira oznaku
- default, definira vrijednost koja se prikazuje ako nije navedena nijedna vrijednost (samo za globalne postavke, ne za postavke upitnika)
- current, definira trenutnu vrijednost.
- readOnly : prikazuje postavke samo za čitanje
- htmlOptions, htmlOptions dijela za unos ( pogledajte Yii priručnik [[1]])
- pluginOptions, za neke postavke (html ili select) : postavlja opciju widgeta
- labelOptions : htmlOptions oznake
- controlOptions : htmlOptions omotača oznake i unosa
- localized : ako je true, vrijednost se pohranjuje po jeziku. Unos se šalje kao
name[language], acurrentmora biti niz indeksiran kôdom jezika. - language : koristi se zajedno s localized. Ili jedan kôd jezika, ili (New in X.Y.Z ) niz kôdova jezika za prikaz jednog unosa po jeziku (pogledajte Lokalizirane postavke dodatka)
Primjer dodatka koji koristi sve trenutne postavke možete pronaći na exampleSettings
Čitanje i pisanje postavki dodatka
Postavke dodatka moguće je čitati i zapisivati izravno iz koda vašeg dodatka.
Primjer:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Zadanu vrijednost možete dobiti ako postavka slučajno ima vrijednost null:
$mySetting = $this->get('mySetting', null, null, 10); // 10 is default
Postavke dodatka specifične za upitnik
Za izradu postavki dodatka specifičnih za upitnik koriste se dva događaja:
- newSurveySettings
- beforeSurveySettings
Primjer onemogućivanja dodatka za određeni upitnik:
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);
}
<span id="Localized_plugin_settings_ (New in 7.4 )">
Lokalizirane postavke dodatka (New in 7.4 )
Da biste za istu postavku prikazali jedan unos po jeziku upitnika, postavite localized na true i u language proslijedite popis jezika. Naziv jezika dodaje se oznaci svakog unosa.
public function beforeSurveySettings()
{
$event = $this->event;
$surveyId = intval($event->get('survey'));
$survey = Survey::model()->findByPk($surveyId);
$event->set(
"surveysettings.{$this->id}",
[
'name' => get_class($this),
'settings' => [
'errorText' => [
'type' => 'text',
'label' => $this->gT('Error text'),
'localized' => true,
'language' => $survey->getAllLanguages(),
// Niz indeksiran kôdom jezika, npr. ['en' => '...', 'de' => '...']
'current' => $this->get('errorText', 'Survey', $surveyId, []),
],
]
]
);
}
Poslana vrijednost je niz indeksiran kôdom jezika, pa ga funkcija newSurveySettings iz prethodnog primjera sprema bez ikakvih izmjena. Za čitanje teksta za trenutni jezik:
$errorTexts = $this->get('errorText', 'Survey', $surveyId, []);
$errorText = $errorTexts[App()->getLanguage()] ?? '';
Događaji
Dodaci se pretplaćuju na događaje i mogu stupiti u interakciju s LimeSurveyjem kada se događaj aktivira. Popis trenutno dostupnih događaja potražite na stranici Događaji dodataka.
API
Dodaci bi LimeSurvey trebali proširivati isključivo putem njegovog „javnog” API-ja. To znači da je izravno korištenje klasa iz izvornog koda loša praksa. Iako vas ne možemo spriječiti u tome, riskirate da vam dodatak prestane raditi sa svakim manjim ažuriranjem.
Koliko god je moguće, s LimeSurveyjem komunicirajte samo putem metoda opisanih ovdje. Isto vrijedi i za događaje.
API objekt dostupan je putem $this->api kada proširujete PluginBase, a u suprotnom ga možete dobiti iz instance PluginManagera koja se proslijeđuje konstruktoru vašeg dodatka.
Nove funkcije mogu se dodati API objektu na zahtjev.
<span id="Form_extension (New in 6 )">
Proširenje obrazaca (New in 6 )
Uvod
Sustav proširenja obrazaca općenitiji je način proširivanja obrazaca u jezgri LimeSurveya bez dodavanja novog događaja za svaki obrazac.
Sastoji se od sljedećih komponenti:
- Globalni modul pod nazivom FormExtensionService
- Biblioteka klasa unosa koje dodaci mogu dodati inicijalizaciji gornjeg modula
- Widget zajedno s prilagođenim rendererima, koji se koristi u datotekama prikaza LimeSurveya
Svaki obrazac identificira se nizom pozicije, u obliku <form name><dot><tab name>. Primjer: globalsettings.general ili globalsettings.security.
Svrha sustava temeljenog na klasama bez HTML-a je osloboditi autore dodataka posla ažuriranja HTML-a kada se promijeni HTML jezgre. Ipak, autor po potrebi može koristiti tip RawHtmlInput.
Jedino što u ovom sustavu ne možete učiniti jest dodavanje novih kartica obrasca.
Primjer
Za dodavanje novog unosa u obrazac iz dodatka upotrijebite sljedeći kôd u funkciji init():
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');
}
])
);
Provjera
Provjera unosa obavlja se u funkciji save (vidi primjer iznad). Ako je poslana vrijednost neispravna, bacite SaveFailedException i korisniku će se prikazati poruka upozorenja.
Podržani obrasci
Mogu se proširiti sljedeći obrasci:
- globalsettings.general (New in 6.0.0 )
Ako želite dodati podršku za drugi osnovni obrazac, trebate primijeniti sljedeću izmjenu u pull-requestu:
U datoteku prikaza (view) dodajte:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... more HTML
<?= FormExtensionWidget::render(
App()->formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
Možda ćete morati izraditi novu klasu renderera temeljenu na DefaultBaseRenderer ako se HTML obrasca razlikuje od drugih obrazaca. Možda ćete također morati proširiti zadanu klasu renderera vrstama unosa koje još nisu dodane.
Druga izmjena koju trebate napraviti je dodati poziv klasi usluge proširenja obrazaca u akciji kontrolera koja sprema obrazac:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
To je sve!
<span id="Localization_ (New in 3 )">
Lokalizacija (New in 3 )
Dodaci mogu dodati vlastite datoteke lokalizacije. Koristi se format .mo, isti kao za osnovne prijevode. Datoteke moraju biti pohranjene u
<plugin root folder>/locale/<language>/<language>.mo
gdje je "<language>" oznaka od dva slova, poput "de" ili "fr".
Za korištenje određene datoteke lokalizacije upotrijebite funkciju dodatka gT:
$this->gT("A plugin text that needs to be translated");
Ako zadani tekst nije pronađen u datoteci lokalizacije dodatka, funkcija će ga potražiti u osnovnim datotekama lokalizacije. Stoga je sigurno koristiti tekstove poput "Poništi":
$this->gT("Cancel"); // Will be translated even if "Cancel" is not in the plugin locale file
Ako uz svoj dodatak koristite prikaze (views), trebali biste koristiti
$plugin->gT("Translate me");
za prijevod specifičan za dodatak u vašem prikazu.
Datoteku limesurvey.pot možete koristiti kao primjer kako može izgledati pot datoteka. Ona se uvozi u vaš alat za prevođenje.
Alati
Jedan od alata otvorenog koda za uređivanje po i mo datoteka je Poedit.
<span id="Logging_ (New in 3 )">
Bilježenje (logging) (New in 3 )
Ako želite nešto zabilježiti iz svog dodatka, jednostavno napišite
$this->log("Your message");
Zadana razina bilježenja je trace, ali možete navesti drugu razinu kao neobavezni drugi argument:
$this->log("Something went wrong!", CLogger::LEVEL_ERROR);
Datoteka dnevnika nalazi se u mapi
<limesurvey root folder>/tmp/runtime/plugin.log
Naziv vašeg dodatka automatski se koristi kao kategorija. Zgodan način za prikaz samo pogrešaka vašeg dodatka je korištenje grep (na Linuxu):
$ tail -f tmp/runtime/plugin.log | grep <your plugin name>
<span id="Logging_plugin_deactivation_due_to_error_ (New in 6.13.3 )">
Bilježenje deaktivacije dodatka zbog pogreške (New in 6.13.3 )
Od LimeSurvey verzije 5: dodatak se može automatski deaktivirati u slučaju PHP pogreške.
LimeSurvey administratoru automatski je poslana e-pošta. Sustav bilježenja možete koristiti za generiranje upozorenja za ostale administratore poslužitelja.
Na primjer: za slanje poruke upozorenja
// Plugin error happen, plugin was disable : send email using CLogRoute
'pluginError' => array(
'class' => 'CEmailLogRoute', // https://www.yiiframework.com/doc/api/1.1/CEmailLogRoute
'categories' => 'application.model.plugin.setLoadError', // A plugin was disable
'subject' => '[ERROR] Plugin deactivated',
'emails' => ['webmaster@example.org'],
'sentFrom' => 'noreply@example.org',
'enabled' => 1, // enabled here
)
Više informacija o konfiguriranju bilježenja u Yii 1: Optional_settings#Logging_settings.
<span id="Extension_updates_ (New in 4 )">
Ažuriranja proširenja (New in 4 )
Od LimeSurvey verzije 4.0.0 postoji sustav za ažuriranje dodataka i drugih proširenja. Za korištenje tog sustava datoteka config.xml vašeg proširenja mora sadržavati konfiguraciju ažuriranja.
<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>
(Gornja oznaka source upućuje na LimeStore REST API, koji će se koristiti za sva proširenja dostupna u našem LimeStoreu.)
| Oznaka | Opis |
|---|---|
| stable | "1" ako vam ovaj izvor daje samo stabilne brojeve verzija; "0" ako će izvor davati i nestabilne verzije, poput 0.3.3-beta.
|
| type | Za sada je podržan samo tip rest. Lako je dodati nove tipove ažuriranja (provjere verzija), poput git, wget itd.
|
| source | URL s kojeg se preuzimaju nove verzije. |
| manualUpdateUrl | URL na koji korisnik može otići kako bi ažurirao na najnoviju verziju proširenja. |
| automaticUpdateUrl | TODO |
Ako ne želite pružiti ažuriranje, u svoju konfiguracijsku XML datoteku trebali biste staviti sljedeći tekst:
<updaters disabled="disabled">
</updaters>
Na taj način sustavu govorite da ste sustav ažuriranja namjerno onemogućili, a da ga niste samo zaboravili dodati.
Novi dodatak UpdateCheck - instaliran i aktiviran prema zadanim postavkama - provjerava nova ažuriranja za sva instalirana proširenja kada se prijavi superadministrator, asinkrono, najviše jednom svaka 24 sata. Ako se pronađu nove verzije, šalje se obavijest.
Ako se pronađe novo sigurnosno ažuriranje, obavijest će se automatski otvoriti i bit će prikazana u klasi "danger".
Ažuriranja možete provjeriti ručno tako da otvorite prikaz upravitelja dodataka i kliknete na "Check updates". Imajte na umu da je ovaj gumb vidljiv samo ako je dodatak UpdateCheck aktiviran.
Pod haubom
Ovaj odjeljak daje kratak pregled implementacije ažuriranja proširenja.
Ažuriranje proširenja dio je biblioteke ExtensionInstaller. U nastavku se nalazi UML dijagram klasa povezanih s postupkom ažuriranja.
Tijek programa pri pokretanju Yii-ja:
Yii init
VersionFetcherServiceLocator->init()
Add REST version fetcher
ExtensionUpdaterServiceLocator->init()
Add PluginUpdater
TODO: Add an updater for each extension type (theme, question template, ...)
Tijek programa pri pokretanju dodatka UpdaterCheck:
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
Metoda checkAll u dodatku UpdateCheck daje primjer kako provjeriti nove verzije za sva proširenja.
Dodavanje novih dohvaćača verzija
Za dodavanje novog prilagođenog dohvaćača verzija pokrenite sljedeće tijekom inicijalizacije Yii-ja:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
function (\SimpleXMLElement $updaterXml) {
return new MyNewVersionFetcher($updaterXml);
}
);
Naravno, klasa MyNewVersionFetcher mora biti podklasa klase VersionFetcher.
Za korištenje novog dohvaćača verzija konfigurirajte oznaku type u XML-u ažuriranja tako da koristi
myNewVersionFetcherType (umjesto npr. rest).
Dodavanje novih ažuriranja proširenja
Za dodavanje novog prilagođenog ažuriranja proširenja pokrenite sljedeće tijekom inicijalizacije Yii-ja:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
function () {
return MyNewExtensionUpdater::createUpdaters();
}
);
Klasa MyNewExtensionUpdater mora biti podklasa klase ExtensionUpdater.
Glavna oznaka type u datoteci config.xml ('plugin', 'theme', ...) određuje koje se ažuriranje proširenja koristi za ovo proširenje. Sustav još nije potpuno prilagodljiv, jer je potrebno dodati i prilagođeni ExtensionInstaller, stavke izbornika itd. No u teoriji, a možda i u budućnosti, ovako bi trebalo biti moguće dodati novu vrstu proširenja.
Instalacijski program proširenja
Biblioteka instalacijskog programa proširenja sastoji se od dvije apstraktne klase:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller se nasljeđuje za svaku vrstu proširenja, poput PluginInstaller, QuestionThemeInstaller itd.
FileFetcher se nasljeđuje za svaki različiti način dohvaćanja datoteka. Trenutno su podržane samo učitane zip datoteke, ali u budućnosti bi mogao postojati i dohvaćač za Github ili LimeStore.
Vodič
Ovaj vodič korak po korak pokazuje kako izraditi dodatak koji šalje POST zahtjev pri svakom slanju odgovora na upitnik. Vodič prikazuje kako izraditi i spremiti globalne postavke i postavke za pojedini upitnik, kako registrirati događaje i još mnogo toga.




