Plugin
From LimeSurvey Manual
Ikhtisar
LimeSurvey memiliki kemampuan untuk menambahkan fungsionalitas melalui plugin. LimeSurvey sudah dilengkapi dengan sejumlah plugin inti. Lihat juga daftar plugin pihak ketiga kami, dan mungkin di masa depan Anda dapat menambahkan plugin buatan Anda sendiri ke dalamnya!
Plugin memungkinkan pengguna menyesuaikan fungsionalitas instalasi mereka tanpa kehilangan manfaat pembaruan perangkat lunak secara berkala.
Dokumentasi ini ditujukan bagi pengembang yang memperluas LimeSurvey untuk keperluan sendiri atau untuk klien mereka; pengguna akhir tidak akan terbantu oleh dokumentasi ini.
Plugin harus mengimplementasikan antarmuka iPlugin. Kami menyarankan agar kelas plugin Anda diturunkan dari kelas PluginBase.
Plugin dikembangkan berdasarkan mekanisme event.
Pengaturan plugin
Dengan menurunkan kelas tersebut, Anda mendapatkan manfaat dari fungsionalitas umum yang dibutuhkan plugin dan sudah kami implementasikan untuk Anda. Salah satunya adalah implementasi fungsi getPluginSettings. Fungsi ini harus mengembalikan larik yang menjelaskan opsi konfigurasi bagi pengguna.
Plugin contoh hanya menampilkan 1 pengaturan yang dapat dikonfigurasi, yaitu pesan yang akan ditampilkan.
protected $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
),
'message' => array(
'type' => 'string',
'label' => 'Message'
)
);
Larik tersebut berisi nama untuk setiap pengaturan sebagai kunci. Nilainya berupa larik yang berisi metadata yang diperlukan.
Tipe yang didukung adalah:
- logo
- int (bilangan bulat)
- string (alfanumerik)
- text
- html
- relevance
- info
- password
- date
- select
Selain type, tersedia sejumlah kunci lain:
- label, menentukan label
- default, menentukan nilai yang ditampilkan jika tidak ada nilai yang ditentukan (hanya untuk pengaturan global, bukan untuk pengaturan survei)
- current, menentukan nilai saat ini.
- readOnly : menampilkan pengaturan sebagai hanya-baca
- htmlOptions, htmlOptions untuk bagian input ( lihat manual Yii [[1]])
- pluginOptions, untuk beberapa pengaturan (html atau select) : mengatur opsi widget
- labelOptions : htmlOptions untuk label
- controlOptions : htmlOptions untuk pembungkus label dan input
- localized : jika true, nilai disimpan per bahasa. Input dikirim sebagai
name[language]dancurrentharus berupa larik yang diindeks berdasarkan kode bahasa. - language : digunakan bersama localized. Bisa berupa satu kode bahasa, atau (New in X.Y.Z ) larik kode bahasa untuk menampilkan satu input per bahasa (lihat Pengaturan plugin yang dilokalkan)
Anda dapat menemukan contoh plugin yang menggunakan semua pengaturan yang tersedia di exampleSettings
Anda dapat membaca dan menulis pengaturan plugin langsung dari kode plugin Anda.
Contoh:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Anda dapat memperoleh nilai default jika pengaturan bernilai null:
$mySetting = $this->get('mySetting', null, null, 10); // 10 is default
Pengaturan plugin khusus survei
Dua event digunakan untuk membuat pengaturan plugin khusus survei:
- newSurveySettings
- beforeSurveySettings
Contoh untuk menonaktifkan plugin pada survei tertentu:
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 )">
Pengaturan plugin yang dilokalkan (New in 7.4 )
Untuk menampilkan satu input per bahasa survei untuk pengaturan yang sama, atur localized menjadi true dan berikan daftar bahasa pada language. Nama bahasa ditambahkan ke label setiap input.
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(),
// Larik yang diindeks berdasarkan kode bahasa, mis. ['en' => '...', 'de' => '...']
'current' => $this->get('errorText', 'Survey', $surveyId, []),
],
]
]
);
}
Nilai yang dikirim berupa larik yang diindeks berdasarkan kode bahasa, sehingga fungsi newSurveySettings dari contoh di atas dapat menyimpannya tanpa perubahan apa pun. Untuk membaca teks bagi bahasa saat ini:
$errorTexts = $this->get('errorText', 'Survey', $surveyId, []);
$errorText = $errorTexts[App()->getLanguage()] ?? '';
Event
Plugin berlangganan (subscribe) ke event dan dapat berinteraksi dengan LimeSurvey saat event tersebut dipicu. Untuk daftar event yang saat ini tersedia, lihat Event plugin.
API
Plugin sebaiknya hanya memperluas LimeSurvey melalui API "publik"-nya. Artinya, menggunakan langsung kelas-kelas yang ada di kode sumber merupakan praktik yang kurang baik. Meskipun kami tidak dapat melarang Anda, Anda berisiko membuat plugin Anda rusak setiap kali kami merilis pembaruan minor.
Sebisa mungkin berinteraksilah dengan LimeSurvey hanya melalui metode yang dijelaskan di sini. Hal yang sama berlaku untuk event.
Objek API tersedia melalui $this->api saat memperluas dari PluginBase; jika tidak, Anda dapat memperolehnya dari instance PluginManager yang diteruskan ke konstruktor plugin Anda.
Fungsi baru dapat ditambahkan ke objek API berdasarkan permintaan.
<span id="Form_extension (New in 6 )">
Ekstensi formulir (New in 6 )
Pendahuluan
Sistem ekstensi formulir adalah cara yang lebih umum untuk memperluas formulir pada inti LimeSurvey tanpa menambahkan event baru untuk setiap formulir.
Sistem ini terdiri dari komponen berikut:
- Sebuah modul global bernama FormExtensionService
- Sebuah pustaka kelas input yang dapat ditambahkan oleh plugin ke inisialisasi modul di atas
- Sebuah widget, beserta renderer khusus, yang digunakan pada file tampilan LimeSurvey
Setiap formulir diidentifikasi dengan string posisi, seperti <form name><dot><tab name>. Contoh: globalsettings.general atau globalsettings.security.
Tujuan dari sistem berbasis kelas tanpa HTML adalah membebaskan pembuat plugin dari pekerjaan memperbarui HTML ketika HTML inti berubah. Meski begitu, pembuat plugin tetap dapat menggunakan tipe RawHtmlInput jika diperlukan.
Satu hal yang tidak dapat Anda lakukan dalam sistem ini adalah menambahkan tab formulir baru.
Contoh
Untuk menambahkan input baru ke sebuah formulir dari plugin, gunakan kode berikut dari fungsi init() Anda:
TODO: Simpan di pengaturan plugin, bukan secara 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');
}
])
);
Validasi
Validasi input dilakukan di fungsi save (lihat contoh di atas). Jika nilai yang dikirim tidak valid, lempar SaveFailedException, dan pesan flash peringatan akan ditampilkan kepada pengguna.
Formulir yang didukung
Formulir berikut dapat diperluas:
- globalsettings.general (New in 6.0.0 )
Jika Anda ingin menambahkan dukungan untuk formulir inti lainnya, Anda perlu menerapkan perubahan berikut dalam pull request:
Pada file view, tambahkan:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... more HTML
<?= FormExtensionWidget::render(
App()->formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
Anda mungkin perlu membuat kelas renderer baru berdasarkan DefaultBaseRenderer, jika HTML formulir berbeda dari formulir lainnya. Anda mungkin juga perlu memperluas kelas renderer default dengan tipe input yang belum ditambahkan.
Perubahan kedua yang harus Anda lakukan adalah menambahkan pemanggilan ke kelas form extension service pada aksi controller yang menyimpan formulir:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
Selesai!
<span id="Localization_ (New in 3 )">
Lokalisasi (New in 3 )
Plugin dapat menambahkan file locale mereka sendiri. Format file yang digunakan adalah .mo, sama seperti terjemahan inti. File harus disimpan di
<plugin root folder>/locale/<language>/<language>.mo
dengan "<language>" adalah kata dua huruf seperti "de" atau "fr".
Untuk menggunakan file locale tertentu, gunakan fungsi plugin gT:
$this->gT("A plugin text that needs to be translated");
Jika string yang diberikan tidak ditemukan di file locale khusus plugin, fungsi akan mencarinya di file locale inti. Jadi, aman untuk menggunakan string seperti "Cancel":
$this->gT("Cancel"); // Will be translated even if "Cancel" is not in the plugin locale file
Jika Anda menggunakan view bersama plugin Anda, sebaiknya gunakan
$plugin->gT("Translate me");
untuk melakukan terjemahan khusus plugin pada view Anda.
Anda dapat menggunakan file limesurvey.pot sebagai contoh tampilan sebuah file pot. File ini diimpor ke alat terjemahan Anda.
Alat
Salah satu alat sumber terbuka untuk mengedit file po dan mo adalah Poedit.
<span id="Logging_ (New in 3 )">
Pencatatan log (New in 3 )
Jika Anda ingin mencatat sesuatu dari plugin Anda, cukup tulis
$this->log("Your message");
Level pencatatan default adalah trace, tetapi Anda dapat memberikan level log lain sebagai argumen kedua yang opsional:
$this->log("Something went wrong!", CLogger::LEVEL_ERROR);
File log dapat ditemukan di folder
<limesurvey root folder>/tmp/runtime/plugin.log
Nama plugin Anda otomatis digunakan sebagai kategori. Cara praktis untuk melihat hanya error dari plugin Anda adalah dengan menggunakan grep (di Linux):
$ tail -f tmp/runtime/plugin.log | grep <your plugin name>
<span id="Logging_plugin_deactivation_due_to_error_ (New in 6.13.3 )">
Pencatatan log penonaktifan plugin karena error (New in 6.13.3 )
Sejak LimeSurvey versi 5: plugin dapat dinonaktifkan secara otomatis jika terjadi error PHP.
Sebuah surel dikirim secara otomatis ke administrator LimeSurvey. Anda dapat menggunakan sistem log untuk membuat peringatan bagi administrator server lainnya.
Contoh: untuk mengirim pesan peringatan
// 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
)
Info lebih lanjut tentang konfigurasi pencatatan log di Yii 1: Optional settings.
<span id="Extension_updates_ (New in 4 )">
Pembaruan ekstensi (New in 4 )
Sejak LimeSurvey versi 4.0.0, tersedia sistem untuk menangani pembaruan plugin dan ekstensi lainnya. Untuk menggunakan sistem ini, file config.xml ekstensi Anda harus menyertakan konfigurasi updater.
<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>
(Tag source di atas mengarah ke REST API LimeStore, yang akan digunakan untuk semua ekstensi yang tersedia di LimeStore kami.)
| Tag | Deskripsi |
|---|---|
| stable | "1" jika sumber ini hanya memberikan nomor versi stabil; "0" jika sumber juga menyediakan versi tidak stabil, seperti 0.3.3-beta.
|
| type | Untuk saat ini, hanya tipe rest yang didukung. Tipe updater baru (pemeriksa versi) mudah ditambahkan, seperti git, wget, dll.
|
| source | URL untuk mengambil versi baru. |
| manualUpdateUrl | URL yang dapat dikunjungi pengguna untuk memperbarui ekstensi ke versi terbaru. |
| automaticUpdateUrl | TODO |
Jika Anda tidak ingin menyediakan updater, Anda harus menempatkan teks berikut di file XML konfigurasi Anda:
<updaters disabled="disabled">
</updaters>
Dengan cara ini, Anda memberi tahu sistem bahwa Anda sengaja menonaktifkan sistem pembaruan, dan bukan sekadar lupa menambahkannya.
Plugin baru UpdateCheck - yang diinstal dan diaktifkan secara default - memeriksa pembaruan baru untuk semua ekstensi yang terinstal saat super admin masuk, secara asinkron, maksimal satu kali setiap 24 jam. Jika ada versi baru yang ditemukan, sebuah pemberitahuan akan dikirim.
Jika pembaruan keamanan baru ditemukan, pemberitahuan akan terbuka secara otomatis dan ditampilkan dengan gaya kelas "danger".
Anda dapat memeriksa pembaruan secara manual dengan membuka tampilan pengelola plugin dan mengeklik "Check updates". Perhatikan bahwa tombol ini hanya terlihat jika plugin UpdateCheck diaktifkan.
Di balik layar
Bagian ini memberikan gambaran singkat tentang implementasi updater ekstensi.
Updater ekstensi merupakan bagian dari pustaka ExtensionInstaller. Berikut adalah diagram UML untuk kelas-kelas yang terkait dengan proses updater.
Alur program saat Yii dimulai:
Yii init
VersionFetcherServiceLocator->init()
Add REST version fetcher
ExtensionUpdaterServiceLocator->init()
Add PluginUpdater
TODO: Add an updater for each extension type (theme, question template, ...)
Alur program saat menjalankan plugin 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
Metode checkAll di plugin UpdateCheck memberikan contoh cara mengkueri semua ekstensi untuk versi baru.
Menambahkan pengambil versi baru
Untuk menambahkan pengambil versi kustom baru, jalankan kode berikut saat inisialisasi Yii:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
function (\SimpleXMLElement $updaterXml) {
return new MyNewVersionFetcher($updaterXml);
}
);
Tentu saja, kelas MyNewVersionFetcher harus merupakan subkelas dari VersionFetcher.
Untuk menggunakan pengambil versi baru Anda, atur tag type di XML updater agar menggunakan
myNewVersionFetcherType (bukan misalnya rest).
Menambahkan updater ekstensi baru
Untuk menambahkan updater ekstensi kustom baru, jalankan kode berikut saat inisialisasi Yii:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
function () {
return MyNewExtensionUpdater::createUpdaters();
}
);
Kelas MyNewExtensionUpdater harus merupakan subkelas dari ExtensionUpdater.
Tag type teratas di config.xml ('plugin', 'theme', ...) akan menentukan updater ekstensi mana yang digunakan untuk ekstensi ini. Sistem ini belum sepenuhnya dapat disesuaikan, karena Anda juga perlu menambahkan ExtensionInstaller kustom, item menu, dll. Namun secara teori, dan mungkin di masa depan, seharusnya dimungkinkan untuk menambahkan tipe ekstensi baru dengan cara ini.
Pemasang ekstensi
Pustaka pemasang ekstensi terdiri dari dua kelas abstrak:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller dibuatkan subkelasnya untuk setiap tipe ekstensi, seperti PluginInstaller, QuestionThemeInstaller, dll.
FileFetcher dibuatkan subkelasnya untuk setiap cara pengambilan file yang berbeda. Saat ini, hanya file zip yang diunggah yang didukung, tetapi di masa depan mungkin ada pengambil Github atau LimeStore juga.
Tutorial
Tutorial langkah demi langkah ini menunjukkan cara membuat plugin yang mengirim permintaan POST pada setiap pengiriman tanggapan survei. Tutorial ini menunjukkan cara membuat dan menyimpan pengaturan global maupun pengaturan per survei, cara mendaftarkan event, dan banyak lagi.




