Plugin - nâng cao
From LimeSurvey Manual
Tổng quan
LimeSurvey có khả năng bổ sung chức năng thông qua plugin. LimeSurvey đã đi kèm sẵn nhiều plugin lõi. Ngoài ra, hãy xem danh sách plugin của bên thứ ba của chúng tôi và biết đâu trong tương lai bạn sẽ thêm plugin của riêng mình vào đó!
Plugin cho phép người dùng tùy chỉnh chức năng cài đặt của họ trong khi vẫn có thể hưởng lợi từ các bản cập nhật phần mềm thường xuyên.
Tài liệu này dành cho các nhà phát triển đang mở rộng LimeSurvey cho mục đích sử dụng của riêng họ hoặc cho khách hàng của họ; người dùng cuối sẽ không được tài liệu này trợ giúp.
Các plugin phải triển khai giao diện iPlugin. Chúng tôi khuyên bạn nên mở rộng lớp plugin của mình từ lớp PluginBase.
Các plugin được phát triển dựa trên cơ chế sự kiện.
Cài đặt plugin
Bằng cách mở rộng, bạn sẽ được hưởng lợi từ chức năng chung được yêu cầu bởi các plugin mà chúng tôi đã triển khai cho bạn. Một trong những chức năng này là việc triển khai chức năng getPluginSettings. Hàm này phải trả về một mảng mô tả các tùy chọn cấu hình cho người dùng.
Plugin ví dụ chỉ hiển thị 1 cài đặt có thể định cấu hình, thông báo sẽ hiển thị.
protected $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
) ,
'message' => array(
'type' => 'string',
'label' => 'Message'
)
);
Mảng chứa tên cho mỗi cài đặt làm khóa. Các giá trị là các mảng chứa dữ liệu meta cần thiết.
Các loại được hỗ trợ là:
- logo
- int (số nguyên)
- chuỗi (chữ và số)
- văn bản
- html
- mức độ liên quan
- thông tin
- mật khẩu
- ngày
- chọn
Ngoài ra còn có một số phím gõ khác:
- label, xác định nhãn
- default, xác định giá trị hiển thị nếu không có giá trị nào được chỉ định (chỉ dành cho cài đặt toàn cục, không dành cho cài đặt khảo sát)
- current, xác định giá trị hiện tại.
- readOnly : hiển thị các cài đặt ở dạng chỉ đọc
- htmlOptions, htmlOptions của phần nhập liệu ( xem tài liệu hướng dẫn Yii [[1]])
- pluginOptions, đối với một số cài đặt (html hoặc select) : đặt tùy chọn của widget
- labelOptions : htmlOptions của nhãn
- controlOptions : htmlOptions của phần bao bọc nhãn và ô nhập liệu
- localized : nếu là true, giá trị được lưu theo từng ngôn ngữ. Dữ liệu nhập được gửi dưới dạng
name[language]vàcurrentphải là một mảng được lập chỉ mục theo mã ngôn ngữ. - language : được dùng cùng với localized. Có thể là một mã ngôn ngữ duy nhất, hoặc (New in X.Y.Z ) một mảng các mã ngôn ngữ để hiển thị một ô nhập liệu cho mỗi ngôn ngữ (xem Cài đặt plugin được bản địa hóa)
Bạn có thể tìm thấy ví dụ về plugin sử dụng tất cả cài đặt thực tế tại exampleSettings
Đọc và ghi cài đặt plugin
Có thể đọc và ghi cài đặt plugin trực tiếp từ mã plugin của bạn.
Ví dụ:
$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);
Bạn có thể nhận giá trị mặc định nếu cài đặt là null:
$mySetting = $this->get('mySetting', null, null, 10); // 10 là mặc định
Cài đặt plugin riêng cho khảo sát
Hai sự kiện được sử dụng để tạo cài đặt plugin riêng cho khảo sát:
- newSurveySettings
- beforeSurveySettings
Ví dụ về cách vô hiệu hóa một plugin cho một khảo sát cụ thể:
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 )">
Cài đặt plugin được bản địa hóa (New in 7.4 )
Để hiển thị một ô nhập liệu cho mỗi ngôn ngữ khảo sát đối với cùng một cài đặt, hãy đặt localized thành true và truyền danh sách các ngôn ngữ trong language. Tên ngôn ngữ được thêm vào nhãn của mỗi ô nhập liệu.
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(),
// Mảng được lập chỉ mục theo mã ngôn ngữ, ví dụ ['en' => '...', 'de' => '...']
'current' => $this->get('errorText', 'Survey', $surveyId, []),
],
]
]
);
}
Giá trị được gửi là một mảng được lập chỉ mục theo mã ngôn ngữ, vì vậy hàm newSurveySettings trong ví dụ trên sẽ lưu nó mà không cần thay đổi gì. Để đọc văn bản cho ngôn ngữ hiện tại:
$errorTexts = $this->get('errorText', 'Survey', $surveyId, []);
$errorText = $errorTexts[App()->getLanguage()] ?? '';
Sự kiện
Các plugin đăng ký sự kiện và có thể tương tác với LimeSurvey khi sự kiện được kích hoạt. Để biết danh sách các sự kiện hiện có, hãy kiểm tra Sự kiện plugin.
API
Các plugin chỉ nên mở rộng LimeSurvey thông qua API "công khai" của nó. Điều này có nghĩa là việc sử dụng trực tiếp các lớp có trong mã nguồn là một cách làm không tốt. Mặc dù chúng tôi không thể buộc bạn không làm vậy nhưng bạn có nguy cơ gặp phải plugin bị hỏng sau mỗi lần cập nhật nhỏ mà chúng tôi thực hiện.
Hãy tương tác với LimeSurvey càng nhiều càng tốt chỉ thông qua các phương thức được mô tả tại đây. Tương tự đối với các sự kiện.
Đối tượng API có sẵn thông qua $this->api khi mở rộng từ PluginBase, nếu không, bạn có thể lấy nó từ phiên bản PluginManager được chuyển đến hàm tạo của plugin của bạn.
Các chức năng mới có thể được thêm vào đối tượng API theo yêu cầu.
<span id="Form_extension (New in 6 )">
Tiện ích mở rộng biểu mẫu (New in 6 )
Giới thiệu
Hệ thống tiện ích mở rộng biểu mẫu là một cách tổng quát hơn để mở rộng biểu mẫu trong LimeSurvey cốt lõi mà không cần thêm sự kiện mới cho mỗi biểu mẫu.
Nó bao gồm các thành phần sau:
- Một mô-đun toàn cầu có tên FormExtensionService
- Một thư viện các lớp đầu vào mà các plugin có thể thêm vào quá trình khởi tạo mô-đun ở trên
- Một widget, cùng với trình kết xuất tùy chỉnh, được sử dụng trong các tệp xem LimeSurvey
Mỗi dạng được xác định bằng một chuỗi vị trí, như<form name><dot><tab name> . Ví dụ: globalsettings.general hoặc globalsettings.security .
Mục đích đằng sau một hệ thống dựa trên lớp không có HTML là giải phóng các tác giả plugin của tác phẩm để cập nhật HTML khi HTML cốt lõi thay đổi. Tuy nhiên, tác giả có thể sử dụng loại RawHtmlInput nếu cần.
Một điều bạn không thể làm trong hệ thống này là thêm tab biểu mẫu mới.
Ví dụ
Để thêm đầu vào mới vào biểu mẫu từ plugin, hãy sử dụng đoạn mã sau từ init() của bạn:
VIỆC CẦN LÀM: Lưu trong cài đặt plugin thay vì lưu chung
// Ở đầu tệp
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;
// Bên trong init()
Yii::app()->formExtensionService->add(
'globalsettings.general',
new TextInput([
'name' => 'myinput',
'label' => 'Label',
'disabled' => true,
'tooltip' => 'Moo moo moo',
'help' => 'Một số văn bản trợ giúp',
'save' => function($request, $connection) {
$value = $request->getPost('myinput');
if ($value === 'một số giá trị không hợp lệ') {
Throw new SaveFailedException("Không thể lưu thông tin nhập tùy chỉnh 'myinput'");
} else {
SettingGlobal::setSetting('myinput', $value);
}
} ,
'load' => function () {
return getGlobalSetting('myinput');
}
])
);
Xác thực
Việc xác thực đầu vào được thực hiện trong chức năng save (xem ví dụ ở trên). Nếu giá trị được đăng không hợp lệ, hãy ném SaveFailedException và một thông báo flash cảnh báo sẽ được hiển thị cho người dùng.
Các hình thức được hỗ trợ
Các hình thức sau đây có thể được mở rộng:
- Globalsettings.general (New in 6.0.0 )
Nếu bạn muốn thêm hỗ trợ cho một biểu mẫu cốt lõi khác, bạn cần áp dụng thay đổi sau trong yêu cầu kéo:
Trong tệp xem, thêm:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... thêm HTML
<?= FormExtensionWidget::render(
App()-> formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
Bạn có thể phải tạo một lớp trình kết xuất mới dựa trên DefaultBaseRenderer , nếu HTML biểu mẫu khác với các biểu mẫu khác. Bạn cũng có thể cần mở rộng lớp trình kết xuất mặc định với các loại đầu vào chưa được thêm vào.
Thay đổi thứ hai bạn phải thực hiện là thêm lệnh gọi đến lớp dịch vụ tiện ích mở rộng biểu mẫu trong hành động của bộ điều khiển lưu biểu mẫu:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
Đó là nó!
<span id="Localization_ (New in 3 )">
Bản địa hóa (New in 3 )
Các plugin có thể thêm tệp ngôn ngữ của riêng chúng. Định dạng tệp được sử dụng là .mo, giống như các bản dịch cốt lõi. Các tập tin phải được lưu trữ trong
<plugin root folder>/địa phương/<language> /<language> .mo
Ở đâu "<language> " là một từ có hai chữ cái như "de" hoặc "fr".
Để sử dụng tệp ngôn ngữ cụ thể, hãy sử dụng chức năng plugin gT:
$this->gT("Văn bản plugin cần được dịch");
Nếu không thể tìm thấy chuỗi đã cho trong tệp ngôn ngữ cụ thể của plugin, hàm sẽ tìm trong tệp ngôn ngữ cốt lõi. Vì vậy, an toàn khi sử dụng các chuỗi như "Hủy":
$this->gT("Hủy"); // Sẽ được dịch ngay cả khi "Hủy" không có trong tệp ngôn ngữ plugin
Nếu bạn đang sử dụng chế độ xem cùng với plugin của mình, bạn nên sử dụng
$plugin->gT("Dịch tôi");
để thực hiện bản dịch cụ thể của plugin trong chế độ xem của bạn.
Bạn có thể sử dụng tệp Limesurvey.pot làm ví dụ về hình thức của tệp pot. Điều này được nhập vào công cụ dịch thuật của bạn.
Công cụ
Một công cụ nguồn mở để chỉnh sửa các tệp po- và mo- là Poedit.
<span id="Logging_ (New in 3 )">
Đang ghi nhật ký (New in 3 )
Nếu bạn muốn đăng nhập nội dung nào đó từ plugin của mình, chỉ cần viết
$this->log("Tin nhắn của bạn");
Mức ghi nhật ký mặc định là theo dõi, nhưng bạn có thể đưa ra một mức nhật ký khác làm đối số thứ hai tùy chọn:
$this->log("Đã xảy ra lỗi!", CLogger::LEVEL_ERROR);
Tệp nhật ký có thể được tìm thấy trong thư mục
<limesurvey root folder>/tmp/runtime/plugin.log
Tên plugin của bạn sẽ tự động được sử dụng làm danh mục. Một cách hay để chỉ xem các lỗi từ plugin của bạn là sử dụng grep (trên Linux):
$ tail -f tmp/runtime/plugin.log | grep<your plugin name>
<span id="Logging_plugin_deactivation_due_to_error_ (New in 6.13.3 )">
Ghi log việc hủy kích hoạt plugin do lỗi (New in 6.13.3 )
Kể từ LimeSurvey phiên bản 5: một plugin có thể tự động bị hủy kích hoạt khi xảy ra lỗi PHP.
Một email được tự động gửi đến quản trị viên LimeSurvey. Bạn có thể dùng hệ thống log để tạo cảnh báo gửi đến các quản trị viên máy chủ khác.
Ví dụ: để gửi một thông báo cảnh báo
// 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
)
Thông tin thêm về cách định cấu hình ghi nhật ký trong Yii 1: Optional_settings/vi#Logging_settings.
<span id="Extension_updates_ (New in 4 )">
Cập nhật tiện ích mở rộng (New in 4 )
Kể từ phiên bản LimeSurvey 4.0.0, đã có sẵn một hệ thống để xử lý các bản cập nhật plugin và tiện ích mở rộng khác. Để sử dụng hệ thống này, tệp config.xml tiện ích mở rộng của bạn cần bao gồm cấu hình trình cập nhật.
<updaters>
<updater>
<stable> 1</stable>
<type> nghỉ ngơi</type>
<source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source>
<manualUpdateUrl> https://somedownloadlink.com/maybegithub</manualUpdateUrl>
</updater>
</updaters>
(Thẻ nguồn ở trên trỏ tới API LimeStore REST, sẽ được sử dụng cho tất cả các tiện ích mở rộng có sẵn trong LimeStore của chúng tôi.)
| Thẻ | Mô tả |
|---|---|
| stable | "1" nếu nguồn này chỉ cung cấp các số phiên bản ổn định; "0" nếu nguồn cũng cung cấp các phiên bản không ổn định, như 0.3.3-beta.
|
| type | Hiện tại chỉ hỗ trợ loại rest. Có thể dễ dàng thêm các loại trình cập nhật mới (trình kiểm tra phiên bản), như git, wget, v.v.
|
| source | URL để tìm nạp các phiên bản mới. |
| manualUpdateUrl | URL mà người dùng có thể truy cập để cập nhật phiên bản mới nhất của tiện ích mở rộng. |
| automaticUpdateUrl | TODO |
Nếu bạn không muốn cung cấp trình cập nhật, bạn nên đặt văn bản sau vào tệp XML cấu hình của mình:
<updaters disabled="disabled">
</updaters>
Bằng cách này, bạn cho hệ thống biết rằng bạn đã cố tình vô hiệu hóa hệ thống cập nhật và không quên thêm nó.
Plugin mới UpdateCheck - được cài đặt và kích hoạt theo mặc định - kiểm tra các bản cập nhật mới cho tất cả tiện ích mở rộng đã cài đặt khi quản trị viên cấp cao đăng nhập, không đồng bộ, tối đa một lần sau mỗi 24 giờ. Nếu tìm thấy bất kỳ phiên bản mới nào, một thông báo sẽ được đưa ra.
Nếu tìm thấy bản cập nhật bảo mật mới, thông báo sẽ tự động mở và được xếp vào loại "nguy hiểm".
Bạn có thể kiểm tra cập nhật theo cách thủ công bằng cách đi tới chế độ xem trình quản lý plugin và nhấp vào "Kiểm tra cập nhật". Lưu ý rằng nút này chỉ hiển thị nếu plugin UpdateCheck được kích hoạt.
Dưới mui xe
Phần này cung cấp thông tin tổng quan ngắn gọn về việc triển khai trình cập nhật tiện ích mở rộng.
Trình cập nhật tiện ích mở rộng là một phần của thư viện ExtensionInstaller. Dưới đây là sơ đồ UML cho các lớp liên quan đến quá trình cập nhật.
Luồng chương trình khi Yii khởi động:
Yii bắt đầu VersionFetcherServiceLocator->init() Thêm trình tìm nạp phiên bản REST ExtensionUpdaterServiceLocator->init() Thêm PluginUpdater VIỆC CẦN LÀM: Thêm trình cập nhật cho từng loại tiện ích mở rộng (chủ đề, mẫu câu hỏi, ...)
Luồng chương trình khi chạy plugin UpdaterCheck:
Nhận tất cả các bản cập nhật từ ExtensionUpdaterServiceLocator Lặp lại từng trình cập nhật Đối với mỗi trình cập nhật, lặp qua các trình tìm nạp phiên bản được định cấu hình bởi<updater> XML Đối với mỗi trình tìm nạp phiên bản, hãy liên hệ với nguồn từ xa và nhận thông tin phiên bản Soạn tất cả các phiên bản thành một thông báo
Phương thức checkAll trong plugin UpdateCheck cung cấp ví dụ về cách truy vấn tất cả tiện ích mở rộng cho phiên bản mới .
Thêm trình tìm nạp phiên bản mới
Để thêm trình tìm nạp phiên bản tùy chỉnh mới, hãy chạy nó trong quá trình khởi tạo Yii:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
function (\SimpleXMLElement $updaterXml) {
return new MyNewVersionFetcher( $updaterXml);
}
);
Tất nhiên, lớp MyNewVersionFetcher phải phân lớp VersionFetcher .
Để sử dụng trình tìm nạp phiên bản mới của bạn, hãy định cấu hình thẻ type trong XML của trình cập nhật để sử dụng
myNewVersionFetcherType(thay vì ví dụ nhưrest).
Thêm trình cập nhật tiện ích mở rộng mới
Để thêm trình cập nhật tiện ích mở rộng tùy chỉnh mới, hãy chạy trình này trong quá trình khởi tạo Yii:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
function () {
return MyNewExtensionUpdater::createUpdaters() ;
}
);
Lớp MyNewExtensionUpdater phải phân lớp ExtensionUpdater .
Thẻ type hàng đầu trong config.xml ('plugin', 'theme', ...) sẽ kiểm soát trình cập nhật tiện ích mở rộng nào được sử dụng cho tiện ích mở rộng này. Hệ thống này chưa thể tùy chỉnh hoàn toàn vì bạn cũng cần thêm ExtensionInstaller tùy chỉnh, các mục menu, v.v. Nhưng về mặt lý thuyết và có thể trong tương lai, bạn có thể thêm một loại tiện ích mở rộng mới theo cách này.
Trình cài đặt tiện ích mở rộng
Thư viện trình cài đặt tiện ích mở rộng bao gồm hai lớp trừu tượng:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller được phân lớp cho từng loại tiện ích mở rộng, như PluginInstaller, AskThemeInstaller, v.v.
FileFetcher được phân lớp cho từng cách tìm nạp tệp khác nhau. Hiện tại, chỉ hỗ trợ các tệp zip đã tải lên, nhưng trong tương lai, có thể có trình tìm nạp Github hoặc LimeStore.
Hướng dẫn
Hướng dẫn từng bước này chỉ cách tạo một plugin gửi yêu cầu post mỗi khi có một phản hồi khảo sát được gửi. Hướng dẫn cho bạn biết cách tạo và lưu cài đặt toàn cục cũng như cài đặt theo từng khảo sát, cách đăng ký sự kiện và nhiều nội dung khác.




