प्लगइन
From LimeSurvey Manual
अवलोकन
LimeSurvey में प्लगइन के माध्यम से सुविधाएँ जोड़ने की क्षमता है। LimeSurvey पहले से ही कई कोर प्लगइन के साथ आता है। हमारी थर्ड-पार्टी प्लगइन की सूची भी देखें, और हो सकता है भविष्य में आप उसमें अपना प्लगइन भी जोड़ें!
प्लगइन उपयोगकर्ताओं को अपनी इंस्टॉलेशन की कार्यक्षमता को अनुकूलित करने की सुविधा देते हैं, और साथ ही वे नियमित सॉफ़्टवेयर अपडेट का लाभ भी उठा सकते हैं।
यह दस्तावेज़ उन डेवलपर्स के लिए है जो LimeSurvey को अपने उपयोग या अपने क्लाइंट्स के लिए विस्तृत कर रहे हैं; अंतिम उपयोगकर्ताओं के लिए यह दस्तावेज़ उपयोगी नहीं होगा।
प्लगइन को iPlugin इंटरफ़ेस लागू करना होगा। हम अनुशंसा करते हैं कि आप अपनी प्लगइन क्लास को PluginBase क्लास से विस्तृत करें।
प्लगइन इवेंट तंत्र के आधार पर विकसित किए जाते हैं।
प्लगइन सेटिंग्स
क्लास को विस्तृत करने से आपको प्लगइन के लिए आवश्यक सामान्य कार्यक्षमता मिलती है, जिसे हमने पहले ही आपके लिए लागू कर दिया है। इनमें से एक फ़ंक्शन getPluginSettings फ़ंक्शन का कार्यान्वयन है। इस फ़ंक्शन को उपयोगकर्ता के लिए कॉन्फ़िगरेशन विकल्पों का वर्णन करने वाली एक सरणी लौटानी होगी।
उदाहरण प्लगइन केवल एक कॉन्फ़िगर करने योग्य सेटिंग प्रदान करता है, यानी वह संदेश जो वह दिखाएगा।
protected $settings = array(
'logo' => array(
'type' => 'logo',
'path' => 'assets/logo.png'
),
'message' => array(
'type' => 'string',
'label' => 'Message'
)
);
सरणी में प्रत्येक सेटिंग के लिए एक नाम कुंजी (key) के रूप में होता है। मान ऐसी सरणियाँ होती हैं जिनमें आवश्यक मेटा डेटा होता है।
समर्थित प्रकार हैं:
- logo
- int (पूर्णांक संख्या)
- string (अल्फ़ान्यूमेरिक)
- text
- html
- relevance
- info
- password
- date
- select
type के अलावा कई अन्य कुंजियाँ भी उपलब्ध हैं:
- label, एक लेबल परिभाषित करता है
- default, यदि कोई मान निर्दिष्ट न हो तो दिखाने के लिए मान परिभाषित करता है (केवल वैश्विक सेटिंग्स के लिए, सर्वेक्षण सेटिंग्स के लिए नहीं)
- current, मौजूदा मान परिभाषित करता है।
- readOnly : सेटिंग को केवल-पढ़ने योग्य (readonly) के रूप में दिखाता है
- htmlOptions, इनपुट भाग के htmlOptions (Yii मैनुअल देखें [[१]])
- 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);
यदि सेटिंग का मान null हो, तो आप डिफ़ॉल्ट मान प्राप्त कर सकते हैं:
$mySetting = $this->get('mySetting', null, null, 10); // 10 is default
सर्वेक्षण-विशिष्ट प्लगइन सेटिंग्स
सर्वेक्षण-विशिष्ट प्लगइन सेटिंग्स बनाने के लिए दो इवेंट उपयोग किए जाते हैं:
- 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 के साथ इंटरैक्ट कर सकते हैं। वर्तमान में उपलब्ध इवेंट की सूची के लिए प्लगइन इवेंट देखें।
API
प्लगइन को LimeSurvey का विस्तार केवल इसके "सार्वजनिक" API के माध्यम से ही करना चाहिए। इसका अर्थ है कि सोर्स कोड में मिलने वाली क्लासों का सीधे उपयोग करना खराब तरीका है। हम आपको ऐसा करने से रोक नहीं सकते, लेकिन हर माइनर अपडेट के साथ आपका प्लगइन काम करना बंद कर सकता है।
जहाँ तक संभव हो, LimeSurvey के साथ केवल यहाँ वर्णित मेथड के माध्यम से ही इंटरैक्ट करें। इवेंट के लिए भी यही लागू होता है।
PluginBase से एक्सटेंड करने पर API ऑब्जेक्ट $this->api के माध्यम से उपलब्ध होता है; अन्यथा आप इसे उस 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() फ़ंक्शन से निम्नलिखित कोड का उपयोग करें:
TODO: Save in plugin settings instead of global
// फ़ाइल के शीर्ष पर
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;
// 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');
}
])
);
सत्यापन
इनपुट का सत्यापन save फ़ंक्शन में किया जाता है (ऊपर का उदाहरण देखें)। यदि पोस्ट किया गया मान अमान्य है, तो SaveFailedException थ्रो करें, और उपयोगकर्ता को एक चेतावनी फ़्लैश संदेश दिखाया जाएगा।
समर्थित फ़ॉर्म
निम्नलिखित फ़ॉर्म का विस्तार किया जा सकता है:
- globalsettings.general (New in 6.0.0 )
यदि आप किसी अन्य कोर फ़ॉर्म के लिए सहायता जोड़ना चाहते हैं, तो आपको पुल-रिक्वेस्ट में निम्नलिखित बदलाव लागू करना होगा:
व्यू फ़ाइल में यह जोड़ें:
<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... more HTML
<?= FormExtensionWidget::render(
App()->formExtensionService->getAll('globalsettings.security'),
new DefaultBaseRenderer()
); ?>
यदि फ़ॉर्म का HTML अन्य फ़ॉर्म से अलग है, तो आपको DefaultBaseRenderer पर आधारित एक नई रेंडरर क्लास बनानी पड़ सकती है। आपको डिफ़ॉल्ट रेंडरर क्लास को उन इनपुट प्रकारों के साथ भी विस्तारित करना पड़ सकता है जो अभी तक जोड़े नहीं गए हैं।
दूसरा बदलाव यह है कि फ़ॉर्म को सहेजने वाले कंट्रोलर एक्शन में फ़ॉर्म एक्सटेंशन सर्विस क्लास के लिए एक कॉल जोड़ें:
$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);
बस, इतना ही!
<span id="Localization_ (New in 3 )">
स्थानीयकरण (New in 3 )
प्लगइन अपनी स्वयं की लोकेल फ़ाइलें जोड़ सकते हैं। उपयोग किया जाने वाला फ़ाइल फ़ॉर्मैट .mo है, जो कोर अनुवादों के समान है। फ़ाइलें इस स्थान पर संग्रहीत होनी चाहिए:
<plugin root folder>/locale/<language>/<language>.mo
जहाँ "<language>" दो अक्षरों का कोड है, जैसे "de" या "fr"।
किसी विशिष्ट लोकेल फ़ाइल का उपयोग करने के लिए, प्लगइन फ़ंक्शन gT का उपयोग करें:
$this->gT("A plugin text that needs to be translated");
यदि दी गई स्ट्रिंग प्लगइन की लोकेल फ़ाइल में नहीं मिलती, तो फ़ंक्शन कोर लोकेल फ़ाइलों में खोजेगा। इसलिए "रद्द" जैसी स्ट्रिंग का उपयोग करना सुरक्षित है:
$this->gT("Cancel"); // Will be translated even if "Cancel" is not in the plugin locale file
यदि आप अपने प्लगइन के साथ व्यू का उपयोग कर रहे हैं, तो आपको यह उपयोग करना चाहिए
$plugin->gT("Translate me");
ताकि अपने व्यू में प्लगइन-विशिष्ट अनुवाद किया जा सके।
pot फ़ाइल कैसी दिख सकती है, इसके उदाहरण के रूप में आप limesurvey.pot फ़ाइल का उपयोग कर सकते हैं। इसे आपके अनुवाद टूल में इम्पोर्ट किया जाता है।
टूल
po और mo फ़ाइलों को एडिट करने के लिए एक ओपन-सोर्स टूल Poedit है।
<span id="Logging_ (New in 3 )">
लॉगिंग (New in 3 )
यदि आप अपने प्लगइन से कुछ लॉग करना चाहते हैं, तो बस यह लिखें
$this->log("Your message");
डिफ़ॉल्ट लॉगिंग स्तर trace है, लेकिन आप वैकल्पिक दूसरे आर्गुमेंट के रूप में कोई अन्य लॉग स्तर दे सकते हैं:
$this->log("Something went wrong!", CLogger::LEVEL_ERROR);
लॉग फ़ाइल इस फ़ोल्डर में मिल सकती है:
<limesurvey root folder>/tmp/runtime/plugin.log
आपके प्लगइन का नाम स्वचालित रूप से श्रेणी के रूप में उपयोग किया जाता है। अपने प्लगइन की केवल त्रुटियाँ देखने का एक अच्छा तरीका grep का उपयोग करना है (Linux पर):
$ tail -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 )
LimeSurvey के संस्करण 5 से: 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 में लॉगिंग कॉन्फ़िगर करने के बारे में अधिक जानकारी: लॉगिंग सेटिंग।
<span id="Extension_updates_ (New in 4 )">
एक्सटेंशन अपडेट (New in 4 )
LimeSurvey संस्करण 4.0.0 से, प्लगइन और अन्य एक्सटेंशन अपडेट को संभालने के लिए एक सिस्टम उपलब्ध है। इस सिस्टम का उपयोग करने के लिए, आपके एक्सटेंशन की config.xml फ़ाइल में अपडेटर कॉन्फ़िगरेशन शामिल होना चाहिए।
<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>
(ऊपर दिया गया source टैग LimeStore REST API की ओर इशारा करता है, जिसका उपयोग हमारे LimeStore में उपलब्ध सभी एक्सटेंशन के लिए किया जाएगा।)
| टैग | विवरण |
|---|---|
| stable | "1" यदि यह स्रोत केवल स्थिर (stable) संस्करण संख्याएँ देता है; "0" यदि स्रोत अस्थिर संस्करण भी प्रदान करेगा, जैसे 0.3.3-beta।
|
| type | अभी केवल rest प्रकार समर्थित है। git, wget आदि जैसे नए अपडेटर प्रकार (वर्ज़न चेकर) जोड़ना आसान है।
|
| source | वह URL जहाँ से नए संस्करण प्राप्त किए जाएँ। |
| manualUpdateUrl | वह URL जहाँ उपयोगकर्ता एक्सटेंशन का नवीनतम संस्करण अपडेट करने के लिए जा सकता है। |
| automaticUpdateUrl | TODO |
यदि आप अपडेटर उपलब्ध नहीं कराना चाहते, तो अपनी config XML फ़ाइल में निम्नलिखित टेक्स्ट डालें:
<updaters disabled="disabled">
</updaters>
इस तरह आप सिस्टम को बताते हैं कि आपने अपडेट सिस्टम को जानबूझकर अक्षम किया है, और उसे जोड़ना भूले नहीं हैं।
नया प्लगइन UpdateCheck - जो डिफ़ॉल्ट रूप से इंस्टॉल और सक्रिय होता है - जब कोई सुपर एडमिन लॉग इन करता है, तो सभी इंस्टॉल किए गए एक्सटेंशन के लिए नए अपडेट की जाँच एसिंक्रोनस रूप से करता है, अधिकतम हर 24 घंटे में एक बार। यदि कोई नया संस्करण मिलता है, तो एक नोटिफ़िकेशन भेजा जाता है।
यदि कोई नया सुरक्षा अपडेट मिलता है, तो नोटिफ़िकेशन अपने आप खुल जाएगा और "danger" क्लास में स्टाइल किया जाएगा।
आप प्लगइन मैनेजर दृश्य में जाकर "Check updates" पर क्लिक करके मैन्युअल रूप से अपडेट की जाँच कर सकते हैं। ध्यान दें कि यह बटन केवल तभी दिखाई देता है जब UpdateCheck प्लगइन सक्रिय हो।
अंदरूनी कार्यप्रणाली
यह अनुभाग एक्सटेंशन अपडेटर के कार्यान्वयन का संक्षिप्त अवलोकन प्रदान करता है।
एक्सटेंशन अपडेटर ExtensionInstaller लाइब्रेरी का हिस्सा है। नीचे अपडेटर प्रक्रिया से संबंधित क्लासों का UML आरेख दिया गया है।
Yii शुरू होने पर प्रोग्राम का प्रवाह:
Yii init
VersionFetcherServiceLocator->init()
Add REST version fetcher
ExtensionUpdaterServiceLocator->init()
Add PluginUpdater
TODO: Add an updater for each extension type (theme, question template, ...)
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
UpdateCheck प्लगइन में checkAll मेथड इसका उदाहरण देता है कि नए संस्करणों के लिए सभी एक्सटेंशन की क्वेरी कैसे की जाए।
नए वर्ज़न फ़ेचर जोड़ना
नया कस्टम वर्ज़न फ़ेचर जोड़ने के लिए, Yii इनिशियलाइज़ेशन के दौरान यह चलाएँ:
$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
'myNewVersionFetcherType',
function (\SimpleXMLElement $updaterXml) {
return new MyNewVersionFetcher($updaterXml);
}
);
बेशक, क्लास MyNewVersionFetcher को VersionFetcher की सबक्लास होना चाहिए।
अपना नया वर्ज़न फ़ेचर उपयोग करने के लिए, अपडेटर XML में type टैग को इस प्रकार कॉन्फ़िगर करें कि वह
myNewVersionFetcherType का उपयोग करे (उदा. rest के बजाय)।
नए एक्सटेंशन अपडेटर जोड़ना
नया कस्टम एक्सटेंशन अपडेटर जोड़ने के लिए, Yii इनिशियलाइज़ेशन के दौरान यह चलाएँ:
$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
'myNewExtensionUpdater',
function () {
return MyNewExtensionUpdater::createUpdaters();
}
);
क्लास MyNewExtensionUpdater को ExtensionUpdater की सबक्लास होना चाहिए।
config.xml में सबसे ऊपर का type टैग ('plugin', 'theme', ...) यह नियंत्रित करेगा कि इस एक्सटेंशन के लिए कौन सा एक्सटेंशन अपडेटर उपयोग किया जाए। सिस्टम अभी पूरी तरह अनुकूलन योग्य नहीं है, क्योंकि आपको कस्टम ExtensionInstaller, मेन्यू आइटम आदि भी जोड़ने होंगे। लेकिन सैद्धांतिक रूप से, और शायद भविष्य में, इस तरह नए प्रकार का एक्सटेंशन जोड़ना संभव होना चाहिए।
एक्सटेंशन इंस्टॉलर
एक्सटेंशन इंस्टॉलर लाइब्रेरी में दो एब्स्ट्रैक्ट क्लास होती हैं:
- ExtensionInstaller
- FileFetcher
ExtensionInstaller की सबक्लास हर एक्सटेंशन प्रकार के लिए बनाई जाती है, जैसे PluginInstaller, QuestionThemeInstaller आदि।
FileFetcher की सबक्लास फ़ाइलें प्राप्त करने के हर अलग तरीके के लिए बनाई जाती है। फ़िलहाल केवल अपलोड की गई zip फ़ाइलें समर्थित हैं, लेकिन भविष्य में Github या LimeStore फ़ेचर भी हो सकता है।
ट्यूटोरियल
यह चरण-दर-चरण ट्यूटोरियल दिखाता है कि ऐसा प्लगइन कैसे बनाएँ जो हर सर्वेक्षण प्रतिक्रिया सबमिट होने पर एक POST अनुरोध भेजता है। ट्यूटोरियल में आप सीखेंगे कि वैश्विक और प्रति-सर्वेक्षण सेटिंग्स कैसे बनाएँ और सेव करें, इवेंट कैसे पंजीकृत करें, और बहुत कुछ।




