Плъгини - напреднали
From LimeSurvey Manual
Преглед
LimeSurvey има възможност да добавя функционалност чрез допълнителни модули. LimeSurvey вече се доставя с голям брой основни допълнителни модули. Разгледайте и нашия списък с допълнителни модули от трети страни и може би в бъдеще добавете и свой собствен модул към него!
Приставките позволяват на потребителите да персонализират функционалността на своята инсталация, като същевременно могат да се възползват от редовните софтуерни актуализации.
Тази документация е предназначена за разработчици, които разширяват LimeSurvey за собствена употреба или за свои клиенти; крайните потребители няма да бъдат подпомогнати от тази документация.
Добавките трябва да имплементират iPlugin интерфейс. Препоръчваме да разширите класа на вашия плъгин от класа PluginBase.
Допълнителните модули се разработват около механизъм на събития.
Настройки на плъгина
Чрез разширяването вие се възползвате от общата функционалност, изисквана от добавките, които вече сме внедрили за вас. Една от тези функции е внедряването на функцията getPluginSettings. Тази функция трябва да върне масив, описващ опциите за конфигурация за потребителя.
Примерният плъгин показва само 1 конфигурируема настройка, съобщението, което ще покаже.
protected $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
) ,
'message' => array(
'type' => 'string',
'label' => 'Message'
)
);
Масивът съдържа име за всяка настройка като ключ. Стойностите са масиви, съдържащи необходимите метаданни.
Поддържаните типове са:
- лого
- int (цяло число)
- низ (буквено-цифров)
- текст
- html
- релевантност
- информация
- парола
- дата
- изберете
Освен тип са налични редица други ключове:
- label, дефинира етикет
- default, дефинира стойност, която да се показва, ако не е зададена стойност (само за глобални настройки, не за настройки на проучването)
- current, дефинира текущата стойност.
- readOnly : показва настройките само за четене
- htmlOptions, htmlOptions на входната част (вижте ръководството на Yii [[1]])
- pluginOptions, за някои настройки (html или select) : задава опцията на уиджета
- labelOptions : htmlOptions на етикета
- controlOptions : htmlOptions на обвивката на етикета и полето за въвеждане
- localized : ако е true, стойността се съхранява за всеки език поотделно. Полето се изпраща като
name[language], аcurrentтрябва да е масив, индексиран по езиков код. - language : използва се заедно с localized. Или един езиков код, или (New in X.Y.Z ) масив от езикови кодове, за да се покаже по едно поле за всеки език (вижте Локализирани настройки на допълнителен модул)
Можете да намерите пример за приставка, като използвате всички действителни настройки на exampleSettings
Четете и записвайте настройките на приставката
Възможно е да четете и записвате настройките на приставката директно от кода на приставката.
Пример:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Можете да получите стойност по подразбиране, ако настройката се окаже нулева:
$mySetting = $this->get('mySetting', null, null, 10); // 10 е по подразбиране
Настройки на допълнителен модул, специфични за проучването
Две събития се използват за създаване на настройки на допълнителен модул, специфични за проучването:
- newSurveySettings
- beforeSurveySettings
Пример за деактивиране на допълнителен модул за конкретно проучване:
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 )">
Локализирани настройки на допълнителен модул (New in 7.4 )
За да покажете по едно поле за всеки език на проучването за една и съща настройка, задайте localized на true и подайте списъка с езици в language. Името на езика се добавя към етикета на всяко поле.
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(),
// Масив, индексиран по езиков код, напр. ['en' => '...', 'de' => '...']
'current' => $this->get('errorText', 'Survey', $surveyId, []),
],
]
]
);
}
Изпратената стойност е масив, индексиран по езиков код, така че функцията newSurveySettings от горния пример я запазва без промяна. За да прочетете текста за текущия език:
$errorTexts = $this->get('errorText', 'Survey', $surveyId, []);
$errorText = $errorTexts[App()->getLanguage()] ?? '';
Събития
Приставките се абонират за събития и могат да взаимодействат с LimeSurvey, когато събитието бъде задействано. За списък с налични в момента събития проверете Plugin events.
API
Приставките трябва да разширяват LimeSurvey само чрез неговия „обществен“ API. Това означава, че директното използване на класове, намерени в изходния код, е лоша практика. Въпреки че не можем да ви принудим да не го правите, вие рискувате да имате повреден плъгин с всяка незначителна актуализация, която правим.
Доколкото е възможно, взаимодействайте с LimeSurvey само чрез методите, описани тук. Същото важи и за събитията.
API обектът е достъпен чрез $this->api при разширяване от PluginBase, в противен случай можете да го получите от екземпляра на PluginManager, който се предава на конструктора на вашите добавки.
Нови функции могат да бъдат добавени към API обекта при поискване.
<span id="Form_extension (New in 6 )">
Разширение на формуляра (New in 6 )
Въведение
Системата за разширение на формуляри е по-общ начин за разширяване на формуляри в основния LimeSurvey без добавяне на ново събитие за всеки формуляр.
Състои се от следните компоненти:
- Глобален модул, наречен FormExtensionService
- Библиотека от входни класове, които добавките могат да добавят към горната инициализация на модула
- джаджа, заедно с потребителски рендери, които се използват във файловете за преглед на LimeSurvey
Всяка форма се идентифицира с позиционен низ, като<form name><dot><tab name> . Пример: globalsettings.general или globalsettings.security .
Смисълът зад система, базирана на класове без HTML, е да освободи авторите на плъгина на работата да актуализират HTML, когато основният HTML се промени. Все пак авторът може да използва типа RawHtmlInput , ако е необходимо.
Едно нещо, което не можете да направите в тази система, е да добавите „нови раздели на формуляра“.
Пример
За да добавите нов вход към формуляр от плъгин, използвайте следния код от вашата функция init() :
ЗАДАЧА: Запазете в настройките на плъгина вместо глобално
// В горната част на файла
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;
// В init()
Yii::app()->formExtensionService->add(
'globalsettings.general',
new TextInput([
'name' => 'myinput',
'label' => 'Етикет',
'disabled' => true,
'tooltip' => 'Moo moo moo',
'help' => 'Мало помощен текст',
'save' => function($request, $connection) {
$value = $request->getPost('myinput');
if ($value === 'някоя невалидна стойност') {
throw new SaveFailedException("Could not save custom input 'myinput'");
} else {
SettingGlobal::setSetting('myinput', $value);
}
} ,
'load' => function () {
return getGlobalSetting('myinput');
}
])
);
Валидиране
Валидирането на въведеното се извършва във функцията save (вижте примера по-горе). Ако публикуваната стойност е невалидна, хвърлете SaveFailedException и на потребителя ще се покаже предупредително флаш съобщение.
Поддържани форми
Следните форми могат да бъдат разширени:
- globalsettings.general (New in 6.0.0 )
Ако искате да добавите поддръжка за друга основна форма, трябва да приложите следната промяна в заявка за изтегляне:
Във файла за преглед добавете:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... още HTML
<?= FormExtensionWidget::render(
App()-> formExtensionService->getAll('globalsettings.security'),
нов DefaultBaseRenderer()
); ?>
Може да се наложи да създадете нов клас за изобразяване, базиран на DefaultBaseRenderer , ако формулярът HTML е различен от другите формуляри. Може също така да се наложи да разширите класа за изобразяване по подразбиране с все още недобавени типове вход.
Втората промяна, която трябва да направите, е да добавите извикване към сервизния клас за разширение на формуляр в действието на контролера, което записва формуляра:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
Това е!
<span id="Localization_ (New in 3 )">
Локализация (New in 3 )
Възможно е приставките да добавят свои собствени локални файлове. Използваният файлов формат е .mo, същият като основния превод. Файловете трябва да се съхраняват в
<plugin root folder>/локал/<language> /<language> .mo
където "<language> " е дума от две букви като "de" или "fr".
За да използвате конкретния локален файл, използвайте функцията на плъгина gT:
$this->gT("Текст на плъгин, който трябва да бъде преведен");
Ако даденият низ не може да бъде намерен в локалния файл за конкретния плъгин, функцията ще търси в основните локални файлове. Така че е безопасно да използвате низове като "Отказ":
$this->gT("Отказ"); // Ще бъде преведено, дори ако "Отказ" не е във файла с локал на приставката
Ако използвате изгледи заедно с вашия плъгин, трябва да използвате
$plugin->gT("Преведи ме");
за да направите специфичен за плъгина превод по ваш изглед.
Можете да използвате файла limesurvey.pot като пример за това как може да изглежда един pot файл. Това се импортира във вашия инструмент за превод.
Инструменти
Един инструмент с отворен код за редактиране на po- и mo-файлове е Poedit.
<span id="Logging_ (New in 3 )">
Регистриране (New in 3 )
Ако искате да регистрирате нещо от вашия плъгин, просто пишете
$this->log("Вашето съобщение");
Нивото на регистриране по подразбиране е проследяване, но можете да зададете друго ниво на регистриране като незадължителен втори аргумент:
$this->log("Нещо се обърка!", CLogger::LEVEL_ERROR);
Регистрационният файл може да бъде намерен в папка
<limesurvey root folder>/tmp/runtime/plugin.log
Името на вашия плъгин автоматично се използва като категория. Добър начин да видите само грешките от вашия плъгин е използването на grep (на Linux):
$ опашка -f tmp/runtime/plugin.log | grep<your plugin name>
<span id="Logging_plugin_deactivation_due_to_error_ (New in 6.13.3 )">
Записване в журнала при деактивиране на допълнителен модул поради грешка (New in 6.13.3 )
От версия 5 на LimeSurvey допълнителен модул може да бъде деактивиран автоматично при възникване на PHP грешка.
Автоматично се изпраща имейл до администратора на LimeSurvey. Можете да използвате системата за журнал, за да генерирате известие и към другите администратори на сървъра.
Например: за изпращане на известие
// 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
)
Повече информация за конфигуриране на регистриране в Yii 1: Optional_settings/bg#Logging_settings.
<span id="Extension_updates_ (New in 4 )">
Актуализации на разширенията (New in 4 )
От LimeSurvey версия 4.0.0 има въведена система за справяне с плъгини и други актуализации на разширения. За да използвате тази система, вашето разширение config.xml файл трябва да включва конфигурация за актуализиране.
<updaters>
<updater>
<stable> 1</stable>
<type> Почивка</type>
<source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source>
<manualUpdateUrl> https://somedownloadlink.com/maybegithub</manualUpdateUrl>
</updater>
</updaters>
(Изходният таг по-горе сочи към LimeStore REST API, който ще се използва за всички разширения, налични в нашия LimeStore.)
| Маркер | Описание |
|---|---|
| stable | „1“, ако този източник предоставя само номера на стабилни версии; „0“, ако източникът предоставя и нестабилни версии, като 0.3.3-beta.
|
| type | Засега се поддържа само тип rest. Лесно е да се добавят нови типове програми за актуализиране (проверка на версиите), като git, wget и др.
|
| source | URL адресът, от който да се извличат новите версии. |
| manualUpdateUrl | URL адрес, на който потребителят може да отиде, за да актуализира разширението до последната версия. |
| automaticUpdateUrl | TODO |
Ако не искате да предоставите програма за актуализиране, трябва да поставите следния текст във вашия конфигурационен XML файл:
<updaters disabled="disabled">
</updaters>
По този начин казвате на системата, че нарочно сте деактивирали системата за актуализиране и не сте забравили просто да я добавите.
Новият плъгин UpdateCheck - инсталиран и активиран по подразбиране - проверява за нови актуализации за всички инсталирани разширения, когато супер администратор влезе, асинхронно, максимум веднъж на всеки 24 часа. Ако бъдат намерени нови версии, се изпраща известие.
Ако бъде намерена нова актуализация на защитата, известието ще се отвори автоматично и ще бъде стилизирано в клас „опасност“.
Можете ръчно да проверите за актуализации, като отидете в изгледа на мениджъра на приставките и кликнете върху „Проверка на актуализациите“. Обърнете внимание, че този бутон се вижда само ако е активиран плъгинът UpdateCheck.
Под капака
Този раздел предоставя кратък преглед на внедряването на програмата за актуализиране на разширения.
Актуализаторът на разширението е част от библиотеката ExtensionInstaller. По-долу е UML диаграма за класовете, свързани с процеса на актуализиране.
Поток на програмата при стартиране на Yii:
Yii init VersionFetcherServiceLocator->init() Добавете програма за извличане на REST версия ExtensionUpdaterServiceLocator->init() Добавяне на PluginUpdater ЗАДАЧА: Добавете програма за актуализиране за всеки тип разширение (тема, шаблон на въпрос, ...)
Поток на програмата при стартиране на приставката UpdaterCheck:
!Н! Вземете всички актуализации от ExtensionUpdaterServiceLocator Цикъл на всеки актуализатор За всяка програма за актуализация преминете през програмите за извличане на версии, конфигурирани от<updater> XML За всяка версия за извличане, свържете се с отдалечен източник и получете информация за версията Композирайте всички версии в известие
Методът checkAll в плъгина UpdateCheck предоставя пример как да направите заявка за всички разширения за нови версии .
Добавяне на средства за извличане на нови версии
За да добавите нова персонализирана програма за извличане на версии, изпълнете това по време на инициализацията на Yii:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
функция (\SimpleXMLElement $updaterXml) {
връща нов MyNewVersionFetcher( $updaterXml);
}
);
Разбира се, класът MyNewVersionFetcher трябва да подкласи VersionFetcher .
За да използвате програмата за извличане на нови версии, конфигурирайте маркера type в XML на програмата за актуализиране да използва
myNewVersionFetcherType(вместо напр.rest).
Добавяне на нови програми за актуализация на разширения
За да добавите нов инструмент за актуализиране на потребителско разширение, изпълнете това по време на инициализацията на Yii:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
функция () {
return MyNewExtensionUpdater::createUpdaters() ;
}
);
Класът MyNewExtensionUpdater трябва да бъде подклас ExtensionUpdater .
Най-горният type таг в config.xml ('plugin', 'theme', ...) ще контролира кой инструмент за актуализиране на разширение се използва за това разширение. Системата все още не може да се персонализира напълно, тъй като трябва да добавите персонализиран ExtensionInstaller, елементи от менюто и т.н. Но на теория и може би в бъдеще би трябвало да е възможно да добавите нов тип разширение по този начин.
Инсталатор на разширение
Библиотеката за инсталиране на разширение се състои от два абстрактни класа:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller е подклас за всеки тип разширение, като PluginInstaller, QuestionThemeInstaller и т.н.
FileFetcher е подклас за всеки различен начин за извличане на файлове. Понастоящем се поддържат само качени zip файлове, но в бъдеще може да има и инструмент за извличане на Github или LimeStore.
Урок
Този урок стъпка по стъпка показва как да създадете допълнителен модул, който изпраща post заявка при всяко подаване на отговор в проучване. Уроците показва как да създавате и запазвате глобални настройки и настройки за всяко проучване, как да регистрирате събития и други.




