<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sammousa</id>
	<title>LimeSurvey Manual - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sammousa"/>
	<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/Special:Contributions/Sammousa"/>
	<updated>2026-08-12T21:00:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67878</id>
		<title>Plugins - advanced</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67878"/>
		<updated>2016-05-10T11:51:12Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Starting from LimeSurvey 2.05, LimeSurvey will officially support plugins. Some plugins will be supported by the LimeSurvey team and will go into core. Some will be supported by others outside the LimeSurvey team. To help find them, check out the [[Available third party plugins]] and add your own plugin to it!&lt;br /&gt;
&lt;br /&gt;
Plugins allow users to customize the functionality of their installation while still being able to benefit from regular software updates.&lt;br /&gt;
&lt;br /&gt;
This documentation is meant for developers that are extending LimeSurvey for their own use or for their clients; end users will not be helped by this documentation.&lt;br /&gt;
&lt;br /&gt;
Plugins must implement the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/iPlugin.php iPlugin] interface. We recommend extending your plugin class from the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/PluginBase.php PluginBase] class. &lt;br /&gt;
&lt;br /&gt;
Plugins are developed around an [http://manual.limesurvey.org/Plugin_events event] mechanism.&lt;br /&gt;
&lt;br /&gt;
== Plugin settings ==&lt;br /&gt;
&lt;br /&gt;
By extending you benefit from common functionality required by plugins that we already have implemented for you. One of these function is the implementation of the getPluginSettings function. This function must return an array describing the configuration options for the user.&lt;br /&gt;
&lt;br /&gt;
The example plugin exposes just 1 configurable setting, the message it&#039;ll show.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
protected $settings = array(&lt;br /&gt;
    &#039;logo&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;logo&#039;,&lt;br /&gt;
          &#039;path&#039; =&amp;gt; &#039;assets/logo.png&#039;&lt;br /&gt;
     ),&lt;br /&gt;
&lt;br /&gt;
     &#039;message&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
          &#039;label&#039; =&amp;gt; &#039;Message&#039;&lt;br /&gt;
     )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array contains a name for each setting as a key. The values are arrays containing the required meta data.&lt;br /&gt;
&lt;br /&gt;
Supported types are:&lt;br /&gt;
&lt;br /&gt;
* logo&lt;br /&gt;
* string&lt;br /&gt;
* html&lt;br /&gt;
* choice&lt;br /&gt;
* relevance&lt;br /&gt;
* info&lt;br /&gt;
&lt;br /&gt;
Besides type a number of other keys are available:&lt;br /&gt;
&lt;br /&gt;
* label, defines a label (use English, the label specified here will be passed through the translation functions)&lt;br /&gt;
* default, defines a value to show if no value is specified.&lt;br /&gt;
* current, defines the current value.&lt;br /&gt;
* readOnly, specifies the setting is read only.&lt;br /&gt;
&lt;br /&gt;
You can find a plugin example using all actual settings at https://framagit.org/Shnoulle/exampleSettings&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
Plugins subscribe to events and can interact with LimeSurvey when the event is fired. For a list of currently available events check [[Plugin events]].&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
Plugins should only extend LimeSurvey via its &amp;quot;public&amp;quot; API. This means that directly using classes found in the source code is a bad practice. Though we can&#039;t force you not to, you risk having a broken plugin with every minor update we do.&lt;br /&gt;
&lt;br /&gt;
As much as possible interact with LimeSurvey only via methods described [http://api.limesurvey.org/classes/ls.pluginmanager.LimesurveyApi.html here]. Same as for events.&lt;br /&gt;
&lt;br /&gt;
New functions can be added to the API object upon request.&lt;br /&gt;
&lt;br /&gt;
The API object is available via `$this-&amp;gt;api` when extending from PluginBase, otherwise you can get it from the PluginManager instance that is passed to your plugins&#039; constructor.&lt;br /&gt;
&lt;br /&gt;
== Special plugins ==&lt;br /&gt;
&lt;br /&gt;
[[Authentication plugin development]]&lt;br /&gt;
&lt;br /&gt;
== Available plugins ==&lt;br /&gt;
* [[Authentication plugins]]&lt;br /&gt;
* [[Available third party plugins]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67876</id>
		<title>Plugins - advanced</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67876"/>
		<updated>2016-05-10T09:13:59Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Starting from LimeSurvey 2.05, LimeSurvey will officially support plugins. Some plugins will be supported by the LimeSurvey team and will go into core. Some will be supported by others outside the LimeSurvey team. To help find them, check out the [[Available third party plugins]] and add your own plugin to it!&lt;br /&gt;
&lt;br /&gt;
Plugins allow users to customize the functionality of their installation while still being able to benefit from regular software updates.&lt;br /&gt;
&lt;br /&gt;
This documentation is meant for developers that are extending LimeSurvey for their own use or for their clients; end users will not be helped by this documentation.&lt;br /&gt;
&lt;br /&gt;
Plugins must implement the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/iPlugin.php iPlugin] interface. We recommend extending your plugin class from the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/PluginBase.php PluginBase] class. &lt;br /&gt;
&lt;br /&gt;
Plugins are developed around an [http://manual.limesurvey.org/Plugin_events event] mechanism.&lt;br /&gt;
&lt;br /&gt;
Plugins should only extend LS via its &amp;quot;public&amp;quot; API. This means that directly using classes found in the source code is a bad practice. Though we can&#039;t force you not to, you risk having a broken plugin with every minor update we do.&lt;br /&gt;
As much as possible interact with LS only via http://api.limesurvey.org/classes/ls.pluginmanager.LimesurveyApi.html, same as for events.&lt;br /&gt;
&lt;br /&gt;
New functions can be added to the API object upon request.&lt;br /&gt;
&lt;br /&gt;
== Plugin settings ==&lt;br /&gt;
&lt;br /&gt;
By extending you benefit from common functionality required by plugins that we already have implemented for you. One of these function is the implementation of the getPluginSettings function. This function must return an array describing the configuration options for the user.&lt;br /&gt;
&lt;br /&gt;
The example plugin exposes just 1 configurable setting, the message it&#039;ll show.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
protected $settings = array(&lt;br /&gt;
    &#039;logo&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;logo&#039;,&lt;br /&gt;
          &#039;path&#039; =&amp;gt; &#039;assets/logo.png&#039;&lt;br /&gt;
     ),&lt;br /&gt;
&lt;br /&gt;
     &#039;message&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
          &#039;label&#039; =&amp;gt; &#039;Message&#039;&lt;br /&gt;
     )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array contains a name for each setting as a key. The values are arrays containing the required meta data.&lt;br /&gt;
&lt;br /&gt;
Supported types are:&lt;br /&gt;
&lt;br /&gt;
* logo&lt;br /&gt;
* string&lt;br /&gt;
* html&lt;br /&gt;
* choice&lt;br /&gt;
* relevance&lt;br /&gt;
* info&lt;br /&gt;
&lt;br /&gt;
Besides type a number of other keys are available:&lt;br /&gt;
&lt;br /&gt;
* label, defines a label (use English, the label specified here will be passed through the translation functions)&lt;br /&gt;
* default, defines a value to show if no value is specified.&lt;br /&gt;
* current, defines the current value.&lt;br /&gt;
* readOnly, specifies the setting is read only.&lt;br /&gt;
&lt;br /&gt;
You can find a plugin example using all actual settings at https://framagit.org/Shnoulle/exampleSettings&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
Plugins subscribe to events and can interact with LimeSurvey when the event is fired. For a list of currently available events check [[Plugin events]].&lt;br /&gt;
&lt;br /&gt;
== Special plugins ==&lt;br /&gt;
[[Authentication plugin development]]&lt;br /&gt;
&lt;br /&gt;
== Available plugins ==&lt;br /&gt;
* [[Authentication plugins]]&lt;br /&gt;
* [[Available third party plugins]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67875</id>
		<title>Plugins - advanced</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=67875"/>
		<updated>2016-05-10T09:06:38Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Starting from LimeSurvey 2.05, LimeSurvey will officially support plugins. Some plugins will be supported by the LimeSurvey team and will go into core. Some will be supported by others outside the LimeSurvey team. To help find them, check out the [[Available third party plugins]] and add your own plugin to it!&lt;br /&gt;
&lt;br /&gt;
Plugins allow users to customize the functionality of their installation while still being able to benefit from regular software updates.&lt;br /&gt;
&lt;br /&gt;
This documentation is meant for developers that are extending LimeSurvey for their own use or for their clients; end users will not be helped by this documentation.&lt;br /&gt;
&lt;br /&gt;
Plugins must implement the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/iPlugin.php iPlugin] interface. We recommend extending your plugin class from the [https://github.com/LimeSurvey/LimeSurvey/blob/master/application/libraries/PluginManager/PluginBase.php PluginBase] class. &lt;br /&gt;
&lt;br /&gt;
Plugins are developed around an [http://manual.limesurvey.org/Plugin_events event] mechanism.&lt;br /&gt;
&lt;br /&gt;
Plugins should only extend LS via its &amp;quot;public&amp;quot; API. This means that directly using classes found in the source code is a bad practice. Though we can&#039;t force you not to, you risk having a broken plugin with every minor update we do.&lt;br /&gt;
As much as possible interact with LS only via http://api.limesurvey.org/classes/ls.pluginmanager.LimesurveyApi.html, same as for events, this API object can be extended upon request.&lt;br /&gt;
&lt;br /&gt;
== Plugin settings ==&lt;br /&gt;
&lt;br /&gt;
By extending you benefit from common functionality required by plugins that we already have implemented for you. One of these function is the implementation of the getPluginSettings function. This function must return an array describing the configuration options for the user.&lt;br /&gt;
&lt;br /&gt;
The example plugin exposes just 1 configurable setting, the message it&#039;ll show.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
protected $settings = array(&lt;br /&gt;
    &#039;logo&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;logo&#039;,&lt;br /&gt;
          &#039;path&#039; =&amp;gt; &#039;assets/logo.png&#039;&lt;br /&gt;
     ),&lt;br /&gt;
&lt;br /&gt;
     &#039;message&#039; =&amp;gt; array(&lt;br /&gt;
          &#039;type&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
          &#039;label&#039; =&amp;gt; &#039;Message&#039;&lt;br /&gt;
     )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array contains a name for each setting as a key. The values are arrays containing the required meta data.&lt;br /&gt;
&lt;br /&gt;
Supported types are:&lt;br /&gt;
&lt;br /&gt;
* logo&lt;br /&gt;
* string&lt;br /&gt;
* html&lt;br /&gt;
* choice&lt;br /&gt;
* relevance&lt;br /&gt;
* info&lt;br /&gt;
&lt;br /&gt;
Besides type a number of other keys are available:&lt;br /&gt;
&lt;br /&gt;
* label, defines a label (use English, the label specified here will be passed through the translation functions)&lt;br /&gt;
* default, defines a value to show if no value is specified.&lt;br /&gt;
* current, defines the current value.&lt;br /&gt;
* readOnly, specifies the setting is read only.&lt;br /&gt;
&lt;br /&gt;
You can find a plugin example using all actual settings at https://framagit.org/Shnoulle/exampleSettings&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
Plugins subscribe to events and can interact with LimeSurvey when the event is fired. For a list of currently available events check [[Plugin events]].&lt;br /&gt;
&lt;br /&gt;
== Special plugins ==&lt;br /&gt;
[[Authentication plugin development]]&lt;br /&gt;
&lt;br /&gt;
== Available plugins ==&lt;br /&gt;
* [[Authentication plugins]]&lt;br /&gt;
* [[Available third party plugins]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Plugins_-_advanced&amp;diff=67615</id>
		<title>Talk:Plugins - advanced</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Plugins_-_advanced&amp;diff=67615"/>
		<updated>2016-04-27T21:06:37Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Add a picture to show how each setting type look like.&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 23:36, 22 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
TODO: Add information of each setting type:&lt;br /&gt;
&lt;br /&gt;
* logo&lt;br /&gt;
* string&lt;br /&gt;
* html&lt;br /&gt;
* choice&lt;br /&gt;
* relevance&lt;br /&gt;
* info&lt;br /&gt;
&lt;br /&gt;
should rather be:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! &amp;lt;b&amp;gt;Setting type&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Example usage&amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;logo&amp;lt;/code&amp;gt; || Logo to what? Put a logo in HTML flow || near same than &#039;info&#039; type &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; || Enter string, htmlOptions needed for HTML5 validation || https://github.com/SondagesPro/LS-exportCompleteAnswers/blob/master/exportCompleteAnswers.php#L64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;float/integer&amp;lt;/code&amp;gt; || Enter a number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;html&amp;lt;/code&amp;gt; || a textearea with html editor for admin user (or public user ?)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;choice&amp;lt;/code&amp;gt; || choice : select box, need htmlOptions (multiple) || https://github.com/SondagesPro/LS-moreAccessibility/blob/master/moreAccessibility.php#L32 , can be multiple.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;relevance&amp;lt;/code&amp;gt; || Enter a relevance equation (this is basically a text editor++ think syntax highlighting / checking).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;password&amp;lt;/code&amp;gt; || A password  : to fix : don&#039;t show it in HTML flow. || for another tool (smtp/API ... etc)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; || Show information in the settings ||&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
protected $settings = array(&lt;br /&gt;
  &#039;PluginName_settingName&#039; =&amp;gt; array(&lt;br /&gt;
    &#039;type&#039; =&amp;gt; &#039;info&#039;,&lt;br /&gt;
    &#039;content&#039; =&amp;gt; &#039;This is some info&#039;&lt;br /&gt;
  )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 23:44, 22 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
We need a way to center info, or style it better by default. Also, it should use Bootstrap form-horizontal, the labels are not centered vertically as should.&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 00:17, 23 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
TODO: Add support for tabs in the settings widget.&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 15:37, 23 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
@todo : add &#039;lang&amp;quot; system : show directly html/textarea/input with all language of survey or global settings. Sam start something when save with extra data.&lt;br /&gt;
[[User:DenisChenu|DenisChenu]] ([[User talk:DenisChenu|talk]]) 08:51, 27 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Any information about plugins and translations?&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 22:46, 25 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
@todo : bug reported on Feature request. It&#039;s a must have.  Thii Yii::t directly is better for this [[User:DenisChenu|DenisChenu]] ([[User talk:DenisChenu|talk]]) 08:51, 27 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
Another feature request: A member variable that checks for LS version number.&lt;br /&gt;
&lt;br /&gt;
[[User:Olle|Olle]] ([[User talk:Olle|talk]]) 23:07, 25 April 2016 (CEST)&lt;br /&gt;
&lt;br /&gt;
Already can be done App()-&amp;gt;getConfig(&amp;quot;version&amp;quot;); I use it in one of my plugin, but don&#039;t remind where. [[User:DenisChenu|DenisChenu]] ([[User talk:DenisChenu|talk]]) 08:51, 27 April 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67376</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67376"/>
		<updated>2016-04-25T14:41:49Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Storing custom question attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
* Gender question as being a subtype of yes-no. Yes/No : subtype of &amp;quot;fixed list&amp;quot; ?&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getExportData || Way of exporting : data + &amp;quot;syntax of data&amp;quot; : SPSS/Stata/triple-S/etc ... Some &amp;quot;settings&amp;quot; can update this too (interger value for numeric for example)&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
==== Storing custom question attributes ====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Assumptions:&lt;br /&gt;
1. All questions are always (partly) stored in the `Questions` table.&lt;br /&gt;
2. There exist question attributes that are unknown (we don&#039;t know their names, their types and how many there are).&lt;br /&gt;
3. Known question attributes (like: mandatory) are always stored normalized as a column in the `Questions` table, the list below applies only to custom attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Options for storing custom question attributes:&lt;br /&gt;
&lt;br /&gt;
1. Single Table Inheritance (Add columns to `questions` table).&lt;br /&gt;
- Risk of collisions&lt;br /&gt;
- Harder to import backups into environments that slightly differ.&lt;br /&gt;
- Creates a very sparse table.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
o Full support for advanced queries / indexes (LS does not do advanced queries on this table)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Use EAV.&lt;br /&gt;
- Schemaless&lt;br /&gt;
- No data types (everything is a string)&lt;br /&gt;
+ Current approach.&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
o Little support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&lt;br /&gt;
3. Use EBLOB - store question attributes in a serialized form like JSON / XML.&lt;br /&gt;
- Schemaless&lt;br /&gt;
o More datatypes than EAV: string, int, float, bool, NULL. Fewer datatypes than STI or CTI.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Little / slow support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
o Write amplification (Yii writes the whole record regardless of what columns changed)&lt;br /&gt;
- Unfriendly for direct database editing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4.Class table inheritance (Separate table per question type containing a PK that is a FK into `Questions`)&lt;br /&gt;
+ Strict schema&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
- Complicated to implement in Yii.&lt;br /&gt;
- Reading requires at least one query per question type, depending on implemention up to 1 query per question.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67375</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67375"/>
		<updated>2016-04-25T14:34:35Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Storing custom question attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
* Gender question as being a subtype of yes-no. Yes/No : subtype of &amp;quot;fixed list&amp;quot; ?&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getExportData || Way of exporting : data + &amp;quot;syntax of data&amp;quot; : SPSS/Stata/triple-S/etc ... Some &amp;quot;settings&amp;quot; can update this too (interger value for numeric for example)&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
==== Storing custom question attributes ====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Assumptions:&lt;br /&gt;
1. All questions are always (partly) stored in the `Questions` table.&lt;br /&gt;
2. There exist question attributes that are unknown (we don&#039;t know their names, their types and how many there are).&lt;br /&gt;
3. Known question attributes (like: mandatory) are always stored normalized as a column in the `Questions` table, the list below applies only to custom attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Options for storing custom question attributes:&lt;br /&gt;
&lt;br /&gt;
1. Single Table Inheritance (Add columns to `questions` table).&lt;br /&gt;
- Risk of collisions&lt;br /&gt;
- Harder to import backups into environments that slightly differ.&lt;br /&gt;
- Creates a very sparse table.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
o Full support for advanced queries / indexes (LS does not do advanced queries on this table)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Use EAV.&lt;br /&gt;
- Schemaless&lt;br /&gt;
- No data types (everything is a string)&lt;br /&gt;
+ Current approach.&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
o Little support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&lt;br /&gt;
3. Use EBLOB - store question attributes in a serialized form like JSON / XML.&lt;br /&gt;
- Schemaless&lt;br /&gt;
o More datatypes than EAV: string, int, float, bool, NULL. Fewer datatypes than STI or CTI.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Little / slow support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
o Write amplification (Yii writes the whole record regardless of what columns changed)&lt;br /&gt;
- Unfriendly for direct database editing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4.Class table inheritance (Separate table per question type containing a PK that is a FK into `Questions`)&lt;br /&gt;
+ Strict schema&lt;br /&gt;
+ Easy to interpret database / SQL exports.&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67374</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67374"/>
		<updated>2016-04-25T14:30:57Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Storing custom question attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
* Gender question as being a subtype of yes-no. Yes/No : subtype of &amp;quot;fixed list&amp;quot; ?&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getExportData || Way of exporting : data + &amp;quot;syntax of data&amp;quot; : SPSS/Stata/triple-S/etc ... Some &amp;quot;settings&amp;quot; can update this too (interger value for numeric for example)&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
==== Storing custom question attributes ====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Assumptions:&lt;br /&gt;
1. All questions are always (partly) stored in the `Questions` table.&lt;br /&gt;
2. There exist question attributes that are unknown (we don&#039;t know their names, their types and how many there are).&lt;br /&gt;
3. Known question attributes (like: mandatory) are always stored normalized as a column in the `Questions` table, the list below applies only to custom attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Options for storing custom question attributes:&lt;br /&gt;
&lt;br /&gt;
1. Single Table Inheritance (Add columns to `questions` table).&lt;br /&gt;
- Risk of collisions&lt;br /&gt;
- Harder to import backups into environments that slightly differ.&lt;br /&gt;
- Creates a very sparse table.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Full support for advanced queries / indexes (LS does not do advanced queries on this table)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Use EAV.&lt;br /&gt;
- Schemaless&lt;br /&gt;
- No data types (everything is a string)&lt;br /&gt;
+ Current approach.&lt;br /&gt;
+ Easier to interpret database / SQL exports.&lt;br /&gt;
o Little support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&lt;br /&gt;
3. Use EBLOB - store question attributes in a serialized form like JSON / XML.&lt;br /&gt;
- Schemaless&lt;br /&gt;
o More datatypes than EAV: string, int, float, bool, NULL. Fewer datatypes than STI or CTI.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Little / slow support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
o Write amplification (Yii writes the whole record regardless of what columns changed)&lt;br /&gt;
- Unfriendly for direct database editing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4.Class table inheritance (Separate table per question type containing a PK that is a FK into `Questions`)&lt;br /&gt;
+ Strict schema&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67373</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67373"/>
		<updated>2016-04-25T14:28:56Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Storing custom question attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
* Gender question as being a subtype of yes-no. Yes/No : subtype of &amp;quot;fixed list&amp;quot; ?&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getExportData || Way of exporting : data + &amp;quot;syntax of data&amp;quot; : SPSS/Stata/triple-S/etc ... Some &amp;quot;settings&amp;quot; can update this too (interger value for numeric for example)&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
==== Storing custom question attributes ====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Assumptions:&lt;br /&gt;
1. All questions are always (partly) stored in the `Questions` table.&lt;br /&gt;
2. There exist question attributes that are unknown (we don&#039;t know their names, their types and how many there are).&lt;br /&gt;
3. Known question attributes (like: mandatory) are always stored normalized as a column in the `Questions` table, the list below applies only to custom attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Options for storing custom question attributes:&lt;br /&gt;
&lt;br /&gt;
1. Single Table Inheritance (Add columns to `questions` table).&lt;br /&gt;
- Risk of collisions&lt;br /&gt;
- Harder to import backups into environments that slightly differ.&lt;br /&gt;
- Creates a very sparse table.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Full support for advanced queries / indexes (LS does not do advanced queries on this table)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Use EAV.&lt;br /&gt;
- Schemaless&lt;br /&gt;
- No data types (everything is a string)&lt;br /&gt;
+ Current approach.&lt;br /&gt;
o Little support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&lt;br /&gt;
3. Use EBLOB - store question attributes in a serialized form like JSON / XML.&lt;br /&gt;
- Schemaless&lt;br /&gt;
o More datatypes than EAV: string, int, float, bool, NULL. Fewer datatypes than STI or CTI.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Little / slow support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
o Write amplification (Yii writes the whole record regardless of what columns changed)&lt;br /&gt;
- Unfriendly for direct database editing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4.Class table inheritance (Separate table per question type containing a PK that is a FK into `Questions`)&lt;br /&gt;
+ Strict schema&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67372</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67372"/>
		<updated>2016-04-25T14:09:10Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
* Gender question as being a subtype of yes-no. Yes/No : subtype of &amp;quot;fixed list&amp;quot; ?&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getExportData || Way of exporting : data + &amp;quot;syntax of data&amp;quot; : SPSS/Stata/triple-S/etc ... Some &amp;quot;settings&amp;quot; can update this too (interger value for numeric for example)&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
==== Storing custom question attributes ====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Assumptions:&lt;br /&gt;
1. All questions are always (partly) stored in the `Questions` table.&lt;br /&gt;
2. There exist question attributes that are unknown (we don&#039;t know their names, their types and how many there are).&lt;br /&gt;
3. Known question attributes (like: mandatory) are always stored normalized as a column in the `Questions` table, the list below applies only to custom attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Options for storing custom question attributes:&lt;br /&gt;
&lt;br /&gt;
1. Single Table Inheritance (Add columns to `questions` table).&lt;br /&gt;
- Risk of collisions&lt;br /&gt;
- Harder to import backups into environments that slightly differ.&lt;br /&gt;
- Creates a very sparse table.&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Full support for advanced queries / indexes (LS does not do advanced queries on this table)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Use EAV.&lt;br /&gt;
- Schemaless&lt;br /&gt;
+ Current approach.&lt;br /&gt;
o Little support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&lt;br /&gt;
3. Use EBLOB - store question attributes in a serialized form like JSON / XML.&lt;br /&gt;
- Schemaless&lt;br /&gt;
+ Fast for retrieving&lt;br /&gt;
+ Easy to support full model validation in Yii&lt;br /&gt;
o Little / slow support for advanced queries (LS does not do advanced queries on this table)&lt;br /&gt;
o Write amplification (Yii writes the whole record regardless of what columns changed)&lt;br /&gt;
- Unfriendly for direct database editing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4.Class table inheritance (Separate table per question type containing a PK that is a FK into `Questions`)&lt;br /&gt;
+ Strict schema&lt;br /&gt;
- Requires transactions if we want to have atomic writes.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67332</id>
		<title>Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_object_types&amp;diff=67332"/>
		<updated>2016-04-25T11:13:50Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object types is about making questions in LS more object-oriented and modular, and letting users create and upload their own object types.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Basically, every place in the code which is doing a switch on question type should be replaced by a polymorphic call to an object, e.g. &amp;lt;code&amp;gt;$object-&amp;gt;renderFrontend();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old wiki page: https://manual.limesurvey.org/Question_Objects&lt;br /&gt;
&lt;br /&gt;
=== Use-cases ===&lt;br /&gt;
&lt;br /&gt;
* Colour picker - user click on a picture with colours, and the position in the picture defines the colour.&lt;br /&gt;
* &amp;quot;... the surgeon would indicate the location of a fracture by drawing on a diagram of the knee.&amp;quot;&lt;br /&gt;
* Having more than one question in one &amp;quot;library&amp;quot; file, where some of the questions can be activated via a bought activation code.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Open issues ===&lt;br /&gt;
&lt;br /&gt;
* Is array it&#039;s own object type, or is it a &amp;lt;i&amp;gt;property&amp;lt;/i&amp;gt; of a question? Could we have an array of any question typ, e.g. yes/no questions?&lt;br /&gt;
* Cross-cutting concerns: &lt;br /&gt;
** What if the user wants to add a comment field to all questions in the survey? Use a plugin? Or time limit, which can be added to all questions, but shouldn&#039;t take up space if it&#039;s not used. Shnoulle/Sam recommends EAV table; Olle thinks it&#039;s too schema-less and that question types could modify the database instead. Actually all this part was in QuestionAttribute.&lt;br /&gt;
&lt;br /&gt;
*** Sam:&lt;br /&gt;
**** I think we can identify some properties that apply to (almost) all question types, these should be in the question table (think EM expression, or mandatory or always hidden).&lt;br /&gt;
**** Then there are properties that are specific for a question type, for example the maximum / minimum number for a text question, or the step size for a slider. Storing these in the main table as separate column will make create lots of columns with very sparse data. Alternatives are EAV or serialization. Note: LS core will never do anything with this data except retrieve / store it, so serialization is a valid option.&lt;br /&gt;
**** Then there are generic question settings that someone might want to add support for, for example time_limit. There should be some way for plugins to add these settings to all questions and then handle their values when the time comes. -- This is something new and needs to be further explored.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
** Example of some part that can not be Question Type object, but must extend Question type &lt;br /&gt;
*** Updating EM/core system : example for [[Question_type_-_Short_free_text#Always_hide_this_question_.28hidden.29|hidden]] or [[Question_type_-_Short_free_text#Randomization_group_name_.28random_group.29|random_group]], validation (em_validation, numeric, min , max ...)&lt;br /&gt;
*** Updating HTML produced only [[Question_type_-_Short_free_text#Maximum_characters_.28maximum_chars.29|maximum_chars]], validation can update HTML part too : min+max+step on numeric for example (usage of type=&amp;quot;number&amp;quot;)&lt;br /&gt;
*** Add some JS/css or some HTML element (addContent, registerScript ....) [[Question_type_-_Short_free_text#Time_limit_.28time_limit.29|time_limit]]&lt;br /&gt;
* Composability: Should it be possible to combine two questions into one, or pick-and-choose among &amp;quot;question elements&amp;quot;?&lt;br /&gt;
* Should we also change the way we save answer data? If yes, in which step - first or last? Which database design should we use instead?&lt;br /&gt;
* Can we inherit views?&lt;br /&gt;
* Interaction with plugins, e.g. Stata XML export? No other way around it than using switch in plugin, or each question type should itself supply a method the plugin can use?&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
Object hierarchy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
&lt;br /&gt;
This is a list of functions that question types could implement. They could be included in a &amp;quot;base interface&amp;quot; or abstract base class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
! &amp;lt;b&amp;gt;Function name&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt;Meaning&amp;lt;/b&amp;gt; !! &amp;lt;b&amp;gt; Mandatory &amp;lt;/b&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| renderFrontend || Former qanda code; render question for survey taker || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderDataEntryForm || Render form for manual insertion of data. NB: Same as renderFrontend? || Y&lt;br /&gt;
|-&lt;br /&gt;
| getSettings || Return settings (array) that can be used by a settings widget for edit form in backend || Y&lt;br /&gt;
|-&lt;br /&gt;
| renderCustomSettings || Possibly custom HTML settings?&lt;br /&gt;
|-&lt;br /&gt;
| getStatisticsData || Return statistics data that will be fed to a renderer (like HTML, PDF, etc) || Y&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Implemented as Yii module, with views, models and controllers (http://www.yiiframework.com/doc/guide/1.1/en/basics.module#creating-module).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace switch-cases in:&lt;br /&gt;
&lt;br /&gt;
* Frontend render (render answers, qanda)&lt;br /&gt;
* Backend render (edit question, file &amp;lt;code&amp;gt;questions.php&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Statistics&lt;br /&gt;
* SQL and database queries, included extra field the question might define&lt;br /&gt;
* Expression manager&lt;br /&gt;
&lt;br /&gt;
Ideally, each switch case in the code should have a unit test or functional test to test it with.&lt;br /&gt;
&lt;br /&gt;
==== Current question types ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From statistics.php:&lt;br /&gt;
&lt;br /&gt;
*  1 - Array Dual Scale &lt;br /&gt;
*  5 - 5 Point Choice&lt;br /&gt;
*  A - Array (5 Point Choice)&lt;br /&gt;
*  B - Array (10 Point Choice)&lt;br /&gt;
*  C - Array (Yes/No/Uncertain)&lt;br /&gt;
*  D - Date&lt;br /&gt;
*  E - Array (Increase, Same, Decrease)&lt;br /&gt;
*  F - Array (Flexible Labels)&lt;br /&gt;
*  G - Gender&lt;br /&gt;
*  H - Array (Flexible Labels) by Column&lt;br /&gt;
*  I - Language Switch&lt;br /&gt;
*  K - Multiple Numerical Input&lt;br /&gt;
*  L - List (Radio)&lt;br /&gt;
*  M - Multiple choice&lt;br /&gt;
*  N - Numerical Input&lt;br /&gt;
*  O - List With Comment&lt;br /&gt;
*  P - Multiple choice with comments&lt;br /&gt;
*  Q - Multiple Short Text&lt;br /&gt;
*  R - Ranking&lt;br /&gt;
*  S - Short Free Text&lt;br /&gt;
*  T - Long Free Text&lt;br /&gt;
*  U - Huge Free Text&lt;br /&gt;
*  X - Boilerplate Question&lt;br /&gt;
*  Y - Yes/No&lt;br /&gt;
*  ! - List (Dropdown)&lt;br /&gt;
*  : - Array (Flexible Labels) multiple drop down&lt;br /&gt;
*  ; - Array (Flexible Labels) multiple texts&lt;br /&gt;
*  | - File Upload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Categories:&lt;br /&gt;
&lt;br /&gt;
* Single-choice questions&lt;br /&gt;
* Arrays&lt;br /&gt;
* Mask questions&lt;br /&gt;
* Text questions&lt;br /&gt;
* Multiple-choice questions&lt;br /&gt;
&lt;br /&gt;
=== Prototype/proof-of-concept ===&lt;br /&gt;
&lt;br /&gt;
As a first cycle of development (iteration), one could implement a completely new question type (say, drawing board) with the new system on top of the old one. The purpose would be to get a better feeling of the problem domain, what changes are needed, if the current approach is possible, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the prototype is done, the existent questions can be exported to the new system one by one. This represents a &amp;quot;horizontal&amp;quot; development style, where the complete problem is solved for _one_ case in the first cycle, in contrast to exporting the entire qanda to the new system, then the entire statistics module, etc. A horizontal style would give faster results and introduce lesser mechanical work, focusing on design and creativity which is needed in the beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example from qanda:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;if (is_object($ia))&lt;br /&gt;
{&lt;br /&gt;
  $ia-&amp;gt;renderFrontend();&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    switch ($ia[4])  // $ia[4] is question type&lt;br /&gt;
    {&lt;br /&gt;
        case &#039;X&#039;: //BOILERPLATE QUESTION&lt;br /&gt;
            $values = do_boilerplate($ia);&lt;br /&gt;
            break;&lt;br /&gt;
        // and so on for all question types&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When all questions have been exported to the new system, this snippet will just be:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$ia-&amp;gt;renderFrontend();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current LS3 implementation ===&lt;br /&gt;
&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66990</id>
		<title>Talk:Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66990"/>
		<updated>2016-04-21T09:50:09Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Question object specification text ==&lt;br /&gt;
&lt;br /&gt;
# I think specification is not the same as (our) implementation.&lt;br /&gt;
#: Olle: True. But the current implementation in LS3 lacks specification. There needs to be something written down that exactly specifies what&#039;s needed and why.&lt;br /&gt;
#:: Sam: Agree, the current implementation is just a refactoring of LS2 code (moving global functions to OO), it can and should be adapted to whatever requirements come up with.&lt;br /&gt;
# Specifications should consist of interfaces (and optionally abstract classes) only.&lt;br /&gt;
#: Olle: Question types will need to include CSS, Javascript, HTML, pictures etc. So only interfaces is not enough.&lt;br /&gt;
#:: Sam: It doesn&#039;t matter what they include, we just need to specify how it should interact. For example, for example how it tells us what javascript / css to publish to a publicly accessible directory. Note that I agree that we should give a &amp;quot;logically structured&amp;quot; example plugin, that should not be part of the contract in my opinion.&lt;br /&gt;
&lt;br /&gt;
== Current LS3 implementation ==&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
#: Sam: Regarding the current minimum requirements with 6 render functions:&lt;br /&gt;
(11:44:52 AM) sammousa: @ollehar, I don&#039;t like the 5 render functions on the question interface&lt;br /&gt;
&lt;br /&gt;
(11:45:34 AM) sammousa: 3 of them are for statistics, but instead there should be 1 &amp;quot;canonical&amp;quot; form for statistical information that LS can then properly render into different formats&lt;br /&gt;
&lt;br /&gt;
(11:45:50 AM) sammousa: (I don&#039;t want to implement a new question type just to have it use a different kind of display for statistics)&lt;br /&gt;
&lt;br /&gt;
(11:46:24 AM) sammousa: Also I don&#039;t think we should have renderEditForm, but instead we should provide some format where a question can define its settings.&lt;br /&gt;
&lt;br /&gt;
(11:46:49 AM) sammousa: Having each question render HTML will make templating practically impossible; also when I develop a new type of question&lt;br /&gt;
&lt;br /&gt;
(11:47:10 AM) sammousa: I don&#039;t want to think about HTML code for the settings, I just want to say: setting A is a boolean setting&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66989</id>
		<title>Talk:Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66989"/>
		<updated>2016-04-21T09:49:47Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Question object specification text ==&lt;br /&gt;
&lt;br /&gt;
# I think specification is not the same as (our) implementation.&lt;br /&gt;
#: Olle: True. But the current implementation in LS3 lacks specification. There needs to be something written down that exactly specifies what&#039;s needed and why.&lt;br /&gt;
#:: Sam: Agree, the current implementation is just a refactoring of LS2 code (moving global functions to OO), it can and should be adapted to whatever requirements come up with.&lt;br /&gt;
# Specifications should consist of interfaces (and optionally abstract classes) only.&lt;br /&gt;
#: Olle: Question types will need to include CSS, Javascript, HTML, pictures etc. So only interfaces is not enough.&lt;br /&gt;
#:: Sam: It doesn&#039;t matter what they include, we just need to specify how it should interact. For example, for example how it tells us what javascript / css to publish to a publicly accessible directory. Note that I agree that we should give a &amp;quot;logically structured&amp;quot; example plugin, that should not be part of the contract in my opinion.&lt;br /&gt;
&lt;br /&gt;
== Current LS3 implementation ==&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;br /&gt;
&lt;br /&gt;
#: Sam: Regarding the current minimum requirements with 6 render functions:&lt;br /&gt;
(11:44:52 AM) sammousa: @ollehar, I don&#039;t like the 5 render functions on the question interface&lt;br /&gt;
(11:45:34 AM) sammousa: 3 of them are for statistics, but instead there should be 1 &amp;quot;canonical&amp;quot; form for statistical information that LS can then properly render into different formats&lt;br /&gt;
(11:45:50 AM) sammousa: (I don&#039;t want to implement a new question type just to have it use a different kind of display for statistics)&lt;br /&gt;
(11:46:24 AM) sammousa: Also I don&#039;t think we should have renderEditForm, but instead we should provide some format where a question can define its settings.&lt;br /&gt;
(11:46:49 AM) sammousa: Having each question render HTML will make templating practically impossible; also when I develop a new type of question&lt;br /&gt;
(11:47:10 AM) sammousa: I don&#039;t want to think about HTML code for the settings, I just want to say: setting A is a boolean setting&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66684</id>
		<title>Talk:Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66684"/>
		<updated>2016-04-12T16:32:33Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Question object specification text */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Question object specification text ==&lt;br /&gt;
&lt;br /&gt;
# I think specification is not the same as (our) implementation.&lt;br /&gt;
## Olle: True. But the current implementation in LS3 lacks specification. There needs to be something written down that exactly specifies what&#039;s needed and why.&lt;br /&gt;
## Sam: Agree, the current implementation is just a refactoring of LS2 code (moving global functions to OO), it can and should be adapted to whatever requirements come up with.&lt;br /&gt;
# Specifications should consist of interfaces (and optionally abstract classes) only.&lt;br /&gt;
## Olle: Question types will need to include CSS, Javascript, HTML, pictures etc. So only interfaces is not enough.&lt;br /&gt;
## Sam: It doesn&#039;t matter what they include, we just need to specify how it should interact. For example, for example how it tells us what javascript / css to publish to a publicly accessible directory. Note that I agree that we should give a &amp;quot;logically structured&amp;quot; example plugin, that should not be part of the contract in my opinion.&lt;br /&gt;
&lt;br /&gt;
== Current LS3 implementation ==&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66676</id>
		<title>Talk:Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66676"/>
		<updated>2016-04-12T13:02:02Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Question object specification text ==&lt;br /&gt;
1. I think specification is not the same as (our) implementation.&lt;br /&gt;
&lt;br /&gt;
2. Specifications should consist of interfaces (and optionally abstract classes) only.&lt;br /&gt;
&lt;br /&gt;
== Current LS3 implementation ==&lt;br /&gt;
Note, this is the current state and some of these are mostly because it is a refactoring from LS2.&lt;br /&gt;
&lt;br /&gt;
1. Uses an interface.&lt;br /&gt;
&lt;br /&gt;
2. Defines what columns it needs via a fieldname =&amp;gt; column type map.&lt;br /&gt;
&lt;br /&gt;
3. Defines what EM expressions apply to it.&lt;br /&gt;
&lt;br /&gt;
4. Defines a render functionality that renders the content.&lt;br /&gt;
&lt;br /&gt;
5. Defines a list of classes that should be in the wrapping div.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66675</id>
		<title>Talk:Question object types</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Talk:Question_object_types&amp;diff=66675"/>
		<updated>2016-04-12T12:55:17Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: Created page with &amp;quot;Question object specification 1. I think specification is not the same as (our) implementation. 2. Specifications should consist of interfaces (and optionally abstract classes...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Question object specification&lt;br /&gt;
1. I think specification is not the same as (our) implementation.&lt;br /&gt;
2. Specifications should consist of interfaces (and optionally abstract classes) only.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugin_events&amp;diff=66033</id>
		<title>Plugin events</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugin_events&amp;diff=66033"/>
		<updated>2015-07-02T08:50:05Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At version 2.05+ build 140320 the following events are available for plugins to subscribe to:&lt;br /&gt;
*[[Authentication plugin development#afterLoginFormSubmit|afterLoginFormSubmit]]&lt;br /&gt;
*[[Authentication plugin development#afterLogout|afterLogout]]&lt;br /&gt;
*[[afterPluginLoad]]&lt;br /&gt;
*[[afterSurveyComplete]]&lt;br /&gt;
*[[afterSurveyQuota]]{{NewIn|v=2.05|b=141006}}&lt;br /&gt;
*[[beforeActivate]]&lt;br /&gt;
*[[beforeDeactivate]]&lt;br /&gt;
*[[beforeHasPermission]]{{NewIn|v=2.06}}&lt;br /&gt;
*[[beforeLoadResponse]]&lt;br /&gt;
*[[beforeLogin]]&lt;br /&gt;
*[[beforeLogout]]&lt;br /&gt;
*[[beforeQuestionRender]]{{NewIn|v=2.05|b=140922}}&lt;br /&gt;
*[[beforeRegister]]{{NewIn|v=2.06}}&lt;br /&gt;
*[[beforeRegisterForm]]{{NewIn|v=2.06}}&lt;br /&gt;
*[[beforePermissionSetSave]]&lt;br /&gt;
*[[beforeSurveyPage]]{{NewIn|v=2.05|b=140109}}&lt;br /&gt;
*[[beforeSurveySettings]]&lt;br /&gt;
*[[beforeTokenEmail]]{{NewIn|v=2.05|b=140404}}&lt;br /&gt;
*[[cron]]{{NewIn|v=2.05|b=140404}}&lt;br /&gt;
*[[listExportOptions]]&lt;br /&gt;
*[[listExportPlugins]]&lt;br /&gt;
*[[listQuestionPlugins]]&lt;br /&gt;
*[[newDirectRequest]]&lt;br /&gt;
*[[newExport]]&lt;br /&gt;
*[[newLoginForm]]&lt;br /&gt;
*[[newSurveySettings]]&lt;br /&gt;
*[[newUserSession]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64711</id>
		<title>Feature:alloweditaftercompletion</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64711"/>
		<updated>2015-04-03T09:43:52Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When enabled this will allow users to edit their response after completion.&lt;br /&gt;
A user can get access to edit his or her response in several ways:&lt;br /&gt;
*When using tokens, by clicking the token link. &lt;br /&gt;
*When not using tokens, by using the &amp;quot;bookmark my survey&amp;quot; button.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64710</id>
		<title>Feature:alloweditaftercompletion</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64710"/>
		<updated>2015-04-03T09:43:34Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Allow editing after completion}} &lt;br /&gt;
When enabled this will allow users to edit their response after completion.&lt;br /&gt;
A user can get access to edit his or her response in several ways:&lt;br /&gt;
*When using tokens, by clicking the token link. &lt;br /&gt;
*When not using tokens, by using the &amp;quot;bookmark my survey&amp;quot; button.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64708</id>
		<title>Feature:alloweditaftercompletion</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Feature:alloweditaftercompletion&amp;diff=64708"/>
		<updated>2015-04-03T09:39:58Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: Created page with &amp;quot;When enabled this will allow users to edit their response after completion. A user can get access to edit his or her response in several ways: *When using tokens, by clicking...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When enabled this will allow users to edit their response after completion.&lt;br /&gt;
A user can get access to edit his or her response in several ways:&lt;br /&gt;
*When using tokens, by clicking the token link. &lt;br /&gt;
*When not using tokens, by using the &amp;quot;bookmark my survey&amp;quot; button.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSoC_2015&amp;diff=64427</id>
		<title>Project ideas for GSoC 2015</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSoC_2015&amp;diff=64427"/>
		<updated>2015-02-24T15:10:47Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Make use of the SettingsWidget for core functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Welcome, Google Summer of Code student aspirants!=&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community - &#039;&#039;&#039;please note that we have applied as organization for GSoC 2015 but we are currently waiting if we will get accepted into this great program, again&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The ideas listed here are the ones that will get the most support since they have been developed by people who know the project and what it needs the most. However, if you have your own project idea for LimeSurvey please discuss your awesome idea with us in our [https://www.limesurvey.org/en/forum/development forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or in our [https://www.limesurvey.org/en/community-services/live-chat IRC channel at #limesurvey on irc.freenode.net]. &lt;br /&gt;
&lt;br /&gt;
You can also find alot of ideas for new features in our [http://bugs.limesurvey.org/set_project.php?ref=view_all_set.php&amp;amp;project_id=12 feature tracker] &lt;br /&gt;
&lt;br /&gt;
Also have a look at our following documents:&lt;br /&gt;
&lt;br /&gt;
*[[GSoC FAQ]]   &lt;br /&gt;
*[[GSoC getting started]]&lt;br /&gt;
*[[GSoC selection criteria]]&lt;br /&gt;
*[[GSoC Student Application Template]]&lt;br /&gt;
&lt;br /&gt;
We are looking forward to your proposal. Good luck!&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Visualize different paths through a survey based on conditions set at a survey==&lt;br /&gt;
&lt;br /&gt;
Limesurvey&#039;s Expression Manager (EM) allows [https://manual.limesurvey.org/Expression_Manager#Relevance_.28Controlling_Navigation.2FBranching.29 adding complex conditions] to survey questions so that certain questions are only shown if those conditions validate to &amp;quot;true&amp;quot;. At lengthy surveys with lots of conditions this will create several different potentials paths through a survey depending on the answers given by a user.&lt;br /&gt;
To help our growing user base to deal with this complex problem we plan to create a fully new tool for visualizing the different paths through a survey based on the existing conditions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps&#039;&#039;&#039;&lt;br /&gt;
# Have a look at the [https://manual.limesurvey.org/Expression_Manager Expression Manager documentation] to get familiar with this powerful tool for creating complex conditions&lt;br /&gt;
# Check how conditions are stored at the database&lt;br /&gt;
# Analyse how EM internally handles conditions to determine whether a question should be displayed &lt;br /&gt;
# Test conditions of different complexity at different survey levels (single question vs survey groups)&lt;br /&gt;
# Do some research on tools which can be used for visualizing paths e.g. [http://diagramo.com/Diagramo]. Make sure the licence is compatible with the [https://www.limesurvey.org/en/about-limesurvey/license Limesurvey licence]&lt;br /&gt;
# Describe the architecture of your program and how you plan to integrate it into Limesurvey. Discuss your approach with your mentor&lt;br /&gt;
# Start coding a first test version based on simple conditions and short surveys. Test how this scales when it comes to larger surveys and more complex conditions.&lt;br /&gt;
# Share your first version with other developers and Limesurvey users so they can test their own complex surveys.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You should know about PHP MVC architcture and PHP frameworks (we are using [http://www.yiiframework.com/ Yii] framework) because most development will be PHP code.&lt;br /&gt;
You should also know SQL because your scirpts will need to query the DB for existing conditions. Some HTML + CSS will help for creating a nice visualization of the different paths.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz, Marcel Minke ([[User:Mazi|Mazi]])&lt;br /&gt;
&lt;br /&gt;
==Update Limesurvey Template Engine to use Twig==&lt;br /&gt;
&lt;br /&gt;
Currently Limesurvey uses its own custom coded template engine. Since the framework used for Limesurvey (&amp;quot;[http://www.yiiframework.com/ Yii]&amp;quot;) supports the [http://www.yiiframework.com/ Twig] template engine we plan to replace the custom coded template engine with Twig&#039;s template engine for better code maintenance and embedding with the Yii framework. Extra credits would get you if you introduce customized template functions - so a user can easily change logo, logo placement and colors for a specific template using the template editor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps&#039;&#039;&#039;&lt;br /&gt;
# Check how the current Limesurvey templates are structured&lt;br /&gt;
# Dig into the related code to find out how the underlying Limesurvey template engine works&lt;br /&gt;
# Get familiar with the structure of Twig templates &lt;br /&gt;
# Test-edit one of the shipped templates and make it twig-compatible&lt;br /&gt;
# Embed the Twig template engine into Limesurvey&lt;br /&gt;
# Test your test template and the Twig template engine carefully&lt;br /&gt;
# Adjust further shipped Limesurvey templates&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You should know how a template engine and framework works. In addition to that HTML and CSS skills are required for adjusting the shipped Limesurvey templates.&lt;br /&gt;
You should also know about PHP because switching the template engine will require adjustments of the Limesurvey source code as well.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Easy to medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Marcel Minke ([[User:Mazi|Mazi]])&lt;br /&gt;
&lt;br /&gt;
==Remove jQuery UI and replace it with Bootstrap, harmonize GUI of different admin screens==&lt;br /&gt;
&lt;br /&gt;
The Limesurvey admin GUI currently uses a mixture of jQuery UI and Bootstrap code. That does not only make the related code difficult to maintain, it also creates a lot of overhead.&lt;br /&gt;
In addition to that, the different admin screens are not overall standardized and lack harmonization.&lt;br /&gt;
&lt;br /&gt;
This task aims at standardizing the ~20-25 different Limesurvey admin screens and cleaning up the underlying code for easier maintenance and faster loading times.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps&#039;&#039;&#039;&lt;br /&gt;
# Click through the different screen at the Limesurvey admin interface. Note which screens already look nice and which ones are not following the overall design standards.&lt;br /&gt;
# Take a look at the related source code and MVC views to see how the code for the views is structured and which libraries are used.&lt;br /&gt;
# Note where at the code jQuery UI is used.&lt;br /&gt;
# Test how to best remove the jQuery UI elements and what is needed to replace that code with Bootstrap features.&lt;br /&gt;
# Adjust the admin GUI code to make it fully Bootstrap compatible.&lt;br /&gt;
# Check all Limesurvey admin screens, standardize the layout/design and polish them where needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You should be familiar with jQuery UI and Bootstrap and known about HTML + CSS. A basic understanding of the MVC coding approach as well as some PHP coding skills are also helpful.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Easy to medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Marcel Minke ([[User:Mazi|Mazi]])&lt;br /&gt;
* Carsten Schmitz&lt;br /&gt;
* [[User:DenisChenu|Denis Chenu]]&lt;br /&gt;
&lt;br /&gt;
==Re-organize the Limesurvey Admin Interface for better Navigation Usability==&lt;br /&gt;
&lt;br /&gt;
When creating a survey at the Limesurvey admin interface the current page structure is:&lt;br /&gt;
survey list -&amp;gt; survey question groups -&amp;gt; questions (within the current group)&lt;br /&gt;
&lt;br /&gt;
That structure forces users to often navigate using the drop down and back/next buttons when dealing with larger surveys. Having a new menu on the left presenting a structured overview of all question groups with all their questions would help a lot to easily jump from question X to question Y.&lt;br /&gt;
That new overview should contain icons for:&lt;br /&gt;
* Deleting a question/question group&lt;br /&gt;
* Directly jumping to the survey question/question group edit mode&lt;br /&gt;
* Copying a survey question&lt;br /&gt;
* Adding a new question/question group at the appropriate survey section&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps&#039;&#039;&#039;&lt;br /&gt;
# Check how the current Limesurvey survey designer is structured&lt;br /&gt;
# Have a look at the different features available on the different levels (survey/question group/question)&lt;br /&gt;
# Think which features could additionally be added to the icon list above&lt;br /&gt;
# Check the related code for creating a full overview of question groups + questions&lt;br /&gt;
# Adjust the admin GUI to embed the additional overview on the left&lt;br /&gt;
# Create the code for the new overview and the functions presented by the different icons (most of that code is already there)&lt;br /&gt;
# Testing, testing, testing...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You should be familiar with the &amp;quot;[http://www.yiiframework.com/ Yii]&amp;quot; framework we are using for Limesurvey or at least other PHP frameworks. A good understanding of object-oriented PHP programmierung is required as well.&lt;br /&gt;
For adjusting the GUI moderate HTML + CSS skills are needed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Easy&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz&lt;br /&gt;
&lt;br /&gt;
==Make use of the SettingsWidget for core functions==&lt;br /&gt;
&lt;br /&gt;
Use and update (if needed) extension SettingsWidget for core Survey forms.&lt;br /&gt;
&lt;br /&gt;
Some forms to be updated:&lt;br /&gt;
&lt;br /&gt;
* Survey settings&lt;br /&gt;
* Personal settings&lt;br /&gt;
* Users settings (IN LS3 users&#039; settings are managed by the authentication plugin and already use SettingsWidget)&lt;br /&gt;
* Export settings&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, html, js and css&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Easy to moderate : some settings can be more diffcult&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Link on mantis&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://bugs.limesurvey.org/view.php?id=9523 SettingsWidget :renderHTML]&lt;br /&gt;
* [http://bugs.limesurvey.org/view.php?id=9501 SettingsWidget :renderDate / DateTime and Time]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:DenisChenu|Denis Chenu]]&lt;br /&gt;
&lt;br /&gt;
==Expression Manager JavaScript optimizations==&lt;br /&gt;
&lt;br /&gt;
Actually the Expression Manager in LimeSurvey uses inline JavaScript for relevance, updating classes and updating HTML. In its current state an administrator or extension developer can not use their own functions. The task is to update Expression manager inline JavaScript to use an JavaScript-only event on update expression manager javascript to call an actual function on this events.&lt;br /&gt;
&lt;br /&gt;
The second part of this task is to move inline Javascript to jQuery. In the old current system each input (when taking a survey) uses the onchange/onkeyup function to fire events. The idea is to remove these inline code and use only JavaScript/jQuery general code where possible.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some PHP to update Expression Manager class, deep jQuery/JavaScript knowledge. A jQuery plugin might be a great idea.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mantis&#039;&#039;&#039;&lt;br /&gt;
* [http://bugs.limesurvey.org/view.php?id=8725 Replace Expression manager Hard coded javascript by event]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:DenisChenu|Denis Chenu]]&lt;br /&gt;
&lt;br /&gt;
== Revamp database grids in LimeSurvey==&lt;br /&gt;
&lt;br /&gt;
We have various data table/lists in LimeSurvey - for example when listing surveys, tokens or responses.&lt;br /&gt;
With most of these lists we use jqGrid, some don&#039;t use any Javascript widget at all.&lt;br /&gt;
&lt;br /&gt;
All instances of data lists in LimeSurvey should be replaced with a proper Javascript grid (which has to be chosen yet) and a related widget in Yii. As smarter as you will choose the data grid and as better the related Yii widget is coded as easier you will be able to replace the existing jqGrid with your better version.&lt;br /&gt;
&lt;br /&gt;
All lists need to be customized in some way - for example with token editing we will need mass editing functions - for example you should be able to set all tokens to be unused, reset invitation/reminder date/time or similar. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Good PHP and JavaScript skills&lt;br /&gt;
*Experience with jQuery and Bootstrap, AJAX&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium difficulty - getting accustomed to the Yii 1.1 widget system and replacing the existing jqGrid functionality will be the difficult part.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[[User:C_schmitz|Carsten Schmitz]]&lt;br /&gt;
*Sam Mousa&lt;br /&gt;
&lt;br /&gt;
==Replace current CKEditor usage with TinyMCE==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey currently uses extensively CKEditor to let people edit their survey texts (question, answer options, general survey texts) and invitation emails.&lt;br /&gt;
However the CKEditor version we are using is outdated and some components are difficult to update due to CKeditor limitations. Also we use a customized CKeditor widget and a file browser widget that needs to be replaced with newer &amp;amp; better versions. &lt;br /&gt;
&lt;br /&gt;
We have concluded that TinyMCE will be the best replacement as the codebase is very stable and it offers a plugin interface.&lt;br /&gt;
&lt;br /&gt;
Your task would be to replace CKEditor instances with TinyMCE - also a widget for Yii should be written to ease any future implementation.&lt;br /&gt;
As mentioned before the functionality of the existing CKEditor extensions need to be ported as TinyMCE plugins.&lt;br /&gt;
&lt;br /&gt;
This task is linked with [[#Make_use_of_the_SettingsWidget_for_core_functions]]&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Good PHP and JavaScript skills&lt;br /&gt;
*Experience with jQuery and Bootstrap, AJAX&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium difficulty - getting accustomed to the Yii 1.1 widget system and replacing the existing CKEditor functionality will be the difficult part.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[[User:C_schmitz|Carsten Schmitz]]&lt;br /&gt;
*Sam Mousa&lt;br /&gt;
*[[User:DenisChenu|Denis Chenu]]&lt;br /&gt;
&lt;br /&gt;
==Idea template==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mentor(s)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
=Additional links=&lt;br /&gt;
==Official GSoC links==&lt;br /&gt;
*[https://www.google-melange.com/gsoc/homepage/google/gsoc2015 GSoC 2015 website]&lt;br /&gt;
*[https://www.google-melange.com/gsoc/events/google/gsoc2015 GSoC 2015 Timeline/Deadlines]&lt;br /&gt;
*[https://www.google-melange.com/gsoc/document/show/gsoc_program/google/gsoc2015/help_page GSoC 2015 FAQ page]&lt;br /&gt;
&lt;br /&gt;
==Limesurvey coding details==&lt;br /&gt;
*[https://manual.limesurvey.org/Coding_guidelines Limesurvey coding guidelines]&lt;br /&gt;
*[https://manual.limesurvey.org/Accessing_the_source_code Accessing the Limesurvey source code]&lt;br /&gt;
*[https://manual.limesurvey.org/Standard_for_Git_commit_messages Standard GIT commit messages]&lt;br /&gt;
*[https://manual.limesurvey.org/Directory_structure Limesurvey code base and directory structure]&lt;br /&gt;
*[https://manual.limesurvey.org/Yii Basic Yii framework information]&lt;br /&gt;
&lt;br /&gt;
==General information==&lt;br /&gt;
*[https://manual.limesurvey.org/GSoC_getting_started GSoC - Getting started]&lt;br /&gt;
*[https://manual.limesurvey.org/Writing_GSoC_application How to write your application]&lt;br /&gt;
*[https://manual.limesurvey.org/GSoC_Student_Application_Template Application template]&lt;br /&gt;
*[https://manual.limesurvey.org/GSoC_selection_criteria Our selection criteria]&lt;br /&gt;
*[https://manual.limesurvey.org/GSoC_FAQ GSoC FAQ]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSOC_2015]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=62281</id>
		<title>RemoteControl 2 API</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=62281"/>
		<updated>2014-09-02T10:58:16Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* How to use LSRC2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl 2 is a XML-RPC/JSON-RPC based web service available in LimeSurvey 2.0 or later. The old [RemoteControl] will not be available any longer in version 2.&lt;br /&gt;
&lt;br /&gt;
LSRC2 makes it possible for developers to control specific functionality of LimeSurvey from any other application, without being restricted to PHP as a programming language.&lt;br /&gt;
&lt;br /&gt;
The following features are planned:&lt;br /&gt;
* start a predefined survey (change titles and things)&lt;br /&gt;
* add predefined groups or questions&lt;br /&gt;
* activate the survey, restrict it to start and endtime&lt;br /&gt;
* make it closed,&lt;br /&gt;
* add participant data/tokens when you need them&lt;br /&gt;
* return the unused tokens to the main application&lt;br /&gt;
* get a fieldmap for a survey,&lt;br /&gt;
* invite or remind the participants of your survey&lt;br /&gt;
&lt;br /&gt;
...and much more&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* libXML installed&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC2==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC2 is disabled. In order to use LSRC2 you must first enable the service, and then adjust the settings to suit your needs. To enable LSRC2 login to the LimeSurvey administration, go to [[Global settings]], choose the tab &#039;Services&#039; and select one of the two RPC services (XML-RPC or JSON-RPC) service.&lt;br /&gt;
&lt;br /&gt;
== Security==&lt;br /&gt;
&lt;br /&gt;
LSRC2 uses the same security measures as the normal administration login. That means that the permission set of the used username and password is the same as if you would login in the administration with that user/password. Also LSRC2 is protected against brute-force password cracking - like the normal administration login.&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC2=&lt;br /&gt;
&lt;br /&gt;
The basic LSRC2 URL is: http://&amp;lt;your_domain&amp;gt;/&amp;lt;your_limesurvey_dir&amp;gt;/index.php/admin/remotecontrol&lt;br /&gt;
&lt;br /&gt;
LSRC2 fully complies to the [http://www.xmlrpc.com/ XML-RPC specification] and JSON-RPC version 1 specifications. We recommend in general to use JSON-RPC because it is well tested and has a much smaller footprint than XML-RPC.&lt;br /&gt;
&lt;br /&gt;
LSRC2 offers a lot of functions. Please check the automatically generated [http://api.limesurvey.org/classes/remotecontrol_handle.html API Documentation].&lt;br /&gt;
LSRC2 offers the following functions:&lt;br /&gt;
&lt;br /&gt;
==get_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can create a new XML/JSON-RPC session key. This is mandatory for all following LSRC2 function calls.&lt;br /&gt;
&lt;br /&gt;
Parameters: username (string), password (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: A session key (string)&lt;br /&gt;
*On failure:  for protocol-level errors (invalid format etc), an error message.  For invalid username and password, returns a null error and the result body contains a &#039;status&#039; name-value pair with the error message.&lt;br /&gt;
&lt;br /&gt;
==release_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can close a previously opened XML-RPC/JSON-RPC session.&lt;br /&gt;
&lt;br /&gt;
Parameters: session key (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*Always: &#039;OK&#039; (string)&lt;br /&gt;
&lt;br /&gt;
==get_site_settings==&lt;br /&gt;
&lt;br /&gt;
Function to provide with site settings only to administrators&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) The session key&lt;br /&gt;
&lt;br /&gt;
sSetttingName (string) -  Name of the setting to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Setting&lt;br /&gt;
*On failure: (string) Error message&lt;br /&gt;
&lt;br /&gt;
==add_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty survey with minimum details&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID     (int),    The wish id of the Survey to add&lt;br /&gt;
&lt;br /&gt;
sSurveyTitle     (string),  Title of the new Survey&lt;br /&gt;
&lt;br /&gt;
sSurveyLanguage    (string),  Default language of the Survey&lt;br /&gt;
&lt;br /&gt;
sformat     (string),  Question appearance format (S|G|A)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Faulty parameters&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to Delete a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string), Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int), The Survey to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: Status =&amp;gt;OK (array)&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==import_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a survey from lss,csv,xls or survey zip archive.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sImportData  (string) String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive&lt;br /&gt;
&lt;br /&gt;
sImportDataType     (string),    The format of the import file (lss,csv,xls or zip)&lt;br /&gt;
&lt;br /&gt;
sNewSurveyName     (string),  The optional new name of the survey (base language)&lt;br /&gt;
&lt;br /&gt;
DestSurveyID    (int), This is the new ID of the survey - if already used a random one will be taken instead&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import error&lt;br /&gt;
&lt;br /&gt;
==get_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|   sid||   savetimings||   allowprev||   tokenanswerspersistence||   showgroupinfo||   showwelcome&lt;br /&gt;
|-&lt;br /&gt;
|   owner_id||   template||   printanswers||   assessments||  shownoanswer ||   showprogress&lt;br /&gt;
|-&lt;br /&gt;
|   admin||   language||   ipaddr||   usecaptcha||   showqnumcode||   allowjumps&lt;br /&gt;
|-&lt;br /&gt;
|   active||   additional_languages ||   refurl||   usetokens||   bouncetime||   navigationdelay&lt;br /&gt;
|-&lt;br /&gt;
|   expires||   datestamp||   datecreated||   bounce_email||   bounceprocessing||   nokeyboard&lt;br /&gt;
|-&lt;br /&gt;
|   startdate||   usecookie||   publicstatistics||   attributedescriptions||   bounceaccounttype||   alloweditaftercompletion&lt;br /&gt;
|-&lt;br /&gt;
|   adminemail||   allowregister||   publicgraphs||   emailresponseto||   bounceaccounthost||   googleanalyticsstyle&lt;br /&gt;
|-&lt;br /&gt;
|   anonymized||   allowsave||   listpublic||   emailnotificationto||   bounceaccountpass||   googleanalyticsapikey&lt;br /&gt;
|-&lt;br /&gt;
|   faxto||   autonumber_start||   htmlemail||   tokenlength||   bounceaccountencryption||&lt;br /&gt;
|-&lt;br /&gt;
|format||   autoredirect||   sendconfirmation||   showxquestions||   bounceaccountuser||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An assosiative array with the name-value  pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of the change for each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
Properties available for changing are all those defined in get_survey_properties with the following exceptions&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|properties not allowed to be modified|| Properties not allowed to be modified when survey active&lt;br /&gt;
|-&lt;br /&gt;
|sid||anonymized&lt;br /&gt;
|-&lt;br /&gt;
|language||datestamp&lt;br /&gt;
|-&lt;br /&gt;
|additional_languages||savetimings&lt;br /&gt;
|-&lt;br /&gt;
|active||ipaddr&lt;br /&gt;
|-&lt;br /&gt;
|||refurl&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_surveys==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to list the ids and info of surveys belonging to a user.&lt;br /&gt;
&lt;br /&gt;
    * If user is admin he can get surveys of every user (parameter sUser) or all surveys (sUser=null)&lt;br /&gt;
&lt;br /&gt;
    * Else only the syrveys belonging to the user requesting will be shown.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sUser (string) -  The users surveys to list&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Survey&#039;s properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid user&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No surveys found&lt;br /&gt;
&lt;br /&gt;
Survey&#039;s properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|property||type&lt;br /&gt;
|-&lt;br /&gt;
|sid||integer&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_title||string&lt;br /&gt;
|-&lt;br /&gt;
|startdate||date&lt;br /&gt;
|-&lt;br /&gt;
|expires||date&lt;br /&gt;
|-&lt;br /&gt;
|active||y/n&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==activate_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine that launches a newly created survey (sets active -available for users)&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (array) The result of the activation&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Activation Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==export_statistics==&lt;br /&gt;
&lt;br /&gt;
RPC routine to export statistics of a survey to a user.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
docType (string) - Type of document to generate&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional language of the survey to use (if not set, default language is selected)&lt;br /&gt;
&lt;br /&gt;
graph (string) - Optional parameter to enable graphs (0|1)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==get_summary==&lt;br /&gt;
&lt;br /&gt;
RPC routine to get survey summary, regarding token usage and survey participation.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
sStatname (string) - The statistic to return or &#039;all&#039; to get an array of all statistics&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No available data&lt;br /&gt;
**No such property&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available statistics:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Survey stats||Token stats&lt;br /&gt;
|-&lt;br /&gt;
|completed_responses||token_count&lt;br /&gt;
|-&lt;br /&gt;
|incomplete_responses||token_invalid&lt;br /&gt;
|-&lt;br /&gt;
|full_responses||token_sent&lt;br /&gt;
|-&lt;br /&gt;
|||token_opted_out&lt;br /&gt;
|-&lt;br /&gt;
|||token_completed&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==add_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add a language to an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) - The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the new language to be added. Note: If the language is already in that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_survey_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a language of an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the language to be removed. Note: If the language is not part of that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Cannot remove base language&lt;br /&gt;
**Error&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid session key&lt;br /&gt;
&lt;br /&gt;
==get_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleSettings     (array) -  An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
slang (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_survey_id            ||    surveyls_url                  ||    surveyls_email_register_subj  ||    email_admin_notification_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_language             ||    surveyls_urldescription       ||    surveyls_email_register       ||    email_admin_notification&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_title                ||    surveyls_email_invite_subj    ||    surveyls_email_confirm_subj   ||    email_admin_responses_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_description          ||    surveyls_email_invite         ||    surveyls_email_confirm        ||    email_admin_responses&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_welcometext          || surveyls_email_remind_subj       ||    surveyls_dateformat           ||    surveyls_numberformat&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_endtext              ||    surveyls_email_remind         ||    surveyls_attributecaptions    ||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleData     (array) -  An assosiative array with the key-value pairs of properties to set. Invalid fieldnames or fields that may not be modified are ignored.&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Result for each parameter set&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Allowed Parameters:&lt;br /&gt;
&lt;br /&gt;
All those defined in get-language_properties except:&lt;br /&gt;
*surveyls_language&lt;br /&gt;
*surveyls_survey_id&lt;br /&gt;
&lt;br /&gt;
==add_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty group with minimum details.&lt;br /&gt;
&lt;br /&gt;
    * Used as a placeholder for importing questions.&lt;br /&gt;
&lt;br /&gt;
    * Returns the groupid of the created group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the surveythat the group will be added&lt;br /&gt;
&lt;br /&gt;
sGroupTitle     (string) -  Name of the new group&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) - Optional description of the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey that the group belongs&lt;br /&gt;
&lt;br /&gt;
sGroupID    (int) -  Id of the group to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the deleted group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid Group ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Group deletion failed&lt;br /&gt;
&lt;br /&gt;
==import_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a group - imports lsg,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey that the group will belong&lt;br /&gt;
&lt;br /&gt;
sImportData     (string) -  String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) -The format of the importfile in the stream (lsg|csv)&lt;br /&gt;
&lt;br /&gt;
sNewGroupName (string) - Optional new name for the group&lt;br /&gt;
&lt;br /&gt;
sNewGroupDescription (string) - Optional new description for the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Error: Invalid LimeSurvey group structure XML&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import Error&lt;br /&gt;
&lt;br /&gt;
==get_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to get properties of&lt;br /&gt;
&lt;br /&gt;
aGroupSettings     (array) -  Array containing the properties to request.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||description&lt;br /&gt;
|-&lt;br /&gt;
|sid||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to set properties to&lt;br /&gt;
&lt;br /&gt;
aGroupData     (array) -  Assosiative Array containing key-value pairs of the properties to set.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of each set action&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Group with dependencies - Order cannot be changed&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|||description&lt;br /&gt;
|-&lt;br /&gt;
|||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_groups==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of groups belonging to survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey to get groups of&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the groups&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**No groups found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==list_users==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of users&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of users&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No users found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission (super admin is required)&lt;br /&gt;
&lt;br /&gt;
==delete_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int)id of the deleted Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
** Invalid question ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Cannot delete Question. Others rely on this question&lt;br /&gt;
**Error&lt;br /&gt;
&lt;br /&gt;
==import_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a question - imports lsq,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
iGroupID (int) - Id of the group that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
sImportData (string) - String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sImportDataType (string)  - Format of the input stream (lsq,csv)&lt;br /&gt;
&lt;br /&gt;
sMandatory (string) - Optional Mandatory question option (default to No)&lt;br /&gt;
&lt;br /&gt;
sNewQuestionTitle (string) - Optional new title for the question&lt;br /&gt;
&lt;br /&gt;
sNewqQuestion (string) - An optional new question&lt;br /&gt;
&lt;br /&gt;
sNewQuestionHelp (string) - An optional new question help text&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) Id of the new Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid group ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Invalid LimeSurvey question structure XML&lt;br /&gt;
&lt;br /&gt;
==get_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionSettings (array) The properties to get&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||type||help||language&lt;br /&gt;
|-&lt;br /&gt;
|parent_qid||title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|sid||question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|gid||preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|subquestions||attributes||attributes_lang||answeroptions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set question properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) - Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionData (array)  - An array with the particular fieldnames as keys and their values to set on that particular question&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The resilt of the set of each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Questions with dependencies - Order cannot be changed&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|help|| ||&lt;br /&gt;
|-&lt;br /&gt;
|title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_questions==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of questions of a survey/group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
iGroupID  (int) - Id of the group to get questions of&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the questions&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Missmatch in surveyid and groupid&lt;br /&gt;
**No questions found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
Activate tokens&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
surveyid (string) The survey ID&lt;br /&gt;
&lt;br /&gt;
additional_attributes (array of integers) Any additional attribute fields to create. Just give the attribute IDs&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) status OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
&lt;br /&gt;
==add_participants==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new entries to your token table. You can also set if for these new entries a token key is automatically created. Please note that this function does not check for duplicate content in any of the fields, except for token keys created by the function itself.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sessionkey (string) - The session key&lt;br /&gt;
*surveyID (string) - The survey id&lt;br /&gt;
*participantData (array) -  2-dimensional array/structure containing your participants data&lt;br /&gt;
*createTokenKey (boolean) - Set this to true if you want a token key create automatically for each entry - if your participant data included a [token] field it will be overwritten&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success:  participant data (struct) -  structure containing your participants data plus the token ID and (if applicable) the new token&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
&lt;br /&gt;
JSON-RPC example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;add_participants&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;sessionkey&amp;quot;:&amp;quot;73e8rx864rnxmk64gp67bah44u2igivm&amp;quot;,&amp;quot;surveyID&amp;quot;:&amp;quot;668138&amp;quot;,&amp;quot;participantData&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;}]}}&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;result&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;,&amp;quot;tid&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;token&amp;quot;:&amp;quot;auc82gar58dpcg6&amp;quot;}],&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==delete_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete multiple participants of a Survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
aTokenIDs  (array) - IId of the tokens/participants to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of deletion status for each participant&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
&lt;br /&gt;
==get_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return settings of a token/participant of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to get token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to check&lt;br /&gt;
&lt;br /&gt;
aTokenProperties (array) - The properties to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of requested values&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|tid||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey participant/token&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to set token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to alter&lt;br /&gt;
&lt;br /&gt;
aTokenData (array) - Key - value pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of results of changing properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_participants==&lt;br /&gt;
&lt;br /&gt;
RPC routine to return the IDs and info of token/participants of a survey.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
   sSessionKey (string) -  Auth credentials&lt;br /&gt;
   iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
   iStart (int) - Start id of the token list&lt;br /&gt;
   iLimit (int) - Number of participants to return&lt;br /&gt;
   bUnused (bool) - If you want unused tokensm, set true&lt;br /&gt;
   aAttributes(bool|array) An array of extended attributes that can be requested, besides the default ones (default value to false)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of Participants info&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No Tokens found&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
If you provide the iLimit parameter it is required to provide the iStart parameter.&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
RPC routine to to initialise the survey&#039;s collection of tokens where new participant tokens may be later added&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
&lt;br /&gt;
aAttributeFields (array) - An array of integer describing any additional attribute fields&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Status OK&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Token table could not be created&lt;br /&gt;
&lt;br /&gt;
==invite_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to invite participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==remind_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to send reminder for participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
iMinDaysBetween (int) - Optional parameter days from last reminder&lt;br /&gt;
&lt;br /&gt;
iMaxReminders (int) - Optional parameter Maximum reminders count&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==add_response==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=php&amp;gt;&lt;br /&gt;
public function add_response($sSessionKey, $iSurveyID, $aResponseData)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add a response to the survey responses collection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Return&#039;&#039;&#039;: int|array On success: Returns the id of the inserted survey response. On failure array with error information&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $sSessionKey || string || Auth credentials&lt;br /&gt;
|-&lt;br /&gt;
| $iSurveyID || int || Id of the Survey&lt;br /&gt;
|-&lt;br /&gt;
| $aResponseData || array || The actual response&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==export_responses==&lt;br /&gt;
&amp;lt;source lang=php&amp;gt;&lt;br /&gt;
public function export_responses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null,&lt;br /&gt;
   $sCompletionStatus=&#039;all&#039;, $sHeadingType=&#039;code&#039;, $sResponseType=&#039;short&#039;, $iFromResponseID=null, $iToResponseID=null, $aFields=null)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RPC Routine to export responses. Returns the requested file as base64 encoded string. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Return&#039;&#039;&#039;: array|string On success: Requested file as base 64-encoded string. On failure array with error information&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: If you have huge response sets try only to request a certain number of records at a time otherwise the server may run out of memory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: Starting with version 2.0.5 the $iFromResponseID and $iToResponseID parameters refer to the minimum and maximum id&#039;s; prior to this version the parameters refer to the record&#039;s offset in the table&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $sSessionKey || string || Auth credentials&lt;br /&gt;
|-&lt;br /&gt;
| $iSurveyID || int || Id of the Survey&lt;br /&gt;
|-&lt;br /&gt;
| $sDocumentType || string || pdf,csv,xls,doc,json&lt;br /&gt;
|-&lt;br /&gt;
| $sLanguageCode || string || The language to be used&lt;br /&gt;
|-&lt;br /&gt;
| $sCompletionStatus || string || Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; - defaults to &#039;all&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $sHeadingType || string || &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039; Optional defaults to &#039;code&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $sResponseType || string || &#039;short&#039; or &#039;long&#039; Optional defaults to &#039;short&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $iFromResponseID || integer || Optional&lt;br /&gt;
|-&lt;br /&gt;
| $iToResponseID || integer || Optional&lt;br /&gt;
|-&lt;br /&gt;
| $aFields|| array || Optional Selected fields&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==export_responses_by_token==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=php&amp;gt;&lt;br /&gt;
public function export_responses_by_token($sSessionKey, $iSurveyID, $sDocumentType, $sToken, \&lt;br /&gt;
   $sLanguageCode=null, $sCompletionStatus=&#039;all&#039;, $sHeadingType=&#039;code&#039;, $sResponseType=&#039;short&#039;, $aFields=null)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Export responses data of specific token. Returns the requested file as base64 encoded string.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Return&#039;&#039;&#039;: array|string On success: Requested file as base 64-encoded string. On failure array with error information&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $sSessionKey || string || Auth credentials&lt;br /&gt;
|-&lt;br /&gt;
| $iSurveyID || int || Id of the Survey&lt;br /&gt;
|-&lt;br /&gt;
| $sDocumentType || string || pdf,csv,xls,doc,json&lt;br /&gt;
|-&lt;br /&gt;
| $sToken || string || The token for which responses needed&lt;br /&gt;
|-&lt;br /&gt;
| $sLanguageCode || string || The language to be used&lt;br /&gt;
|-&lt;br /&gt;
| $sCompletionStatus || string || Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; - defaults to &#039;all&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $sHeadingType || string || &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039; Optional defaults to &#039;code&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $sResponseType || string || &#039;short&#039; or &#039;long&#039; Optional defaults to &#039;short&#039;&lt;br /&gt;
|-&lt;br /&gt;
| $aFields|| array || Optional Selected fields&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
To test you will have to activate JSON-RPC in global settings. To run a simple self-test go to&lt;br /&gt;
&lt;br /&gt;
http://path_to_your_limesurvey_installation/index.php/admin/remotecontrol/test . This will import the example survey, do various things with it and delete it afterwards.&lt;br /&gt;
&lt;br /&gt;
The test assumes that you still are using the standard user &#039;admin&#039; with password &#039;password&#039;.&lt;br /&gt;
&lt;br /&gt;
The client function for this test can be found in /application/controller/admin/remotecontrol.php and the particular function is called test().&lt;br /&gt;
&lt;br /&gt;
=Ruby Example=&lt;br /&gt;
&lt;br /&gt;
There are some cool things that you can use with the RemoteControl2 API and this is an example of a production use of this. Basically, I, (kobaltz in the forums) have a third party site that I built that controls the users and level of access of each company and their users. From within this site, I have a daemon that will generate participants of the appropriate survey twice an hour. This will use LimeSurvey&#039;s Mail Function to send the end user a link to the survey. Administrators of the third party site will get statistical data of the end user filling out the survey as well as a link to review the surveys completed using the same template that the user used to fill it out. Reducing duplicate entry of data made possible with the RemoteControl2 API.&lt;br /&gt;
&lt;br /&gt;
==Load Requirements and Declare Values==&lt;br /&gt;
You will first need to require the dependencies needed to establish communication with the API. Also, note that there is a username and password field that requires to be stored in plain text. I have a separate API User within my LimeSurvey to handle these calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env ruby&lt;br /&gt;
&lt;br /&gt;
require &#039;net/https&#039;&lt;br /&gt;
require &#039;uri&#039;&lt;br /&gt;
require &#039;json&#039;&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;api_user&amp;quot;&lt;br /&gt;
password = &amp;quot;api_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Module==&lt;br /&gt;
&lt;br /&gt;
The below code is used to define the module LimeSurvey. Within this module is an API class. We will use this to create an instance of this module and then call on the API call wherever needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
module LimeSurvey&lt;br /&gt;
  class API&lt;br /&gt;
    def initialize(service_url)&lt;br /&gt;
      @uri = URI.parse(service_url)&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def method_missing(name, *args)&lt;br /&gt;
      post_body = { &#039;method&#039; =&amp;gt; name, &#039;params&#039; =&amp;gt; args, &#039;id&#039; =&amp;gt; &#039;jsonrpc&#039; }.to_json&lt;br /&gt;
      resp = JSON.parse( http_post_request(post_body) )&lt;br /&gt;
      raise JSONRPCError, resp[&#039;error&#039;] if resp[&#039;error&#039;]&lt;br /&gt;
      resp[&#039;result&#039;]&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def http_post_request(post_body)&lt;br /&gt;
      http    = Net::HTTP.new(@uri.host, @uri.port)&lt;br /&gt;
      request = Net::HTTP::Post.new(@uri.request_uri)&lt;br /&gt;
      request.content_type = &#039;application/json&#039;&lt;br /&gt;
      request.body = post_body&lt;br /&gt;
      http.request(request).body&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  class JSONRPCError &amp;lt; RuntimeError; end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==API Call==&lt;br /&gt;
This code is used to create the instance of the LimeSurvey::API module and class. You will want to change the URL to that of your RemoteControl2 URL.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
survey = LimeSurvey::API.new(&#039;http://localhost/limesurvey/index.php?r=admin/remotecontrol&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example takes the above code and puts it into play. I create a new session with the RemoteControl2 API and store the session in the variable session_key. You will want to change the ID numbers to the appropriate Survey ID in the examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
system(&amp;quot;cls&amp;quot;)&lt;br /&gt;
session_key = survey.get_session_key(username,password)&lt;br /&gt;
puts &amp;quot;Session Key: #{session_key}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
response = survey.get_survey_properties(session_key, &amp;quot;863224&amp;quot;, [&amp;quot;owner_id&amp;quot;])&lt;br /&gt;
puts &amp;quot;Properties:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.list_surveys(sSessionKey: session_key, sUser: &amp;quot;dkimura&amp;quot;)&lt;br /&gt;
puts &amp;quot;Survey List:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.add_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;,&lt;br /&gt;
    [email:&amp;quot;james.bond@example.com&amp;quot;,lastname:&amp;quot;Bond&amp;quot;,firstname:&amp;quot;James&amp;quot;]&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Add Participant:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.invite_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Invite Participant:  #{response}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.release_session_key(session_key)&lt;br /&gt;
puts &amp;quot;Release Session: #{response}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Grabs a Survey&#039;s list of participants and parses through them&lt;br /&gt;
# The response is in an array format.&lt;br /&gt;
# Each response within the array is in JSON format (How the survey is configured with RemoteControl2)&lt;br /&gt;
# Convert the participant response to JSON and then display the token.&lt;br /&gt;
response = survey.list_participants(session_key, &amp;quot;593987&amp;quot;)&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
response_participants = []&lt;br /&gt;
response.each do |part|&lt;br /&gt;
	resps = JSON.parse(part.to_json)&lt;br /&gt;
	puts &amp;quot;Participant: #{resps[&#039;token&#039;]}&amp;quot;&lt;br /&gt;
	puts &amp;quot;\n&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Example Return==&lt;br /&gt;
&lt;br /&gt;
From the above example, here is the return that I receive. Some of the items are returned as a hash and some items returned as an array of hashes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
Session Key: piadscbc94vyanxwkdy8f3xii4av2b2w&lt;br /&gt;
&lt;br /&gt;
Properties:  {&amp;quot;owner_id&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Survey List:  [{&amp;quot;sid&amp;quot;=&amp;gt;&amp;quot;863224&amp;quot;, &amp;quot;surveyls_title&amp;quot;=&amp;gt;&amp;quot;Statement of Work v0.12&amp;quot;, &amp;quot;startdate&amp;quot;=&amp;gt;nil, &amp;quot;expires&amp;quot;=&amp;gt;nil, &amp;quot;active&amp;quot;=&amp;gt;&amp;quot;Y&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Add Participant:  [{&amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;lastname&amp;quot;=&amp;gt;&amp;quot;Bond&amp;quot;, &amp;quot;firstname&amp;quot;=&amp;gt;&amp;quot;James&amp;quot;, &amp;quot;tid&amp;quot;=&amp;gt;&amp;quot;7&amp;quot;, &amp;quot;token&amp;quot;=&amp;gt;&amp;quot;pt5ztzxndibkz4j&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Invite Participant:  {&amp;quot;7&amp;quot;=&amp;gt;{&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;James Bond&amp;quot;, &amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;OK&amp;quot;}, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;0 left to send&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Participant: p7m5zmh38wi9mbk&lt;br /&gt;
Participant: nssu6ne6ii9wva9&lt;br /&gt;
Participant: r9kr2sahn7tfsv9&lt;br /&gt;
Participant: a28ci2z9m7ynfgg&lt;br /&gt;
Participant: 4ytt5axg9ebdazh&lt;br /&gt;
Participant: wswjv2t5v7vh4p7&lt;br /&gt;
Participant: fqvxeckgh6vgy3e&lt;br /&gt;
Participant: n5p2vfnh7dwx699&lt;br /&gt;
Participant: ycsmigup9pagm6z&lt;br /&gt;
Participant: 33ztf4g74k2kvx4&lt;br /&gt;
&lt;br /&gt;
Release Session: OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PHP Example=&lt;br /&gt;
&lt;br /&gt;
To include JSON-RPC in your application, you can write an application using the light-weight jsonRPCClient from the [https://github.com/weberhofer/jsonrpcphp jsonrpcphp Github repository].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once &#039;jsonRPCClient.php&#039;;&lt;br /&gt;
define( &#039;LS_BASEURL&#039;, &#039;http://localhost/limesurvey/&#039;);  // adjust this one to your actual LimeSurvey URL&lt;br /&gt;
define( &#039;LS_USER&#039;, &#039;rpcuser&#039; );&lt;br /&gt;
define( &#039;LS_PASSWORD&#039;, &#039;mypassword&#039; );&lt;br /&gt;
&lt;br /&gt;
// the survey to process&lt;br /&gt;
$survey_id=374699;&lt;br /&gt;
&lt;br /&gt;
// instanciate a new client&lt;br /&gt;
$myJSONRPCClient = new jsonRPCClient( LS_BASEURL.&#039;/admin/remotecontrol&#039; );&lt;br /&gt;
&lt;br /&gt;
// receive session key&lt;br /&gt;
$sessionKey= $myJSONRPCClient-&amp;gt;get_session_key( LS_USER, LS_PASSWORD );&lt;br /&gt;
&lt;br /&gt;
// receive all ids and info of groups belonging to a given survey&lt;br /&gt;
$groups = $myJSONRPCClient-&amp;gt;list_groups( $sessionKey, $survey_id );&lt;br /&gt;
print_r($groups, null );&lt;br /&gt;
&lt;br /&gt;
// release the session key&lt;br /&gt;
$myJSONRPCClient-&amp;gt;release_session_key( $sessionKey );&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JAVA example=&lt;br /&gt;
To decode and code your json calls you can use the library gson as you can see in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.UnsupportedEncodingException;&lt;br /&gt;
&lt;br /&gt;
import org.apache.http.HttpEntity;&lt;br /&gt;
import org.apache.http.HttpResponse;&lt;br /&gt;
import org.apache.http.client.methods.HttpPost;&lt;br /&gt;
import org.apache.http.entity.StringEntity;&lt;br /&gt;
import org.apache.http.impl.client.DefaultHttpClient;&lt;br /&gt;
import org.apache.http.util.EntityUtils;&lt;br /&gt;
&lt;br /&gt;
import com.google.gson.JsonElement;&lt;br /&gt;
import com.google.gson.JsonObject;&lt;br /&gt;
import com.google.gson.JsonParser;&lt;br /&gt;
&lt;br /&gt;
public class TestHttpClient {&lt;br /&gt;
	&lt;br /&gt;
    public static String parse(String jsonLine) {&lt;br /&gt;
	 JsonElement jelement = new JsonParser().parse(jsonLine);&lt;br /&gt;
	 JsonObject  jobject = jelement.getAsJsonObject();&lt;br /&gt;
	 String result = jobject.get(&amp;quot;result&amp;quot;).toString();&lt;br /&gt;
	 return result;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
    public static void main(String[] args) throws UnsupportedEncodingException {&lt;br /&gt;
      DefaultHttpClient client = new DefaultHttpClient();          &lt;br /&gt;
         &lt;br /&gt;
      HttpPost post = new HttpPost(&amp;quot;http://PATH_OF_YOUR_SERVER/index.php/admin/remotecontrol&amp;quot;);&lt;br /&gt;
      post.setHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
      post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;get_session_key\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;username\&amp;quot;: \&amp;quot;YOUR_USERNAME\&amp;quot;, \&amp;quot;password\&amp;quot;: \&amp;quot;YOUR_PASSWORD\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
      try {&lt;br /&gt;
        HttpResponse response = client.execute(post);&lt;br /&gt;
        if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
            HttpEntity entity = response.getEntity();&lt;br /&gt;
            String sessionKey = parse(EntityUtils.toString(entity));&lt;br /&gt;
            post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;list_groups\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;sSessionKey \&amp;quot;: &amp;quot;+sessionKey+&amp;quot;, \&amp;quot;iSurveyID \&amp;quot;: \&amp;quot;ID_SURVEY\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
            response = client.execute(post);&lt;br /&gt;
            if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
                entity = response.getEntity();&lt;br /&gt;
                System.out.println(EntityUtils.toString(entity));&lt;br /&gt;
                }&lt;br /&gt;
           }&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } catch (IOException e) {&lt;br /&gt;
        e.printStackTrace();&lt;br /&gt;
      }&lt;br /&gt;
    }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Python  example=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
import json&lt;br /&gt;
import sys&lt;br /&gt;
# There is an generic json-rpc implemantation in Python but it dose not work for me in this case so I worte Some functions &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
def get_session_key():&lt;br /&gt;
    req = urllib2.Request(url=&#039;http://myurl/index.php/admin/remotecontrol&#039;,\&lt;br /&gt;
                          data=&#039;{\&amp;quot;method\&amp;quot;:\&amp;quot;get_session_key\&amp;quot;,\&amp;quot;params\&amp;quot;:{\&amp;quot;username\&amp;quot;:\&amp;quot;admin\&amp;quot;,\&amp;quot;password\&amp;quot;:\&amp;quot;mypassword\&amp;quot;},\&amp;quot;id\&amp;quot;:1}&#039;)&lt;br /&gt;
    req.add_header(&#039;content-type&#039;, &#039;application/json&#039;)&lt;br /&gt;
    req.add_header(&#039;connection&#039;, &#039;Keep-Alive&#039;)&lt;br /&gt;
    try:&lt;br /&gt;
        f = urllib2.urlopen(req)&lt;br /&gt;
        myretun = f.read()&lt;br /&gt;
        #print myretun&lt;br /&gt;
        j=json.loads(myretun)&lt;br /&gt;
        return j[&#039;result&#039;]&lt;br /&gt;
    except :&lt;br /&gt;
        e = sys.exc_info()[0]&lt;br /&gt;
        print ( &amp;quot;&amp;lt;p&amp;gt;Error: %s&amp;lt;/p&amp;gt;&amp;quot; % e )&lt;br /&gt;
		&lt;br /&gt;
def get_question_properties(skey,QuestionID):&lt;br /&gt;
    req = urllib2.Request(url=&#039;http://myurl/index.php/admin/remotecontrol&#039;,\&lt;br /&gt;
                          data=&#039;{\&amp;quot;method\&amp;quot;:\&amp;quot;get_question_properties\&amp;quot;,\&amp;quot;params\&amp;quot;:{\&amp;quot;sSessionKey\&amp;quot;:\&amp;quot;&#039;+skey+&#039;\&amp;quot;,\&amp;quot;iQuestionID\&amp;quot;:&#039;+QuestionID+&#039;,\&lt;br /&gt;
\&amp;quot;aQuestionSettings\&amp;quot;:[\&amp;quot;gid\&amp;quot;,\&amp;quot;type\&amp;quot;,\&amp;quot;help\&amp;quot;,\&amp;quot;language\&amp;quot;,\&amp;quot;sid\&amp;quot;,\&amp;quot;question_order\&amp;quot;,\&amp;quot;question\&amp;quot;,\&amp;quot;subquestions\&amp;quot;]},\&amp;quot;id\&amp;quot;: 1}&#039;)&lt;br /&gt;
&lt;br /&gt;
    req.add_header(&#039;content-type&#039;, &#039;application/json&#039;)&lt;br /&gt;
    req.add_header(&#039;connection&#039;, &#039;Keep-Alive&#039;)&lt;br /&gt;
    try:&lt;br /&gt;
        f = urllib2.urlopen(req)&lt;br /&gt;
        myretun = f.read()&lt;br /&gt;
        #print myretun&lt;br /&gt;
        j=json.loads(myretun)&lt;br /&gt;
        return j[&#039;result&#039;]&lt;br /&gt;
    except :&lt;br /&gt;
        e = sys.exc_info()[0]&lt;br /&gt;
        print ( &amp;quot;&amp;lt;p&amp;gt;Error: %s&amp;lt;/p&amp;gt;&amp;quot; % e )&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
def release_session_key(relkey):&lt;br /&gt;
    req = urllib2.Request(url=&#039;http://myurl/index.php/admin/remotecontrol&#039;,\&lt;br /&gt;
                          data=&#039;{\&amp;quot;method\&amp;quot;:\&amp;quot;release_session_key\&amp;quot;,\&amp;quot;params\&amp;quot;:{\&amp;quot;sSessionKey\&amp;quot;:\&amp;quot;&#039;+relkey+&#039;\&amp;quot;},\&amp;quot;id\&amp;quot;:1}&#039;)&lt;br /&gt;
    req.add_header(&#039;content-type&#039;, &#039;application/json&#039;)&lt;br /&gt;
    req.add_header(&#039;connection&#039;, &#039;Keep-Alive&#039;)&lt;br /&gt;
    try:&lt;br /&gt;
        f = urllib2.urlopen(req)&lt;br /&gt;
        myretun = f.read()&lt;br /&gt;
        #print myretun&lt;br /&gt;
        j=json.loads(myretun)&lt;br /&gt;
        return j[&#039;result&#039;]&lt;br /&gt;
    except :&lt;br /&gt;
        e = sys.exc_info()[0]&lt;br /&gt;
        print ( &amp;quot;&amp;lt;p&amp;gt;Error: %s&amp;lt;/p&amp;gt;&amp;quot; % e )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def export_responses2(skey,sid):&lt;br /&gt;
    req = urllib2.Request(url=&#039;http://myurl/index.php/admin/remotecontrol&#039;,\&lt;br /&gt;
                          data=&#039;{\&amp;quot;method\&amp;quot;:\&amp;quot;export_responses\&amp;quot;,\&amp;quot;params\&amp;quot;:{\&amp;quot;sSessionKey\&amp;quot;:\&amp;quot;&#039;+skey+&#039;\&amp;quot;,\&amp;quot;iSurveyID\&amp;quot;:\&amp;quot;&#039;+sid+&#039;\&amp;quot;,\&lt;br /&gt;
\&amp;quot;DocumentType\&amp;quot;:\&amp;quot;csv\&amp;quot;,\&amp;quot;sLanguageCode\&amp;quot;:\&amp;quot;de\&amp;quot;,\&amp;quot;sHeadingType\&amp;quot;:\&amp;quot;full\&amp;quot;},\&lt;br /&gt;
&amp;quot;id\&amp;quot;: 1}&#039;)&lt;br /&gt;
    req.add_header(&#039;content-type&#039;, &#039;application/json&#039;)&lt;br /&gt;
    req.add_header(&#039;connection&#039;, &#039;Keep-Alive&#039;)&lt;br /&gt;
    try:&lt;br /&gt;
        f = urllib2.urlopen(req)&lt;br /&gt;
        myretun = f.read()&lt;br /&gt;
        #print myretun&lt;br /&gt;
        j=json.loads(myretun)&lt;br /&gt;
        return j[&#039;result&#039;]&lt;br /&gt;
    except :&lt;br /&gt;
        e = sys.exc_info()[0]&lt;br /&gt;
        print ( &amp;quot;&amp;lt;p&amp;gt;Error: %s&amp;lt;/p&amp;gt;&amp;quot; % e )		&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
mykey=get_session_key()&lt;br /&gt;
print export_responses2(mykey,&#039;566237&#039;).decode(&#039;base64&#039;)&lt;br /&gt;
get_question_properties(mykey,&#039;574&#039;)&lt;br /&gt;
print release_session_key(mykey)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JSON-RPC notes=&lt;br /&gt;
&lt;br /&gt;
The content-type of the HTTP request must be application/json.  Most formatting errors or a failure to set the content-type header will result in a null response from the server (not a JSON response).  Below is an example of a valid request and response pair.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
 HTTP headers:&lt;br /&gt;
&lt;br /&gt;
   content-type=application/json&lt;br /&gt;
&lt;br /&gt;
   connection=Keep-Alive&lt;br /&gt;
&lt;br /&gt;
   host=mylimesurveyhost.com&lt;br /&gt;
&lt;br /&gt;
   content-length=65&lt;br /&gt;
&lt;br /&gt;
   user-agent=Apache-HttpClient/4.2.2 (java 1.5)&lt;br /&gt;
&lt;br /&gt;
 Post body:&lt;br /&gt;
&lt;br /&gt;
   {&amp;quot;method&amp;quot;:&amp;quot;get_session_key&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;username&amp;quot;:&amp;quot;admin&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;mypassword&amp;quot;},&amp;quot;id&amp;quot;:1}&lt;br /&gt;
&lt;br /&gt;
Response body:&lt;br /&gt;
&lt;br /&gt;
 {&amp;quot;id&amp;quot;:1,&amp;quot;result&amp;quot;:&amp;quot;6htqat38fyr4v7iu72nqgv7xgavkvfcz&amp;quot;,&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Cron_(command)&amp;diff=61290</id>
		<title>Cron (command)</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Cron_(command)&amp;diff=61290"/>
		<updated>2014-04-05T15:38:18Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FeatureStarting|2.06}} &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;When&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This event happen when server admin set a crontab instruction.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to use&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This event need to be call with php cli instruction.&lt;br /&gt;
&amp;lt;code&amp;gt;php yourlimesurveydir/application/commands/console.php plugin cron --interval=X&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Input&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The event receives the following information:&lt;br /&gt;
&#039;&#039;interval&#039;&#039; the interval parameter, set this to the interval (in minutes) you run this cron job. Plugins can use this information to self-limit their execution time, or get an idea of when the event will fire next.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugins events]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Testing&amp;diff=59320</id>
		<title>Testing</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Testing&amp;diff=59320"/>
		<updated>2013-11-05T13:13:41Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: Unit testing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Limesurvey 2.05 contains unit tests using PHPUnit.&lt;br /&gt;
&lt;br /&gt;
To run the tests go to the directory application/tests and run phpunit --bootstrap bootstrap.php unit/&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=56804</id>
		<title>RemoteControl 2 API</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=56804"/>
		<updated>2013-09-13T07:03:56Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* How to use LSRC2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl 2 is a XML-RPC/JSON-RPC based web service available in LimeSurvey 2.0 or later. The old [RemoteControl] will not be available any longer in version 2.&lt;br /&gt;
&lt;br /&gt;
LSRC2 makes it possible for developers to control specific functionality of LimeSurvey from any other application, without being restricted to PHP as a programming language.&lt;br /&gt;
&lt;br /&gt;
The following features are planned:&lt;br /&gt;
* start a predefined survey (change titles and things)&lt;br /&gt;
* add predefined groups or questions&lt;br /&gt;
* activate the survey, restrict it to start and endtime&lt;br /&gt;
* make it closed,&lt;br /&gt;
* add participant data/tokens when you need them&lt;br /&gt;
* return the unused tokens to the main application&lt;br /&gt;
* get a fieldmap for a survey,&lt;br /&gt;
* invite or remind the participants of your survey&lt;br /&gt;
&lt;br /&gt;
...and much more&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* libXML installed&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC2==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC2 is disabled. In order to use LSRC2 you must first enable the service, and then adjust the settings to suit your needs. To enable LSRC2 login to the LimeSurvey administration, go to [[Global settings]], choose the tab &#039;Services&#039; and select one of the two RPC services (XML-RPC or JSON-RPC) service.&lt;br /&gt;
&lt;br /&gt;
== Security==&lt;br /&gt;
&lt;br /&gt;
LSRC2 uses the same security measures as the normal administration login. That means that the permission set of the used username and password is the same as if you would login in the administration with that user/password. Also LSRC2 is protected against brute-force password cracking - like the normal administration login.&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC2=&lt;br /&gt;
&lt;br /&gt;
The basic LSRC2 URL is: http://&amp;lt;your_domain&amp;gt;/&amp;lt;your_limesurvey_dir&amp;gt;/index.php/admin/remotecontrol&lt;br /&gt;
&lt;br /&gt;
LSRC2 fully complies to the [http://www.xmlrpc.com/ XML-RPC specification] and JSON-RPC version 1 specifications. We recommend in general to use JSON-RPC because it is well tested and has a much smaller footprint than XML-RPC.&lt;br /&gt;
&lt;br /&gt;
LSRC2 offers the following functions:&lt;br /&gt;
&lt;br /&gt;
==get_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can create a new XML-RPC session key. This is mandatory for all following LSRC2 function calls.&lt;br /&gt;
&lt;br /&gt;
Parameters: username (string), password (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: A session key (string)&lt;br /&gt;
*On failure:  for protocol-level errors (invalid format etc), an error message.  For invalid username and password, returns a null error and the result body contains a &#039;status&#039; name-value pair with the error message.&lt;br /&gt;
&lt;br /&gt;
==release_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can close a previously opened XML-RPC/JSON-RPC session.&lt;br /&gt;
&lt;br /&gt;
Parameters: session key (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*Always: &#039;OK&#039; (string)&lt;br /&gt;
&lt;br /&gt;
==get_site_settings==&lt;br /&gt;
&lt;br /&gt;
Function to provide with site settings only to administrators&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) The session key&lt;br /&gt;
&lt;br /&gt;
sSetttingName (string) -  Name of the setting to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Setting&lt;br /&gt;
*On failure: (string) Error message&lt;br /&gt;
&lt;br /&gt;
==add_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty survey with minimum details&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID     (int),    The wish id of the Survey to add&lt;br /&gt;
&lt;br /&gt;
sSurveyTitle     (string),  Title of the new Survey&lt;br /&gt;
&lt;br /&gt;
sSurveyLanguage    (string),  Default language of the Survey&lt;br /&gt;
&lt;br /&gt;
sformat     (string),  Question appearance format (S|G|A)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Faulty parameters&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to Delete a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string), Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int), The Survey to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: Status =&amp;gt;OK (array)&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==import_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a survey from lss,csv,xls or survey zip archive.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sImportData  (string) String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive&lt;br /&gt;
&lt;br /&gt;
sImportDataType     (string),    The format of the import file (lss,csv,xls or zip)&lt;br /&gt;
&lt;br /&gt;
sNewSurveyName     (string),  The optional new name of the survey (base language)&lt;br /&gt;
&lt;br /&gt;
DestSurveyID    (int), This is the new ID of the survey - if already used a random one will be taken instead&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import error&lt;br /&gt;
&lt;br /&gt;
==get_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|   sid||   savetimings||   allowprev||   tokenanswerspersistence||   showgroupinfo||   showwelcome&lt;br /&gt;
|-&lt;br /&gt;
|   owner_id||   template||   printanswers||   assessments||  shownoanswer ||   showprogress&lt;br /&gt;
|-&lt;br /&gt;
|   admin||   language||   ipaddr||   usecaptcha||   showqnumcode||   allowjumps&lt;br /&gt;
|-&lt;br /&gt;
|   active||   additional_languages ||   refurl||   usetokens||   bouncetime||   navigationdelay&lt;br /&gt;
|-&lt;br /&gt;
|   expires||   datestamp||   datecreated||   bounce_email||   bounceprocessing||   nokeyboard&lt;br /&gt;
|-&lt;br /&gt;
|   startdate||   usecookie||   publicstatistics||   attributedescriptions||   bounceaccounttype||   alloweditaftercompletion&lt;br /&gt;
|-&lt;br /&gt;
|   adminemail||   allowregister||   publicgraphs||   emailresponseto||   bounceaccounthost||   googleanalyticsstyle&lt;br /&gt;
|-&lt;br /&gt;
|   anonymized||   allowsave||   listpublic||   emailnotificationto||   bounceaccountpass||   googleanalyticsapikey&lt;br /&gt;
|-&lt;br /&gt;
|   faxto||   autonumber_start||   htmlemail||   tokenlength||   bounceaccountencryption||&lt;br /&gt;
|-&lt;br /&gt;
|format||   autoredirect||   sendconfirmation||   showxquestions||   bounceaccountuser||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An assosiative array with the name-value  pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of the change for each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
Properties available for changing are all those defined in get_survey_properties with the following exceptions&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|properties not allowed to be modified|| Properties not allowed to be modified when survey active&lt;br /&gt;
|-&lt;br /&gt;
|sid||anonymized&lt;br /&gt;
|-&lt;br /&gt;
|language||datestamp&lt;br /&gt;
|-&lt;br /&gt;
|additional_languages||savetimings&lt;br /&gt;
|-&lt;br /&gt;
|active||ipaddr&lt;br /&gt;
|-&lt;br /&gt;
|||refurl&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_surveys==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to list the ids and info of surveys belonging to a user.&lt;br /&gt;
&lt;br /&gt;
    * If user is admin he can get surveys of every user (parameter sUser) or all surveys (sUser=null)&lt;br /&gt;
&lt;br /&gt;
    * Else only the syrveys belonging to the user requesting will be shown.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sUser (string) -  The users surveys to list&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Survey&#039;s properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid user&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No surveys found&lt;br /&gt;
&lt;br /&gt;
Survey&#039;s properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|property||type&lt;br /&gt;
|-&lt;br /&gt;
|sid||integer&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_title||string&lt;br /&gt;
|-&lt;br /&gt;
|startdate||date&lt;br /&gt;
|-&lt;br /&gt;
|expires||date&lt;br /&gt;
|-&lt;br /&gt;
|active||y/n&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==activate_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine that launches a newly created survey (sets active -available for users)&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (array) The result of the activation&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Activation Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==export_statistics==&lt;br /&gt;
&lt;br /&gt;
RPC routine to export statistics of a survey to a user.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
docType (string) - Type of document to generate&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional language of the survey to use (if not set, default language is selected)&lt;br /&gt;
&lt;br /&gt;
graph (string) - Optional parameter to enable graphs (0|1)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==get_summary==&lt;br /&gt;
&lt;br /&gt;
RPC routine to get survey summary, regarding token usage and survey participation.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
sStatname (string) - The statistic to return&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No available data&lt;br /&gt;
**No such property&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available statistics:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Survey stats||Token stats&lt;br /&gt;
|-&lt;br /&gt;
|completed_responses||token_count&lt;br /&gt;
|-&lt;br /&gt;
|incomplete_responses||token_invalid&lt;br /&gt;
|-&lt;br /&gt;
|full_responses||tokens_sent&lt;br /&gt;
|-&lt;br /&gt;
|||token_opted_out&lt;br /&gt;
|-&lt;br /&gt;
|||token_completed&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==add_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add a language to an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) - The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the new language to be added. Note: If the language is already in that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_survey_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a language of an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the language to be removed. Note: If the language is not part of that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Cannot remove base language&lt;br /&gt;
**Error&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid session key&lt;br /&gt;
&lt;br /&gt;
==get_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleSettings     (array) -  An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
slang (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_survey_id            ||    surveyls_url                  ||    surveyls_email_register_subj  ||    email_admin_notification_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_language             ||    surveyls_urldescription       ||    surveyls_email_register       ||    email_admin_notification&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_title                ||    surveyls_email_invite_subj    ||    surveyls_email_confirm_subj   ||    email_admin_responses_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_description          ||    surveyls_email_invite         ||    surveyls_email_confirm        ||    email_admin_responses&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_welcometext          || surveyls_email_remind_subj       ||    surveyls_dateformat           ||    surveyls_numberformat&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_endtext              ||    surveyls_email_remind         ||    surveyls_attributecaptions    ||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleData     (array) -  An assosiative array with the key-value pairs of properties to set. Invalid fieldnames or fields that may not be modified are ignored.&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Result for each parameter set&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Allowed Parameters:&lt;br /&gt;
&lt;br /&gt;
All those defined in get-language_properties except:&lt;br /&gt;
*surveyls_language&lt;br /&gt;
*surveyls_survey_id&lt;br /&gt;
&lt;br /&gt;
==add_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty group with minimum details.&lt;br /&gt;
&lt;br /&gt;
    * Used as a placeholder for importing questions.&lt;br /&gt;
&lt;br /&gt;
    * Returns the groupid of the created group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the surveythat the group will be added&lt;br /&gt;
&lt;br /&gt;
sGroupTitle     (string) -  Name of the new group&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) - Optional description of the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey that the group belongs&lt;br /&gt;
&lt;br /&gt;
sGroupID    (int) -  Id of the group to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the deleted group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid Group ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Group deletion failed&lt;br /&gt;
&lt;br /&gt;
==import_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a group - imports lsg,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey that the group will belong&lt;br /&gt;
&lt;br /&gt;
sImportData     (string) -  String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) -The format of the importfile in the stream (lsg|csv)&lt;br /&gt;
&lt;br /&gt;
sNewGroupName (string) - Optional new name for the group&lt;br /&gt;
&lt;br /&gt;
sNewGroupDescription (string) - Optional new description for the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Error: Invalid LimeSurvey group structure XML&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import Error&lt;br /&gt;
&lt;br /&gt;
==get_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to get properties of&lt;br /&gt;
&lt;br /&gt;
aGroupSettings     (array) -  Array containing the properties to request.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||description&lt;br /&gt;
|-&lt;br /&gt;
|sid||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to set properties to&lt;br /&gt;
&lt;br /&gt;
aGroupData     (array) -  Assosiative Array containing key-value pairs of the properties to set.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of each set action&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Group with dependencies - Order cannot be changed&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|||description&lt;br /&gt;
|-&lt;br /&gt;
|||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_groups==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of groups belonging to survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey to get groups of&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the groups&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**No groups found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==list_users==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of users&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of users&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No users found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission (super admin is required)&lt;br /&gt;
&lt;br /&gt;
==delete_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int)id of the deleted Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
** Invalid question ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Cannot delete Question. Others rely on this question&lt;br /&gt;
**Error&lt;br /&gt;
&lt;br /&gt;
==import_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a question - imports lsq,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
iGroupID (int) - Id of the group that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
sImportData (string) - String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sImportDataType (string)  - Format of the input stream (lsq,csv)&lt;br /&gt;
&lt;br /&gt;
sMandatory (string) - Optional Mandatory question option (default to No)&lt;br /&gt;
&lt;br /&gt;
sNewQuestionTitle (string) - Optional new title for the question&lt;br /&gt;
&lt;br /&gt;
sNewqQuestion (string) - An optional new question&lt;br /&gt;
&lt;br /&gt;
sNewQuestionHelp (string) - An optional new question help text&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) Id of the new Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid group ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Invalid LimeSurvey question structure XML&lt;br /&gt;
&lt;br /&gt;
==get_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionSettings (array) The properties to get&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||type||help||language&lt;br /&gt;
|-&lt;br /&gt;
|parent_qid||title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|sid||question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|gid||preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|subquestions||attributes||attributes_lang||answeroptions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set question properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) - Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionData (array)  - An array with the particular fieldnames as keys and their values to set on that particular question&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The resilt of the set of each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Questions with dependencies - Order cannot be changed&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|help|| ||&lt;br /&gt;
|-&lt;br /&gt;
|title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_questions==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of questions of a survey/group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
iGroupID  (int) - Id of the group to get questions of&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the questions&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Missmatch in surveyid and groupid&lt;br /&gt;
**No questions found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
Activate tokens&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
surveyid (string) The survey ID&lt;br /&gt;
&lt;br /&gt;
additional_attributes (array of integers) Any additional attribute fields to create. Just give the attribute IDs&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) status OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
&lt;br /&gt;
==add_participants==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new entries to your token table. You can also set if for these new entries a token key is automatically created. Please note that this function does not check for duplicate content in any of the fields, except for token keys created by the function itself.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sessionkey (string) - The session key&lt;br /&gt;
*surveyID (string) - The survey id&lt;br /&gt;
*participantData (array) -  2-dimensional array/structure containing your participants data&lt;br /&gt;
*createTokenKey (boolean) - Set this to true if you want a token key create automatically for each entry - if your participant data included a [token] field it will be overwritten&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success:  participant data (struct) -  structure containing your participants data plus the token ID and (if applicable) the new token&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
&lt;br /&gt;
JSON-RPC example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;add_participants&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;sessionkey&amp;quot;:&amp;quot;73e8rx864rnxmk64gp67bah44u2igivm&amp;quot;,&amp;quot;surveyID&amp;quot;:&amp;quot;668138&amp;quot;,&amp;quot;participantData&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;}]}}&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;result&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;,&amp;quot;tid&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;token&amp;quot;:&amp;quot;auc82gar58dpcg6&amp;quot;}],&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==delete_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete multiple participants of a Survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
aTokenIDs  (array) - IId of the tokens/participants to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of deletion status for each participant&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
&lt;br /&gt;
==get_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return settings of a token/participant of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to get token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to check&lt;br /&gt;
&lt;br /&gt;
aTokenProperties (array) - The properties to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of requested values&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|tid||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey participant/token&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to set token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to alter&lt;br /&gt;
&lt;br /&gt;
aTokenData (array) - Key - value pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of results of changing properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_participants==&lt;br /&gt;
&lt;br /&gt;
RPC routine to return the IDs and info of token/participants of a survey.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
   sSessionKey (string) -  Auth credentials&lt;br /&gt;
   iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
   iStart (int) - Start id of the token list&lt;br /&gt;
   iLimit (int) - Number of participants to return&lt;br /&gt;
   bUnused (bool) - If you want unused tokensm, set true&lt;br /&gt;
   aAttributes(bool|array) An array of extended attributes that can be requested, besides the default ones (default value to false)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of Participants info&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No Tokens found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
RPC routine to to initialise the survey&#039;s collection of tokens where new participant tokens may be later added&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
&lt;br /&gt;
aAttributeFields (array) - An array of integer describing any additional attribute fields&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Status OK&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Token table could not be created&lt;br /&gt;
&lt;br /&gt;
==invite_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to invite participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==remind_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to send reminder for participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
iMinDaysBetween (int) - Optional parameter days from last reminder&lt;br /&gt;
&lt;br /&gt;
iMaxReminders (int) - Optional parameter Maximum reminders count&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==add_response==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new responses to your survey response table.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sSessionKey (string) - The session key&lt;br /&gt;
*iSurveyID (integer) - The survey id&lt;br /&gt;
*aResponseData (array) -  array/structure containing your response data&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: response_id (integer) -  Returns the id of the inserted survey response&lt;br /&gt;
*On failure: (array) with error description&lt;br /&gt;
&lt;br /&gt;
==export_responses==&lt;br /&gt;
&lt;br /&gt;
Export response data to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc, html&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
FromResponse (int) - Optional start number of response&lt;br /&gt;
&lt;br /&gt;
ToResponse (int) - Optional end number of responses&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
Note: If you have huge response sets try only to request a certain number of records at a time otherwise the server may run out of memory.&lt;br /&gt;
&lt;br /&gt;
==export_responses_by_token==&lt;br /&gt;
&lt;br /&gt;
Export responses data of specific token to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc,html&lt;br /&gt;
&lt;br /&gt;
sToken (string) - Token string of a candidate&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
aFields (array) - Optional Selected fields&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
To test you will have to activate JSON-RPC in global settings. To run a simple self-test go to&lt;br /&gt;
&lt;br /&gt;
http://path_to_your_limesurvey_installation/index.php/admin/remotecontrol/test . This will import the example survey, do various things with it and delete it afterwards.&lt;br /&gt;
&lt;br /&gt;
The test assumes that you still are using the standard user &#039;admin&#039; with password &#039;password&#039;.&lt;br /&gt;
&lt;br /&gt;
The client function for this test can be found in /application/controller/admin/remotecontrol.php and the particular function is called test().&lt;br /&gt;
&lt;br /&gt;
=Ruby Example=&lt;br /&gt;
&lt;br /&gt;
There are some cool things that you can use with the RemoteControl2 API and this is an example of a production use of this. Basically, I, (kobaltz in the forums) have a third party site that I built that controls the users and level of access of each company and their users. From within this site, I have a daemon that will generate participants of the appropriate survey twice an hour. This will use LimeSurvey&#039;s Mail Function to send the end user a link to the survey. Administrators of the third party site will get statistical data of the end user filling out the survey as well as a link to review the surveys completed using the same template that the user used to fill it out. Reducing duplicate entry of data made possible with the RemoteControl2 API.&lt;br /&gt;
&lt;br /&gt;
==Load Requirements and Declare Values==&lt;br /&gt;
You will first need to require the dependencies needed to establish communication with the API. Also, note that there is a username and password field that requires to be stored in plain text. I have a separate API User within my LimeSurvey to handle these calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env ruby&lt;br /&gt;
&lt;br /&gt;
require &#039;net/https&#039;&lt;br /&gt;
require &#039;uri&#039;&lt;br /&gt;
require &#039;json&#039;&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;api_user&amp;quot;&lt;br /&gt;
password = &amp;quot;api_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Module==&lt;br /&gt;
&lt;br /&gt;
The below code is used to define the module LimeSurvey. Within this module is an API class. We will use this to create an instance of this module and then call on the API call wherever needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
module LimeSurvey&lt;br /&gt;
  class API&lt;br /&gt;
    def initialize(service_url)&lt;br /&gt;
      @uri = URI.parse(service_url)&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def method_missing(name, *args)&lt;br /&gt;
      post_body = { &#039;method&#039; =&amp;gt; name, &#039;params&#039; =&amp;gt; args, &#039;id&#039; =&amp;gt; &#039;jsonrpc&#039; }.to_json&lt;br /&gt;
      resp = JSON.parse( http_post_request(post_body) )&lt;br /&gt;
      raise JSONRPCError, resp[&#039;error&#039;] if resp[&#039;error&#039;]&lt;br /&gt;
      resp[&#039;result&#039;]&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def http_post_request(post_body)&lt;br /&gt;
      http    = Net::HTTP.new(@uri.host, @uri.port)&lt;br /&gt;
      request = Net::HTTP::Post.new(@uri.request_uri)&lt;br /&gt;
      request.content_type = &#039;application/json&#039;&lt;br /&gt;
      request.body = post_body&lt;br /&gt;
      http.request(request).body&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  class JSONRPCError &amp;lt; RuntimeError; end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==API Call==&lt;br /&gt;
This code is used to create the instance of the LimeSurvey::API module and class. You will want to change the URL to that of your RemoteControl2 URL.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
survey = LimeSurvey::API.new(&#039;http://localhost/limesurvey/index.php?r=admin/remotecontrol&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example takes the above code and puts it into play. I create a new session with the RemoteControl2 API and store the session in the variable session_key. You will want to change the ID numbers to the appropriate Survey ID in the examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
system(&amp;quot;cls&amp;quot;)&lt;br /&gt;
session_key = survey.get_session_key(username,password)&lt;br /&gt;
puts &amp;quot;Session Key: #{session_key}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
response = survey.get_survey_properties(session_key, &amp;quot;863224&amp;quot;, [&amp;quot;owner_id&amp;quot;])&lt;br /&gt;
puts &amp;quot;Properties:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.list_surveys(sSessionKey: session_key, sUser: &amp;quot;dkimura&amp;quot;)&lt;br /&gt;
puts &amp;quot;Survey List:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.add_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;,&lt;br /&gt;
    [email:&amp;quot;james.bond@example.com&amp;quot;,lastname:&amp;quot;Bond&amp;quot;,firstname:&amp;quot;James&amp;quot;]&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Add Participant:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.invite_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Invite Participant:  #{response}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.release_session_key(session_key)&lt;br /&gt;
puts &amp;quot;Release Session: #{response}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Grabs a Survey&#039;s list of participants and parses through them&lt;br /&gt;
# The response is in an array format.&lt;br /&gt;
# Each response within the array is in JSON format (How the survey is configured with RemoteControl2)&lt;br /&gt;
# Convert the participant response to JSON and then display the token.&lt;br /&gt;
response = survey.list_participants(session_key, &amp;quot;593987&amp;quot;)&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
response_participants = []&lt;br /&gt;
response.each do |part|&lt;br /&gt;
	resps = JSON.parse(part.to_json)&lt;br /&gt;
	puts &amp;quot;Participant: #{resps[&#039;token&#039;]}&amp;quot;&lt;br /&gt;
	puts &amp;quot;\n&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Example Return==&lt;br /&gt;
&lt;br /&gt;
From the above example, here is the return that I receive. Some of the items are returned as a hash and some items returned as an array of hashes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
Session Key: piadscbc94vyanxwkdy8f3xii4av2b2w&lt;br /&gt;
&lt;br /&gt;
Properties:  {&amp;quot;owner_id&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Survey List:  [{&amp;quot;sid&amp;quot;=&amp;gt;&amp;quot;863224&amp;quot;, &amp;quot;surveyls_title&amp;quot;=&amp;gt;&amp;quot;Statement of Work v0.12&amp;quot;, &amp;quot;startdate&amp;quot;=&amp;gt;nil, &amp;quot;expires&amp;quot;=&amp;gt;nil, &amp;quot;active&amp;quot;=&amp;gt;&amp;quot;Y&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Add Participant:  [{&amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;lastname&amp;quot;=&amp;gt;&amp;quot;Bond&amp;quot;, &amp;quot;firstname&amp;quot;=&amp;gt;&amp;quot;James&amp;quot;, &amp;quot;tid&amp;quot;=&amp;gt;&amp;quot;7&amp;quot;, &amp;quot;token&amp;quot;=&amp;gt;&amp;quot;pt5ztzxndibkz4j&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Invite Participant:  {&amp;quot;7&amp;quot;=&amp;gt;{&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;James Bond&amp;quot;, &amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;OK&amp;quot;}, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;0 left to send&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Participant: p7m5zmh38wi9mbk&lt;br /&gt;
Participant: nssu6ne6ii9wva9&lt;br /&gt;
Participant: r9kr2sahn7tfsv9&lt;br /&gt;
Participant: a28ci2z9m7ynfgg&lt;br /&gt;
Participant: 4ytt5axg9ebdazh&lt;br /&gt;
Participant: wswjv2t5v7vh4p7&lt;br /&gt;
Participant: fqvxeckgh6vgy3e&lt;br /&gt;
Participant: n5p2vfnh7dwx699&lt;br /&gt;
Participant: ycsmigup9pagm6z&lt;br /&gt;
Participant: 33ztf4g74k2kvx4&lt;br /&gt;
&lt;br /&gt;
Release Session: OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PHP Example=&lt;br /&gt;
&lt;br /&gt;
To include JSON-RPC in your application, you can write an application based on the tiny jsonRPCClient from [http://jsonrpcphp.org/ | jsonrpcphp.org]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once &#039;jsonRPCClient.php&#039;;&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_BASEURL&#039;, &#039;http://localhost/limesurvey/&#039;);  // adjust this one to your actual LimeSurvey URL&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_USER&#039;, &#039;rpcuser&#039; );&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_PASSWORD&#039;, &#039;mypassword&#039; );&lt;br /&gt;
&lt;br /&gt;
// the survey to process&lt;br /&gt;
&lt;br /&gt;
$survey_id=374699;&lt;br /&gt;
&lt;br /&gt;
// instanciate a new client&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient = new jsonRPCClient( LS_BASEURL.&#039;/admin/remotecontrol&#039; );&lt;br /&gt;
&lt;br /&gt;
// receive session key&lt;br /&gt;
&lt;br /&gt;
$sessionKey= $myJSONRPCClient-&amp;gt;get_session_key( LS_USER, LS_PASSWORD );&lt;br /&gt;
&lt;br /&gt;
// receive all ids and info of groups belonging to a given survey&lt;br /&gt;
&lt;br /&gt;
$groups = $myJSONRPCClient-&amp;gt;list_groups( $sessionKey, $survey_id );&lt;br /&gt;
&lt;br /&gt;
print_r($groups, null );&lt;br /&gt;
&lt;br /&gt;
// release the session key&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient-&amp;gt;release_session_key( $sessionKey );&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JAVA example=&lt;br /&gt;
To decode and code your json calls you can use the library gson as you can see in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.UnsupportedEncodingException;&lt;br /&gt;
&lt;br /&gt;
import org.apache.http.HttpEntity;&lt;br /&gt;
import org.apache.http.HttpResponse;&lt;br /&gt;
import org.apache.http.client.methods.HttpPost;&lt;br /&gt;
import org.apache.http.entity.StringEntity;&lt;br /&gt;
import org.apache.http.impl.client.DefaultHttpClient;&lt;br /&gt;
import org.apache.http.util.EntityUtils;&lt;br /&gt;
&lt;br /&gt;
import com.google.gson.JsonElement;&lt;br /&gt;
import com.google.gson.JsonObject;&lt;br /&gt;
import com.google.gson.JsonParser;&lt;br /&gt;
&lt;br /&gt;
public class TestHttpClient {&lt;br /&gt;
	&lt;br /&gt;
    public static String parse(String jsonLine) {&lt;br /&gt;
	 JsonElement jelement = new JsonParser().parse(jsonLine);&lt;br /&gt;
	 JsonObject  jobject = jelement.getAsJsonObject();&lt;br /&gt;
	 String result = jobject.get(&amp;quot;result&amp;quot;).toString();&lt;br /&gt;
	 return result;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
    public static void main(String[] args) throws UnsupportedEncodingException {&lt;br /&gt;
      DefaultHttpClient client = new DefaultHttpClient();          &lt;br /&gt;
         &lt;br /&gt;
      HttpPost post = new HttpPost(&amp;quot;http://PATH_OF_YOUR_SERVER/index.php/admin/remotecontrol&amp;quot;);&lt;br /&gt;
      post.setHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
      post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;get_session_key\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;username\&amp;quot;: \&amp;quot;YOUR_USERNAME\&amp;quot;, \&amp;quot;password\&amp;quot;: \&amp;quot;YOUR_PASSWORD\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
      try {&lt;br /&gt;
        HttpResponse response = client.execute(post);&lt;br /&gt;
        if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
            HttpEntity entity = response.getEntity();&lt;br /&gt;
            String sessionKey = parse(EntityUtils.toString(entity));&lt;br /&gt;
            post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;list_groups\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;sSessionKey \&amp;quot;: &amp;quot;+sessionKey+&amp;quot;, \&amp;quot;iSurveyID \&amp;quot;: \&amp;quot;ID_SURVEY\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
            response = client.execute(post);&lt;br /&gt;
            if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
                entity = response.getEntity();&lt;br /&gt;
                System.out.println(EntityUtils.toString(entity));&lt;br /&gt;
                }&lt;br /&gt;
           }&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } catch (IOException e) {&lt;br /&gt;
        e.printStackTrace();&lt;br /&gt;
      }&lt;br /&gt;
    }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JSON-RPC notes=&lt;br /&gt;
&lt;br /&gt;
The content-type of the HTTP request must be application/json.  Most formatting errors or a failure to set the content-type header will result in a null response from the server (not a JSON response).  Below is an example of a valid request and response pair.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
 HTTP headers:&lt;br /&gt;
&lt;br /&gt;
   content-type=application/json&lt;br /&gt;
&lt;br /&gt;
   connection=Keep-Alive&lt;br /&gt;
&lt;br /&gt;
   host=mylimesurveyhost.com&lt;br /&gt;
&lt;br /&gt;
   content-length=65&lt;br /&gt;
&lt;br /&gt;
   user-agent=Apache-HttpClient/4.2.2 (java 1.5)&lt;br /&gt;
&lt;br /&gt;
 Post body:&lt;br /&gt;
&lt;br /&gt;
   {&amp;quot;method&amp;quot;:&amp;quot;get_session_key&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;username&amp;quot;:&amp;quot;admin&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;mypassword&amp;quot;},&amp;quot;id&amp;quot;:1}&lt;br /&gt;
&lt;br /&gt;
Response body:&lt;br /&gt;
&lt;br /&gt;
 {&amp;quot;id&amp;quot;:1,&amp;quot;result&amp;quot;:&amp;quot;6htqat38fyr4v7iu72nqgv7xgavkvfcz&amp;quot;,&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
2.0a Only three functions are supported right now: getSessionKey, releaseSessionKey, deleteSurvey&lt;br /&gt;
&lt;br /&gt;
2.0b Added function add_participants&lt;br /&gt;
&lt;br /&gt;
2.0RC5 Added import_survey, activate_survey, activate_tokens&lt;br /&gt;
&lt;br /&gt;
2.0 (build 121030) Added subquestions, attributes, attributes_lang and answeroptions properties for get_question_properties&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
for further changes check the Limesurvey release notes, thanks!&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=44313</id>
		<title>RemoteControl 2 API</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=44313"/>
		<updated>2013-07-06T15:32:16Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* export_responses_by_token */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl 2 is a XML-RPC/JSON-RPC based web service available in LimeSurvey 2.0 or later. The old [RemoteControl] will not be available any longer in version 2.&lt;br /&gt;
&lt;br /&gt;
LSRC2 makes it possible for developers to control specific functionality of LimeSurvey from any other application, without being restricted to PHP as a programming language.&lt;br /&gt;
&lt;br /&gt;
The following features are planned:&lt;br /&gt;
* start a predefined survey (change titles and things)&lt;br /&gt;
* add predefined groups or questions&lt;br /&gt;
* activate the survey, restrict it to start and endtime&lt;br /&gt;
* make it closed,&lt;br /&gt;
* add participant data/tokens when you need them&lt;br /&gt;
* return the unused tokens to the main application&lt;br /&gt;
* get a fieldmap for a survey,&lt;br /&gt;
* invite or remind the participants of your survey&lt;br /&gt;
&lt;br /&gt;
...and much more&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* libXML installed&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC2==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC2 is disabled. In order to use LSRC2 you must first enable the service, and then adjust the settings to suit your needs. To enable LSRC2 login to the LimeSurvey administration, go to [[Global settings]], choose the tab &#039;Services&#039; and select one of the two RPC services (XML-RPC or JSON-RPC) service.&lt;br /&gt;
&lt;br /&gt;
== Security==&lt;br /&gt;
&lt;br /&gt;
LSRC2 uses the same security measures as the normal administration login. That means that the permission set of the used username and password is the same as if you would login in the administration with that user/password. Also LSRC2 is protected against brute-force password cracking - like the normal administration login.&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC2=&lt;br /&gt;
&lt;br /&gt;
The basic LSRC2 URL is: http://&amp;lt;your_domain&amp;gt;/&amp;lt;your_limesurvey_dir&amp;gt;/index.php/admin/remotecontrol&lt;br /&gt;
&lt;br /&gt;
LSRC2 fully complies to the [http://www.xmlrpc.com/ XML-RPC specification] and JSON-RPC version 1 specifications. We recommend in general to use JSON-RPC because it is well tested and has a much smaller footprint than XML-RPC.&lt;br /&gt;
&lt;br /&gt;
LSRC2 offers the following functions:&lt;br /&gt;
&lt;br /&gt;
==get_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can create a new XML-RPC session key. This is mandatory for all following LSRC2 function calls.&lt;br /&gt;
&lt;br /&gt;
Parameters: username (string), password (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: A session key (string)&lt;br /&gt;
*On failure:  for protocol-level errors (invalid format etc), an error message.  For invalid username and password, returns a null error and the result body contains a &#039;status&#039; name-value pair with the error message.&lt;br /&gt;
&lt;br /&gt;
==release_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can close a previously opened XML-RPC/JSON-RPC session.&lt;br /&gt;
&lt;br /&gt;
Parameters: session key (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*Always: &#039;OK&#039; (string)&lt;br /&gt;
&lt;br /&gt;
==get_site_settings==&lt;br /&gt;
&lt;br /&gt;
Function to provide with site settings only to administrators&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) The session key&lt;br /&gt;
&lt;br /&gt;
sSetttingName (string) -  Name of the setting to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Setting&lt;br /&gt;
*On failure: (string) Error message&lt;br /&gt;
&lt;br /&gt;
==add_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty survey with minimum details&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID     (int),    The wish id of the Survey to add&lt;br /&gt;
&lt;br /&gt;
sSurveyTitle     (string),  Title of the new Survey&lt;br /&gt;
&lt;br /&gt;
sSurveyLanguage    (string),  Default language of the Survey&lt;br /&gt;
&lt;br /&gt;
sformat     (string),  Question appearance format (S|G|A)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Faulty parameters&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to Delete a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string), Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int), The Survey to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: Status =&amp;gt;OK (array)&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==import_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a survey from lss,csv,xls or survey zip archive.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sImportData  (string) String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive&lt;br /&gt;
&lt;br /&gt;
sImportDataType     (string),    The format of the import file (lss,csv,xls or zip)&lt;br /&gt;
&lt;br /&gt;
sNewSurveyName     (string),  The optional new name of the survey (base language)&lt;br /&gt;
&lt;br /&gt;
DestSurveyID    (int), This is the new ID of the survey - if already used a random one will be taken instead&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import error&lt;br /&gt;
&lt;br /&gt;
==get_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|   sid||   savetimings||   allowprev||   tokenanswerspersistence||   showgroupinfo||   showwelcome&lt;br /&gt;
|-&lt;br /&gt;
|   owner_id||   template||   printanswers||   assessments||  shownoanswer ||   showprogress&lt;br /&gt;
|-&lt;br /&gt;
|   admin||   language||   ipaddr||   usecaptcha||   showqnumcode||   allowjumps&lt;br /&gt;
|-&lt;br /&gt;
|   active||   additional_languages ||   refurl||   usetokens||   bouncetime||   navigationdelay&lt;br /&gt;
|-&lt;br /&gt;
|   expires||   datestamp||   datecreated||   bounce_email||   bounceprocessing||   nokeyboard&lt;br /&gt;
|-&lt;br /&gt;
|   startdate||   usecookie||   publicstatistics||   attributedescriptions||   bounceaccounttype||   alloweditaftercompletion&lt;br /&gt;
|-&lt;br /&gt;
|   adminemail||   allowregister||   publicgraphs||   emailresponseto||   bounceaccounthost||   googleanalyticsstyle&lt;br /&gt;
|-&lt;br /&gt;
|   anonymized||   allowsave||   listpublic||   emailnotificationto||   bounceaccountpass||   googleanalyticsapikey&lt;br /&gt;
|-&lt;br /&gt;
|   faxto||   autonumber_start||   htmlemail||   tokenlength||   bounceaccountencryption||&lt;br /&gt;
|-&lt;br /&gt;
|format||   autoredirect||   sendconfirmation||   showxquestions||   bounceaccountuser||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An assosiative array with the name-value  pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of the change for each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
Properties available for changing are all those defined in get_survey_properties with the following exceptions&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|properties not allowed to be modified|| Properties not allowed to be modified when survey active&lt;br /&gt;
|-&lt;br /&gt;
|sid||anonymized&lt;br /&gt;
|-&lt;br /&gt;
|language||datestamp&lt;br /&gt;
|-&lt;br /&gt;
|additional_languages||savetimings&lt;br /&gt;
|-&lt;br /&gt;
|active||ipaddr&lt;br /&gt;
|-&lt;br /&gt;
|||refurl&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_surveys==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to list the ids and info of surveys belonging to a user.&lt;br /&gt;
&lt;br /&gt;
    * If user is admin he can get surveys of every user (parameter sUser) or all surveys (sUser=null)&lt;br /&gt;
&lt;br /&gt;
    * Else only the syrveys belonging to the user requesting will be shown.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sUser (string) -  The users surveys to list&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Survey&#039;s properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid user&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No surveys found&lt;br /&gt;
&lt;br /&gt;
Survey&#039;s properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|property||type&lt;br /&gt;
|-&lt;br /&gt;
|sid||integer&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_title||string&lt;br /&gt;
|-&lt;br /&gt;
|startdate||date&lt;br /&gt;
|-&lt;br /&gt;
|expires||date&lt;br /&gt;
|-&lt;br /&gt;
|active||y/n&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==activate_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine that launches a newly created survey (sets active -available for users)&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (array) The result of the activation&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Activation Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==export_statistics==&lt;br /&gt;
&lt;br /&gt;
RPC routine to export statistics of a survey to a user.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
docType (string) - Type of document to generate&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional language of the survey to use (if not set, default language is selected)&lt;br /&gt;
&lt;br /&gt;
graph (string) - Optional parameter to enable graphs (0|1)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==get_summary==&lt;br /&gt;
&lt;br /&gt;
RPC routine to get survey summary, regarding token usage and survey participation.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
sStatname (string) - The statistic to return&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No available data&lt;br /&gt;
**No such property&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available statistics:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Survey stats||Token stats&lt;br /&gt;
|-&lt;br /&gt;
|completed_responses||token_count&lt;br /&gt;
|-&lt;br /&gt;
|incomplete_responses||token_invalid&lt;br /&gt;
|-&lt;br /&gt;
|full_responses||tokens_sent&lt;br /&gt;
|-&lt;br /&gt;
|||token_opted_out&lt;br /&gt;
|-&lt;br /&gt;
|||token_completed&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==add_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add a language to an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) - The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the new language to be added. Note: If the language is already in that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_survey_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a language of an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the language to be removed. Note: If the language is not part of that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Cannot remove base language&lt;br /&gt;
**Error&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid session key&lt;br /&gt;
&lt;br /&gt;
==get_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleSettings     (array) -  An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
slang (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_survey_id            ||    surveyls_url                  ||    surveyls_email_register_subj  ||    email_admin_notification_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_language             ||    surveyls_urldescription       ||    surveyls_email_register       ||    email_admin_notification&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_title                ||    surveyls_email_invite_subj    ||    surveyls_email_confirm_subj   ||    email_admin_responses_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_description          ||    surveyls_email_invite         ||    surveyls_email_confirm        ||    email_admin_responses&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_welcometext          || surveyls_email_remind_subj       ||    surveyls_dateformat           ||    surveyls_numberformat&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_endtext              ||    surveyls_email_remind         ||    surveyls_attributecaptions    ||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleData     (array) -  An assosiative array with the key-value pairs of properties to set. Invalid fieldnames or fields that may not be modified are ignored.&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Result for each parameter set&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Allowed Parameters:&lt;br /&gt;
&lt;br /&gt;
All those defined in get-language_properties except:&lt;br /&gt;
*surveyls_language&lt;br /&gt;
*surveyls_survey_id&lt;br /&gt;
&lt;br /&gt;
==add_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty group with minimum details.&lt;br /&gt;
&lt;br /&gt;
    * Used as a placeholder for importing questions.&lt;br /&gt;
&lt;br /&gt;
    * Returns the groupid of the created group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the surveythat the group will be added&lt;br /&gt;
&lt;br /&gt;
sGroupTitle     (string) -  Name of the new group&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) - Optional description of the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey that the group belongs&lt;br /&gt;
&lt;br /&gt;
sGroupID    (int) -  Id of the group to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the deleted group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid Group ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Group deletion failed&lt;br /&gt;
&lt;br /&gt;
==import_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a group - imports lsg,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey that the group will belong&lt;br /&gt;
&lt;br /&gt;
sImportData     (string) -  String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) -The format of the importfile in the stream (lsg|csv)&lt;br /&gt;
&lt;br /&gt;
sNewGroupName (string) - Optional new name for the group&lt;br /&gt;
&lt;br /&gt;
sNewGroupDescription (string) - Optional new description for the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Error: Invalid LimeSurvey group structure XML&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import Error&lt;br /&gt;
&lt;br /&gt;
==get_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to get properties of&lt;br /&gt;
&lt;br /&gt;
aGroupSettings     (array) -  Array containing the properties to request.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||description&lt;br /&gt;
|-&lt;br /&gt;
|sid||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to set properties to&lt;br /&gt;
&lt;br /&gt;
aGroupData     (array) -  Assosiative Array containing key-value pairs of the properties to set.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of each set action&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Group with dependencies - Order cannot be changed&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|||description&lt;br /&gt;
|-&lt;br /&gt;
|||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_groups==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of groups belonging to survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey to get groups of&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the groups&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**No groups found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int)id of the deleted Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
** Invalid question ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Cannot delete Question. Others rely on this question&lt;br /&gt;
**Error&lt;br /&gt;
&lt;br /&gt;
==import_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a question - imports lsq,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
iGroupID (int) - Id of the group that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
sImportData (string) - String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sImportDataType (string)  - Format of the input stream (lsq,csv)&lt;br /&gt;
&lt;br /&gt;
sMandatory (string) - Optional Mandatory question option (default to No)&lt;br /&gt;
&lt;br /&gt;
sNewQuestionTitle (string) - Optional new title for the question&lt;br /&gt;
&lt;br /&gt;
sNewqQuestion (string) - An optional new question&lt;br /&gt;
&lt;br /&gt;
sNewQuestionHelp (string) - An optional new question help text&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) Id of the new Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid group ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Invalid LimeSurvey question structure XML&lt;br /&gt;
&lt;br /&gt;
==get_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionSettings (array) The properties to get&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||type||help||language&lt;br /&gt;
|-&lt;br /&gt;
|parent_qid||title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|sid||question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|gid||preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|subquestions||attributes||attributes_lang||answeroptions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set question properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) - Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionData (array)  - An array with the particular fieldnames as keys and their values to set on that particular question&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The resilt of the set of each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Questions with dependencies - Order cannot be changed&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|help|| ||&lt;br /&gt;
|-&lt;br /&gt;
|title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_questions==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of questions of a survey/group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
iGroupID  (int) - Id of the group to get questions of&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the questions&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Missmatch in surveyid and groupid&lt;br /&gt;
**No questions found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
Activate tokens&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
surveyid (string) The survey ID&lt;br /&gt;
&lt;br /&gt;
additional_attributes (array of integers) Any additional attribute fields to create. Just give the attribute IDs&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) status OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
&lt;br /&gt;
==add_participants==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new entries to your token table. You can also set if for these new entries a token key is automatically created. Please note that this function does not check for duplicate content in any of the fields, except for token keys created by the function itself.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sessionkey (string) - The session key&lt;br /&gt;
*surveyID (string) - The survey id&lt;br /&gt;
*participantData (array) -  2-dimensional array/structure containing your participants data&lt;br /&gt;
*createTokenKey (boolean) - Set this to true if you want a token key create automatically for each entry - if your participant data included a [token] field it will be overwritten&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success:  participant data (struct) -  structure containing your participants data plus the token ID and (if applicable) the new token&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
&lt;br /&gt;
JSON-RPC example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;add_participants&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;sessionkey&amp;quot;:&amp;quot;73e8rx864rnxmk64gp67bah44u2igivm&amp;quot;,&amp;quot;surveyID&amp;quot;:&amp;quot;668138&amp;quot;,&amp;quot;participantData&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;}]}}&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;result&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;,&amp;quot;tid&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;token&amp;quot;:&amp;quot;auc82gar58dpcg6&amp;quot;}],&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==delete_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete multiple participants of a Survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
aTokenIDs  (array) - IId of the tokens/participants to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of deletion status for each participant&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
&lt;br /&gt;
==get_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return settings of a token/participant of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to get token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to check&lt;br /&gt;
&lt;br /&gt;
aTokenProperties (array) - The properties to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of requested values&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|tid||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey participant/token&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to set token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to alter&lt;br /&gt;
&lt;br /&gt;
aTokenData (array) - Key - value pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of results of changing properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_participants==&lt;br /&gt;
&lt;br /&gt;
RPC routine to return the IDs and info of token/participants of a survey.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
   sSessionKey (string) -  Auth credentials&lt;br /&gt;
   iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
   iStart (int) - Start id of the token list&lt;br /&gt;
   iLimit (int) - Number of participants to return&lt;br /&gt;
   bUnused (bool) - If you want unused tokensm, set true&lt;br /&gt;
   aAttributes(bool|array) An array of extended attributes that can be requested, besides the default ones (default value to false)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of Participants info&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No Tokens found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
RPC routine to to initialise the survey&#039;s collection of tokens where new participant tokens may be later added&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
&lt;br /&gt;
aAttributeFields (array) - An array of integer describing any additional attribute fields&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Status OK&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Token table could not be created&lt;br /&gt;
&lt;br /&gt;
==invite_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to invite participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==remind_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to send reminder for participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
iMinDaysBetween (int) - Optional parameter days from last reminder&lt;br /&gt;
&lt;br /&gt;
iMaxReminders (int) - Optional parameter Maximum reminders count&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==add_response==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new responses to your survey response table.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sSessionKey (string) - The session key&lt;br /&gt;
*iSurveyID (integer) - The survey id&lt;br /&gt;
*aResponseData (array) -  array/structure containing your response data&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: response_id (integer) -  Returns the id of the inserted survey response&lt;br /&gt;
*On failure: (array) with error description&lt;br /&gt;
&lt;br /&gt;
==export_responses==&lt;br /&gt;
&lt;br /&gt;
Export response data to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc, html&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
FromResponse (int) - Optional start number of response&lt;br /&gt;
&lt;br /&gt;
ToResponse (int) - Optional end number of responses&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
Note: If you have huge response sets try only to request a certain number of records at a time otherwise the server may run out of memory.&lt;br /&gt;
&lt;br /&gt;
==export_responses_by_token==&lt;br /&gt;
&lt;br /&gt;
Export responses data of specific token to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc,html&lt;br /&gt;
&lt;br /&gt;
sToken (string) - Token string of a candidate&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
aFields (array) - Optional Selected fields&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
To test you will have to activate JSON-RPC in global settings. To run a simple self-test go to&lt;br /&gt;
&lt;br /&gt;
http://path_to_your_limesurvey_installation/index.php/admin/remotecontrol/test . This will import the example survey, do various things with it and delete it afterwards.&lt;br /&gt;
&lt;br /&gt;
The test assumes that you still are using the standard user &#039;admin&#039; with password &#039;password&#039;.&lt;br /&gt;
&lt;br /&gt;
The client function for this test can be found in /application/controller/admin/remotecontrol.php and the particular function is called test().&lt;br /&gt;
&lt;br /&gt;
=Ruby Example=&lt;br /&gt;
&lt;br /&gt;
==Load Requirements and Declare Values==&lt;br /&gt;
You will first need to require the dependencies needed to establish communication with the API. Also, note that there is a username and password field that requires to be stored in plain text. I have a separate API User within my LimeSurvey to handle these calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env ruby&lt;br /&gt;
&lt;br /&gt;
require &#039;net/https&#039;&lt;br /&gt;
require &#039;uri&#039;&lt;br /&gt;
require &#039;json&#039;&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;api_user&amp;quot;&lt;br /&gt;
password = &amp;quot;api_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Module==&lt;br /&gt;
&lt;br /&gt;
The below code is used to define the module LimeSurvey. Within this module is an API class. We will use this to create an instance of this module and then call on the API call wherever needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
module LimeSurvey&lt;br /&gt;
  class API&lt;br /&gt;
    def initialize(service_url)&lt;br /&gt;
      @uri = URI.parse(service_url)&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def method_missing(name, *args)&lt;br /&gt;
      post_body = { &#039;method&#039; =&amp;gt; name, &#039;params&#039; =&amp;gt; args, &#039;id&#039; =&amp;gt; &#039;jsonrpc&#039; }.to_json&lt;br /&gt;
      resp = JSON.parse( http_post_request(post_body) )&lt;br /&gt;
      raise JSONRPCError, resp[&#039;error&#039;] if resp[&#039;error&#039;]&lt;br /&gt;
      resp[&#039;result&#039;]&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def http_post_request(post_body)&lt;br /&gt;
      http    = Net::HTTP.new(@uri.host, @uri.port)&lt;br /&gt;
      request = Net::HTTP::Post.new(@uri.request_uri)&lt;br /&gt;
      request.content_type = &#039;application/json&#039;&lt;br /&gt;
      request.body = post_body&lt;br /&gt;
      http.request(request).body&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  class JSONRPCError &amp;lt; RuntimeError; end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==API Call==&lt;br /&gt;
This code is used to create the instance of the LimeSurvey::API module and class. You will want to change the URL to that of your RemoteControl2 URL.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
survey = LimeSurvey::API.new(&#039;http://localhost/limesurvey/index.php?r=admin/remotecontrol&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example takes the above code and puts it into play. I create a new session with the RemoteControl2 API and store the session in the variable session_key. You will want to change the ID numbers to the appropriate Survey ID in the examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
system(&amp;quot;cls&amp;quot;)&lt;br /&gt;
session_key = survey.get_session_key(username,password)&lt;br /&gt;
puts &amp;quot;Session Key: #{session_key}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
response = survey.get_survey_properties(session_key, &amp;quot;863224&amp;quot;, [&amp;quot;owner_id&amp;quot;])&lt;br /&gt;
puts &amp;quot;Properties:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.list_surveys(sSessionKey: session_key, sUser: &amp;quot;dkimura&amp;quot;)&lt;br /&gt;
puts &amp;quot;Survey List:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.add_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;,&lt;br /&gt;
    [email:&amp;quot;james.bond@example.com&amp;quot;,lastname:&amp;quot;Bond&amp;quot;,firstname:&amp;quot;James&amp;quot;]&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Add Participant:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.invite_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Invite Participant:  #{response}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example Return==&lt;br /&gt;
&lt;br /&gt;
From the above example, here is the return that I receive. Some of the items are returned as a hash and some items returned as an array of hashes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
Session Key: piadscbc94vyanxwkdy8f3xii4av2b2w&lt;br /&gt;
&lt;br /&gt;
Properties:  {&amp;quot;owner_id&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Survey List:  [{&amp;quot;sid&amp;quot;=&amp;gt;&amp;quot;863224&amp;quot;, &amp;quot;surveyls_title&amp;quot;=&amp;gt;&amp;quot;Statement of Work v0.12&amp;quot;, &amp;quot;startdate&amp;quot;=&amp;gt;nil, &amp;quot;expires&amp;quot;=&amp;gt;nil, &amp;quot;active&amp;quot;=&amp;gt;&amp;quot;Y&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Add Participant:  [{&amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;lastname&amp;quot;=&amp;gt;&amp;quot;Bond&amp;quot;, &amp;quot;firstname&amp;quot;=&amp;gt;&amp;quot;James&amp;quot;, &amp;quot;tid&amp;quot;=&amp;gt;&amp;quot;7&amp;quot;, &amp;quot;token&amp;quot;=&amp;gt;&amp;quot;pt5ztzxndibkz4j&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Invite Participant:  {&amp;quot;7&amp;quot;=&amp;gt;{&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;James Bond&amp;quot;, &amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;OK&amp;quot;}, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;0 left to send&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PHP Example=&lt;br /&gt;
&lt;br /&gt;
To include JSON-RPC in your application, you can write an application based on the tiny jsonRPCClient from [http://jsonrpcphp.org/ | jsonrpcphp.org]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once &#039;jsonRPCClient.php&#039;;&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_BASEURL&#039;, &#039;http://localhost/limesurvey/&#039;);  // adjust this one to your actual LimeSurvey URL&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_USER&#039;, &#039;rpcuser&#039; );&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_PASSWORD&#039;, &#039;mypassword&#039; );&lt;br /&gt;
&lt;br /&gt;
// the survey to process&lt;br /&gt;
&lt;br /&gt;
$survey_id=374699;&lt;br /&gt;
&lt;br /&gt;
// instanciate a new client&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient = new jsonRPCClient( LS_BASEURL.&#039;/admin/remotecontrol&#039; );&lt;br /&gt;
&lt;br /&gt;
// receive session key&lt;br /&gt;
&lt;br /&gt;
$sessionKey= $myJSONRPCClient-&amp;gt;get_session_key( LS_USER, LS_PASSWORD );&lt;br /&gt;
&lt;br /&gt;
// receive all ids and info of groups belonging to a given survey&lt;br /&gt;
&lt;br /&gt;
$groups = $myJSONRPCClient-&amp;gt;list_groups( $sessionKey, $survey_id );&lt;br /&gt;
&lt;br /&gt;
print_r($groups, null );&lt;br /&gt;
&lt;br /&gt;
// release the session key&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient-&amp;gt;release_session_key( $sessionKey );&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JAVA example=&lt;br /&gt;
To decode and code your json calls you can use the library gson as you can see in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.UnsupportedEncodingException;&lt;br /&gt;
&lt;br /&gt;
import org.apache.http.HttpEntity;&lt;br /&gt;
import org.apache.http.HttpResponse;&lt;br /&gt;
import org.apache.http.client.methods.HttpPost;&lt;br /&gt;
import org.apache.http.entity.StringEntity;&lt;br /&gt;
import org.apache.http.impl.client.DefaultHttpClient;&lt;br /&gt;
import org.apache.http.util.EntityUtils;&lt;br /&gt;
&lt;br /&gt;
import com.google.gson.JsonElement;&lt;br /&gt;
import com.google.gson.JsonObject;&lt;br /&gt;
import com.google.gson.JsonParser;&lt;br /&gt;
&lt;br /&gt;
public class TestHttpClient {&lt;br /&gt;
	&lt;br /&gt;
    public static String parse(String jsonLine) {&lt;br /&gt;
	 JsonElement jelement = new JsonParser().parse(jsonLine);&lt;br /&gt;
	 JsonObject  jobject = jelement.getAsJsonObject();&lt;br /&gt;
	 String result = jobject.get(&amp;quot;result&amp;quot;).toString();&lt;br /&gt;
	 return result;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
    public static void main(String[] args) throws UnsupportedEncodingException {&lt;br /&gt;
      DefaultHttpClient client = new DefaultHttpClient();          &lt;br /&gt;
         &lt;br /&gt;
      HttpPost post = new HttpPost(&amp;quot;http://PATH_OF_YOUR_SERVER/index.php/admin/remotecontrol&amp;quot;);&lt;br /&gt;
      post.setHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
      post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;get_session_key\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;username\&amp;quot;: \&amp;quot;YOUR_USERNAME\&amp;quot;, \&amp;quot;password\&amp;quot;: \&amp;quot;YOUR_PASSWORD\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
      try {&lt;br /&gt;
        HttpResponse response = client.execute(post);&lt;br /&gt;
        if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
            HttpEntity entity = response.getEntity();&lt;br /&gt;
            String sessionKey = parse(EntityUtils.toString(entity));&lt;br /&gt;
            post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;list_groups\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;sSessionKey \&amp;quot;: &amp;quot;+sessionKey+&amp;quot;, \&amp;quot;iSurveyID \&amp;quot;: \&amp;quot;ID_SURVEY\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
            response = client.execute(post);&lt;br /&gt;
            if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
                entity = response.getEntity();&lt;br /&gt;
                System.out.println(EntityUtils.toString(entity));&lt;br /&gt;
                }&lt;br /&gt;
           }&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } catch (IOException e) {&lt;br /&gt;
        e.printStackTrace();&lt;br /&gt;
      }&lt;br /&gt;
    }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JSON-RPC notes=&lt;br /&gt;
&lt;br /&gt;
The content-type of the HTTP request must be application/json.  Most formatting errors or a failure to set the content-type header will result in a null response from the server (not a JSON response).  Below is an example of a valid request and response pair.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
 HTTP headers:&lt;br /&gt;
&lt;br /&gt;
   content-type=application/json&lt;br /&gt;
&lt;br /&gt;
   connection=Keep-Alive&lt;br /&gt;
&lt;br /&gt;
   host=mylimesurveyhost.com&lt;br /&gt;
&lt;br /&gt;
   content-length=65&lt;br /&gt;
&lt;br /&gt;
   user-agent=Apache-HttpClient/4.2.2 (java 1.5)&lt;br /&gt;
&lt;br /&gt;
 Post body:&lt;br /&gt;
&lt;br /&gt;
   {&amp;quot;method&amp;quot;:&amp;quot;get_session_key&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;username&amp;quot;:&amp;quot;admin&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;mypassword&amp;quot;},&amp;quot;id&amp;quot;:1}&lt;br /&gt;
&lt;br /&gt;
Response body:&lt;br /&gt;
&lt;br /&gt;
 {&amp;quot;id&amp;quot;:1,&amp;quot;result&amp;quot;:&amp;quot;6htqat38fyr4v7iu72nqgv7xgavkvfcz&amp;quot;,&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
2.0a Only three functions are supported right now: getSessionKey, releaseSessionKey, deleteSurvey&lt;br /&gt;
&lt;br /&gt;
2.0b Added function add_participants&lt;br /&gt;
&lt;br /&gt;
2.0RC5 Added import_survey, activate_survey, activate_tokens&lt;br /&gt;
&lt;br /&gt;
2.0 (build 121030) Added subquestions, attributes, attributes_lang and answeroptions properties for get_question_properties&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
for further changes check the Limesurvey release notes, thanks!&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=44312</id>
		<title>RemoteControl 2 API</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl_2_API&amp;diff=44312"/>
		<updated>2013-07-06T15:31:42Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* export_responses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl 2 is a XML-RPC/JSON-RPC based web service available in LimeSurvey 2.0 or later. The old [RemoteControl] will not be available any longer in version 2.&lt;br /&gt;
&lt;br /&gt;
LSRC2 makes it possible for developers to control specific functionality of LimeSurvey from any other application, without being restricted to PHP as a programming language.&lt;br /&gt;
&lt;br /&gt;
The following features are planned:&lt;br /&gt;
* start a predefined survey (change titles and things)&lt;br /&gt;
* add predefined groups or questions&lt;br /&gt;
* activate the survey, restrict it to start and endtime&lt;br /&gt;
* make it closed,&lt;br /&gt;
* add participant data/tokens when you need them&lt;br /&gt;
* return the unused tokens to the main application&lt;br /&gt;
* get a fieldmap for a survey,&lt;br /&gt;
* invite or remind the participants of your survey&lt;br /&gt;
&lt;br /&gt;
...and much more&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* libXML installed&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC2==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC2 is disabled. In order to use LSRC2 you must first enable the service, and then adjust the settings to suit your needs. To enable LSRC2 login to the LimeSurvey administration, go to [[Global settings]], choose the tab &#039;Services&#039; and select one of the two RPC services (XML-RPC or JSON-RPC) service.&lt;br /&gt;
&lt;br /&gt;
== Security==&lt;br /&gt;
&lt;br /&gt;
LSRC2 uses the same security measures as the normal administration login. That means that the permission set of the used username and password is the same as if you would login in the administration with that user/password. Also LSRC2 is protected against brute-force password cracking - like the normal administration login.&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC2=&lt;br /&gt;
&lt;br /&gt;
The basic LSRC2 URL is: http://&amp;lt;your_domain&amp;gt;/&amp;lt;your_limesurvey_dir&amp;gt;/index.php/admin/remotecontrol&lt;br /&gt;
&lt;br /&gt;
LSRC2 fully complies to the [http://www.xmlrpc.com/ XML-RPC specification] and JSON-RPC version 1 specifications. We recommend in general to use JSON-RPC because it is well tested and has a much smaller footprint than XML-RPC.&lt;br /&gt;
&lt;br /&gt;
LSRC2 offers the following functions:&lt;br /&gt;
&lt;br /&gt;
==get_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can create a new XML-RPC session key. This is mandatory for all following LSRC2 function calls.&lt;br /&gt;
&lt;br /&gt;
Parameters: username (string), password (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: A session key (string)&lt;br /&gt;
*On failure:  for protocol-level errors (invalid format etc), an error message.  For invalid username and password, returns a null error and the result body contains a &#039;status&#039; name-value pair with the error message.&lt;br /&gt;
&lt;br /&gt;
==release_session_key==&lt;br /&gt;
&lt;br /&gt;
Using this function you can close a previously opened XML-RPC/JSON-RPC session.&lt;br /&gt;
&lt;br /&gt;
Parameters: session key (string)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*Always: &#039;OK&#039; (string)&lt;br /&gt;
&lt;br /&gt;
==get_site_settings==&lt;br /&gt;
&lt;br /&gt;
Function to provide with site settings only to administrators&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) The session key&lt;br /&gt;
&lt;br /&gt;
sSetttingName (string) -  Name of the setting to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Setting&lt;br /&gt;
*On failure: (string) Error message&lt;br /&gt;
&lt;br /&gt;
==add_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty survey with minimum details&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID     (int),    The wish id of the Survey to add&lt;br /&gt;
&lt;br /&gt;
sSurveyTitle     (string),  Title of the new Survey&lt;br /&gt;
&lt;br /&gt;
sSurveyLanguage    (string),  Default language of the Survey&lt;br /&gt;
&lt;br /&gt;
sformat     (string),  Question appearance format (S|G|A)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Faulty parameters&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to Delete a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string), Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int), The Survey to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: Status =&amp;gt;OK (array)&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==import_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a survey from lss,csv,xls or survey zip archive.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sImportData  (string) String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive&lt;br /&gt;
&lt;br /&gt;
sImportDataType     (string),    The format of the import file (lss,csv,xls or zip)&lt;br /&gt;
&lt;br /&gt;
sNewSurveyName     (string),  The optional new name of the survey (base language)&lt;br /&gt;
&lt;br /&gt;
DestSurveyID    (int), This is the new ID of the survey - if already used a random one will be taken instead&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) $iNewSurveyID&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import error&lt;br /&gt;
&lt;br /&gt;
==get_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|   sid||   savetimings||   allowprev||   tokenanswerspersistence||   showgroupinfo||   showwelcome&lt;br /&gt;
|-&lt;br /&gt;
|   owner_id||   template||   printanswers||   assessments||  shownoanswer ||   showprogress&lt;br /&gt;
|-&lt;br /&gt;
|   admin||   language||   ipaddr||   usecaptcha||   showqnumcode||   allowjumps&lt;br /&gt;
|-&lt;br /&gt;
|   active||   additional_languages ||   refurl||   usetokens||   bouncetime||   navigationdelay&lt;br /&gt;
|-&lt;br /&gt;
|   expires||   datestamp||   datecreated||   bounce_email||   bounceprocessing||   nokeyboard&lt;br /&gt;
|-&lt;br /&gt;
|   startdate||   usecookie||   publicstatistics||   attributedescriptions||   bounceaccounttype||   alloweditaftercompletion&lt;br /&gt;
|-&lt;br /&gt;
|   adminemail||   allowregister||   publicgraphs||   emailresponseto||   bounceaccounthost||   googleanalyticsstyle&lt;br /&gt;
|-&lt;br /&gt;
|   anonymized||   allowsave||   listpublic||   emailnotificationto||   bounceaccountpass||   googleanalyticsapikey&lt;br /&gt;
|-&lt;br /&gt;
|   faxto||   autonumber_start||   htmlemail||   tokenlength||   bounceaccountencryption||&lt;br /&gt;
|-&lt;br /&gt;
|format||   autoredirect||   sendconfirmation||   showxquestions||   bounceaccountuser||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_survey_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveySettings     (array),    An assosiative array with the name-value  pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of the change for each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
Properties available for changing are all those defined in get_survey_properties with the following exceptions&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|properties not allowed to be modified|| Properties not allowed to be modified when survey active&lt;br /&gt;
|-&lt;br /&gt;
|sid||anonymized&lt;br /&gt;
|-&lt;br /&gt;
|language||datestamp&lt;br /&gt;
|-&lt;br /&gt;
|additional_languages||savetimings&lt;br /&gt;
|-&lt;br /&gt;
|active||ipaddr&lt;br /&gt;
|-&lt;br /&gt;
|||refurl&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_surveys==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to list the ids and info of surveys belonging to a user.&lt;br /&gt;
&lt;br /&gt;
    * If user is admin he can get surveys of every user (parameter sUser) or all surveys (sUser=null)&lt;br /&gt;
&lt;br /&gt;
    * Else only the syrveys belonging to the user requesting will be shown.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
sUser (string) -  The users surveys to list&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Survey&#039;s properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid user&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No surveys found&lt;br /&gt;
&lt;br /&gt;
Survey&#039;s properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|property||type&lt;br /&gt;
|-&lt;br /&gt;
|sid||integer&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_title||string&lt;br /&gt;
|-&lt;br /&gt;
|startdate||date&lt;br /&gt;
|-&lt;br /&gt;
|expires||date&lt;br /&gt;
|-&lt;br /&gt;
|active||y/n&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==activate_survey==&lt;br /&gt;
&lt;br /&gt;
RPC Routine that launches a newly created survey (sets active -available for users)&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (array) The result of the activation&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Activation Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==export_statistics==&lt;br /&gt;
&lt;br /&gt;
RPC routine to export statistics of a survey to a user.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
docType (string) - Type of document to generate&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional language of the survey to use (if not set, default language is selected)&lt;br /&gt;
&lt;br /&gt;
graph (string) - Optional parameter to enable graphs (0|1)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==get_summary==&lt;br /&gt;
&lt;br /&gt;
RPC routine to get survey summary, regarding token usage and survey participation.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
sStatname (string) - The statistic to return&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
*On success: (string) Base64 encoded string with the statistics file&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**No available data&lt;br /&gt;
**No such property&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available statistics:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Survey stats||Token stats&lt;br /&gt;
|-&lt;br /&gt;
|completed_responses||token_count&lt;br /&gt;
|-&lt;br /&gt;
|incomplete_responses||token_invalid&lt;br /&gt;
|-&lt;br /&gt;
|full_responses||tokens_sent&lt;br /&gt;
|-&lt;br /&gt;
|||token_opted_out&lt;br /&gt;
|-&lt;br /&gt;
|||token_completed&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==add_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add a language to an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) - The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the new language to be added. Note: If the language is already in that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Error&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_survey_language==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a language of an existing survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
SurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aLanguage (string) - The language shortcut for the language to be removed. Note: If the language is not part of that survey no error will be thrown.&lt;br /&gt;
&lt;br /&gt;
Return values:&lt;br /&gt;
*On success: (array) status=&amp;gt;OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Cannot remove base language&lt;br /&gt;
**Error&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid session key&lt;br /&gt;
&lt;br /&gt;
==get_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to get survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleSettings     (array) -  An array with the properties to return&lt;br /&gt;
&lt;br /&gt;
slang (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) the requested value&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_survey_id            ||    surveyls_url                  ||    surveyls_email_register_subj  ||    email_admin_notification_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_language             ||    surveyls_urldescription       ||    surveyls_email_register       ||    email_admin_notification&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_title                ||    surveyls_email_invite_subj    ||    surveyls_email_confirm_subj   ||    email_admin_responses_subj&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_description          ||    surveyls_email_invite         ||    surveyls_email_confirm        ||    email_admin_responses&lt;br /&gt;
|-&lt;br /&gt;
|    surveyls_welcometext          || surveyls_email_remind_subj       ||    surveyls_dateformat           ||    surveyls_numberformat&lt;br /&gt;
|-&lt;br /&gt;
|surveyls_endtext              ||    surveyls_email_remind         ||    surveyls_attributecaptions    ||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_language_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set survey language properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey&lt;br /&gt;
&lt;br /&gt;
aSurveyLocaleData     (array) -  An assosiative array with the key-value pairs of properties to set. Invalid fieldnames or fields that may not be modified are ignored.&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)    - The language to use&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (string) Result for each parameter set&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Allowed Parameters:&lt;br /&gt;
&lt;br /&gt;
All those defined in get-language_properties except:&lt;br /&gt;
*surveyls_language&lt;br /&gt;
*surveyls_survey_id&lt;br /&gt;
&lt;br /&gt;
==add_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to add an empty group with minimum details.&lt;br /&gt;
&lt;br /&gt;
    * Used as a placeholder for importing questions.&lt;br /&gt;
&lt;br /&gt;
    * Returns the groupid of the created group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the surveythat the group will be added&lt;br /&gt;
&lt;br /&gt;
sGroupTitle     (string) -  Name of the new group&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) - Optional description of the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Creation Failed&lt;br /&gt;
&lt;br /&gt;
==delete_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  ID of the survey that the group belongs&lt;br /&gt;
&lt;br /&gt;
sGroupID    (int) -  Id of the group to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the deleted group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**Invalid Group ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Group deletion failed&lt;br /&gt;
&lt;br /&gt;
==import_group==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a group - imports lsg,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey that the group will belong&lt;br /&gt;
&lt;br /&gt;
sImportData     (string) -  String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sGroupDescription (string) -The format of the importfile in the stream (lsg|csv)&lt;br /&gt;
&lt;br /&gt;
sNewGroupName (string) - Optional new name for the group&lt;br /&gt;
&lt;br /&gt;
sNewGroupDescription (string) - Optional new description for the group&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) The ID of the new group&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Error:Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Error: Invalid LimeSurvey group structure XML&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Import Error&lt;br /&gt;
&lt;br /&gt;
==get_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to get properties of&lt;br /&gt;
&lt;br /&gt;
aGroupSettings     (array) -  Array containing the properties to request.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||description&lt;br /&gt;
|-&lt;br /&gt;
|sid||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_group_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a group of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iGroupID (integer) -  The id of the group to set properties to&lt;br /&gt;
&lt;br /&gt;
aGroupData     (array) -  Assosiative Array containing key-value pairs of the properties to set.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The result of each set action&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Error: Invalid group ID&lt;br /&gt;
**No valid Data&lt;br /&gt;
**Group with dependencies - Order cannot be changed&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
Available properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| ||&lt;br /&gt;
|-&lt;br /&gt;
|||description&lt;br /&gt;
|-&lt;br /&gt;
|||language&lt;br /&gt;
|-&lt;br /&gt;
|group_name||randomization_group&lt;br /&gt;
|-&lt;br /&gt;
|group_order||grelevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_groups==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of groups belonging to survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (integer) -  The id of the survey to get groups of&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the groups&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid Survey ID&lt;br /&gt;
**No groups found&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
&lt;br /&gt;
==delete_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int)id of the deleted Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
** Invalid question ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Cannot delete Question. Others rely on this question&lt;br /&gt;
**Error&lt;br /&gt;
&lt;br /&gt;
==import_question==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to import a question - imports lsq,csv&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
iGroupID (int) - Id of the group that the new questions belongs&lt;br /&gt;
&lt;br /&gt;
sImportData (string) - String containing the BASE 64 encoded data of a lsg,csv&lt;br /&gt;
&lt;br /&gt;
sImportDataType (string)  - Format of the input stream (lsq,csv)&lt;br /&gt;
&lt;br /&gt;
sMandatory (string) - Optional Mandatory question option (default to No)&lt;br /&gt;
&lt;br /&gt;
sNewQuestionTitle (string) - Optional new title for the question&lt;br /&gt;
&lt;br /&gt;
sNewqQuestion (string) - An optional new question&lt;br /&gt;
&lt;br /&gt;
sNewQuestionHelp (string) - An optional new question help text&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (int) Id of the new Question&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Invalid group ID&lt;br /&gt;
**Survey is active and not editable&lt;br /&gt;
**Invalid extension&lt;br /&gt;
**Invalid LimeSurvey question structure XML&lt;br /&gt;
&lt;br /&gt;
==get_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return properties of a question of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string)  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionSettings (array) The properties to get&lt;br /&gt;
&lt;br /&gt;
sLanguage (string) Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The requested properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|gid||type||help||language&lt;br /&gt;
|-&lt;br /&gt;
|parent_qid||title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|sid||question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|gid||preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|subquestions||attributes||attributes_lang||answeroptions&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_question_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set question properties&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iQuestionID  (int) - Id of the question to get properties of&lt;br /&gt;
&lt;br /&gt;
aQuestionData (array)  - An array with the particular fieldnames as keys and their values to set on that particular question&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The resilt of the set of each property&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Questions with dependencies - Order cannot be changed&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Properties:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|  ||  ||&lt;br /&gt;
|-&lt;br /&gt;
|help|| ||&lt;br /&gt;
|-&lt;br /&gt;
|title||other||scale_id&lt;br /&gt;
|-&lt;br /&gt;
|question||mandatory||same_default&lt;br /&gt;
|-&lt;br /&gt;
|preg||question_order||relevance&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_questions==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return the ids and info of questions of a survey/group.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
iGroupID  (int) - Id of the group to get questions of&lt;br /&gt;
&lt;br /&gt;
sLanguage (string)  -  Optional parameter language for multilingual questions&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) The list of the questions&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid questionid&lt;br /&gt;
**Invalid language&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Missmatch in surveyid and groupid&lt;br /&gt;
**No questions found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
Activate tokens&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
session key (string) The session key&lt;br /&gt;
&lt;br /&gt;
surveyid (string) The survey ID&lt;br /&gt;
&lt;br /&gt;
additional_attributes (array of integers) Any additional attribute fields to create. Just give the attribute IDs&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) status OK&lt;br /&gt;
*On failure: (array) Any other status&lt;br /&gt;
&lt;br /&gt;
==add_participants==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new entries to your token table. You can also set if for these new entries a token key is automatically created. Please note that this function does not check for duplicate content in any of the fields, except for token keys created by the function itself.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sessionkey (string) - The session key&lt;br /&gt;
*surveyID (string) - The survey id&lt;br /&gt;
*participantData (array) -  2-dimensional array/structure containing your participants data&lt;br /&gt;
*createTokenKey (boolean) - Set this to true if you want a token key create automatically for each entry - if your participant data included a [token] field it will be overwritten&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success:  participant data (struct) -  structure containing your participants data plus the token ID and (if applicable) the new token&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
&lt;br /&gt;
JSON-RPC example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;add_participants&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;sessionkey&amp;quot;:&amp;quot;73e8rx864rnxmk64gp67bah44u2igivm&amp;quot;,&amp;quot;surveyID&amp;quot;:&amp;quot;668138&amp;quot;,&amp;quot;participantData&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;}]}}&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;result&amp;quot;:[{&amp;quot;email&amp;quot;:&amp;quot;me@example.com&amp;quot;,&amp;quot;lastname&amp;quot;:&amp;quot;Bond&amp;quot;,&amp;quot;firstname&amp;quot;:&amp;quot;James&amp;quot;,&amp;quot;tid&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;token&amp;quot;:&amp;quot;auc82gar58dpcg6&amp;quot;}],&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==delete_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to delete multiple participants of a Survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID (int) - Id of the survey to get questions of&lt;br /&gt;
&lt;br /&gt;
aTokenIDs  (array) - IId of the tokens/participants to delete&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of deletion status for each participant&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
&lt;br /&gt;
==get_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to return settings of a token/participant of a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to get token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to check&lt;br /&gt;
&lt;br /&gt;
aTokenProperties (array) - The properties to get&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of requested values&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|tid||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set_participant_properties==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to set properties of a survey participant/token&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the Survey to set token properties&lt;br /&gt;
&lt;br /&gt;
iTokenID (int) - Id of the participant to alter&lt;br /&gt;
&lt;br /&gt;
aTokenData (array) - Key - value pair of the properties to set&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of results of changing properties&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**Invalid tokenid&lt;br /&gt;
**No valid Data&lt;br /&gt;
&lt;br /&gt;
Available Parameters:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|   ||   ||&lt;br /&gt;
|-&lt;br /&gt;
|||   token||   completed&lt;br /&gt;
|-&lt;br /&gt;
| participant_id ||   language||   usesleft&lt;br /&gt;
|-&lt;br /&gt;
|firstname||   blacklisted||   validfrom&lt;br /&gt;
|-&lt;br /&gt;
|   lastname||   sent||   validuntil&lt;br /&gt;
|-&lt;br /&gt;
|email||   remindersent||   mpid&lt;br /&gt;
|-&lt;br /&gt;
|emailstatus||   remindercount||   &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==list_participants==&lt;br /&gt;
&lt;br /&gt;
RPC routine to return the IDs and info of token/participants of a survey.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
   sSessionKey (string) -  Auth credentials&lt;br /&gt;
   iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
   iStart (int) - Start id of the token list&lt;br /&gt;
   iLimit (int) - Number of participants to return&lt;br /&gt;
   bUnused (bool) - If you want unused tokensm, set true&lt;br /&gt;
   aAttributes(bool|array) An array of extended attributes that can be requested, besides the default ones (default value to false)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Array of Participants info&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No Tokens found&lt;br /&gt;
&lt;br /&gt;
==activate_tokens==&lt;br /&gt;
&lt;br /&gt;
RPC routine to to initialise the survey&#039;s collection of tokens where new participant tokens may be later added&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to list participants&lt;br /&gt;
&lt;br /&gt;
aAttributeFields (array) - An array of integer describing any additional attribute fields&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array) Status OK&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**Token table could not be created&lt;br /&gt;
&lt;br /&gt;
==invite_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to invite participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==remind_participants==&lt;br /&gt;
&lt;br /&gt;
RPC Routine to send reminder for participants in a survey&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) -  Auth credentials&lt;br /&gt;
&lt;br /&gt;
iSurveyID  (int) - Id of the survey to send invitation to participants&lt;br /&gt;
&lt;br /&gt;
iMinDaysBetween (int) - Optional parameter days from last reminder&lt;br /&gt;
&lt;br /&gt;
iMaxReminders (int) - Optional parameter Maximum reminders count&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: (array)  Array of result of each email send action and count of invitations left to send&lt;br /&gt;
*On failure: (array) Failure status&lt;br /&gt;
**Invalid session key&lt;br /&gt;
**No permission&lt;br /&gt;
**Invalid survey ID&lt;br /&gt;
**No token table&lt;br /&gt;
**No candidate tokens&lt;br /&gt;
&lt;br /&gt;
==add_response==&lt;br /&gt;
&lt;br /&gt;
Using this function you can add new responses to your survey response table.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*sSessionKey (string) - The session key&lt;br /&gt;
*iSurveyID (integer) - The survey id&lt;br /&gt;
*aResponseData (array) -  array/structure containing your response data&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
*On success: response_id (integer) -  Returns the id of the inserted survey response&lt;br /&gt;
*On failure: (array) with error description&lt;br /&gt;
&lt;br /&gt;
==export_responses==&lt;br /&gt;
&lt;br /&gt;
Export response data to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc, html&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
FromResponse (int) - Optional start number of response&lt;br /&gt;
&lt;br /&gt;
ToResponse (int) - Optional end number of responses&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
Note: If you have huge response sets try only to request a certain number of records at a time otherwise the server may run out of memory.&lt;br /&gt;
&lt;br /&gt;
==export_responses_by_token==&lt;br /&gt;
&lt;br /&gt;
Export responses data of specific token to pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
sSessionKey (string) - Auth credentials&lt;br /&gt;
&lt;br /&gt;
SurveyID (int) - Id of the Survey&lt;br /&gt;
&lt;br /&gt;
DocumentType (string) - pdf,csv,xls,doc&lt;br /&gt;
&lt;br /&gt;
sToken (string) - Token string of a candidate&lt;br /&gt;
&lt;br /&gt;
sLanguageCode (string) - Optional The language to be used - if not given then the base language will be used&lt;br /&gt;
&lt;br /&gt;
CompletionStatus (string) - Optional &#039;complete&#039;,&#039;incomplete&#039; or &#039;all&#039; selection of responses - defaults to complete&lt;br /&gt;
&lt;br /&gt;
HeadingType (string) - &#039;code&#039;,&#039;full&#039; or &#039;abbreviated&#039;. type of question heading. Optional defaults to &#039;code&#039;&lt;br /&gt;
&lt;br /&gt;
ResponseType (string) - &#039;short&#039; or &#039;long&#039; response type.Optional defaults to &#039;short&#039;&lt;br /&gt;
&lt;br /&gt;
aFields (array) - Optional Selected fields&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
&lt;br /&gt;
On success: Requested file as base 64-encoded string.&lt;br /&gt;
&lt;br /&gt;
On failure: Array with error information&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
To test you will have to activate JSON-RPC in global settings. To run a simple self-test go to&lt;br /&gt;
&lt;br /&gt;
http://path_to_your_limesurvey_installation/index.php/admin/remotecontrol/test . This will import the example survey, do various things with it and delete it afterwards.&lt;br /&gt;
&lt;br /&gt;
The test assumes that you still are using the standard user &#039;admin&#039; with password &#039;password&#039;.&lt;br /&gt;
&lt;br /&gt;
The client function for this test can be found in /application/controller/admin/remotecontrol.php and the particular function is called test().&lt;br /&gt;
&lt;br /&gt;
=Ruby Example=&lt;br /&gt;
&lt;br /&gt;
==Load Requirements and Declare Values==&lt;br /&gt;
You will first need to require the dependencies needed to establish communication with the API. Also, note that there is a username and password field that requires to be stored in plain text. I have a separate API User within my LimeSurvey to handle these calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env ruby&lt;br /&gt;
&lt;br /&gt;
require &#039;net/https&#039;&lt;br /&gt;
require &#039;uri&#039;&lt;br /&gt;
require &#039;json&#039;&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;api_user&amp;quot;&lt;br /&gt;
password = &amp;quot;api_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Module==&lt;br /&gt;
&lt;br /&gt;
The below code is used to define the module LimeSurvey. Within this module is an API class. We will use this to create an instance of this module and then call on the API call wherever needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
module LimeSurvey&lt;br /&gt;
  class API&lt;br /&gt;
    def initialize(service_url)&lt;br /&gt;
      @uri = URI.parse(service_url)&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def method_missing(name, *args)&lt;br /&gt;
      post_body = { &#039;method&#039; =&amp;gt; name, &#039;params&#039; =&amp;gt; args, &#039;id&#039; =&amp;gt; &#039;jsonrpc&#039; }.to_json&lt;br /&gt;
      resp = JSON.parse( http_post_request(post_body) )&lt;br /&gt;
      raise JSONRPCError, resp[&#039;error&#039;] if resp[&#039;error&#039;]&lt;br /&gt;
      resp[&#039;result&#039;]&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
    def http_post_request(post_body)&lt;br /&gt;
      http    = Net::HTTP.new(@uri.host, @uri.port)&lt;br /&gt;
      request = Net::HTTP::Post.new(@uri.request_uri)&lt;br /&gt;
      request.content_type = &#039;application/json&#039;&lt;br /&gt;
      request.body = post_body&lt;br /&gt;
      http.request(request).body&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  class JSONRPCError &amp;lt; RuntimeError; end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==API Call==&lt;br /&gt;
This code is used to create the instance of the LimeSurvey::API module and class. You will want to change the URL to that of your RemoteControl2 URL.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
survey = LimeSurvey::API.new(&#039;http://localhost/limesurvey/index.php?r=admin/remotecontrol&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example takes the above code and puts it into play. I create a new session with the RemoteControl2 API and store the session in the variable session_key. You will want to change the ID numbers to the appropriate Survey ID in the examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
system(&amp;quot;cls&amp;quot;)&lt;br /&gt;
session_key = survey.get_session_key(username,password)&lt;br /&gt;
puts &amp;quot;Session Key: #{session_key}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
response = survey.get_survey_properties(session_key, &amp;quot;863224&amp;quot;, [&amp;quot;owner_id&amp;quot;])&lt;br /&gt;
puts &amp;quot;Properties:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.list_surveys(sSessionKey: session_key, sUser: &amp;quot;dkimura&amp;quot;)&lt;br /&gt;
puts &amp;quot;Survey List:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.add_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;,&lt;br /&gt;
    [email:&amp;quot;james.bond@example.com&amp;quot;,lastname:&amp;quot;Bond&amp;quot;,firstname:&amp;quot;James&amp;quot;]&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Add Participant:  #{response}&amp;quot;&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
response = survey.invite_participants(&lt;br /&gt;
    session_key, &lt;br /&gt;
    &amp;quot;863224&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
puts &amp;quot;Invite Participant:  #{response}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example Return==&lt;br /&gt;
&lt;br /&gt;
From the above example, here is the return that I receive. Some of the items are returned as a hash and some items returned as an array of hashes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
Session Key: piadscbc94vyanxwkdy8f3xii4av2b2w&lt;br /&gt;
&lt;br /&gt;
Properties:  {&amp;quot;owner_id&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Survey List:  [{&amp;quot;sid&amp;quot;=&amp;gt;&amp;quot;863224&amp;quot;, &amp;quot;surveyls_title&amp;quot;=&amp;gt;&amp;quot;Statement of Work v0.12&amp;quot;, &amp;quot;startdate&amp;quot;=&amp;gt;nil, &amp;quot;expires&amp;quot;=&amp;gt;nil, &amp;quot;active&amp;quot;=&amp;gt;&amp;quot;Y&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Add Participant:  [{&amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;lastname&amp;quot;=&amp;gt;&amp;quot;Bond&amp;quot;, &amp;quot;firstname&amp;quot;=&amp;gt;&amp;quot;James&amp;quot;, &amp;quot;tid&amp;quot;=&amp;gt;&amp;quot;7&amp;quot;, &amp;quot;token&amp;quot;=&amp;gt;&amp;quot;pt5ztzxndibkz4j&amp;quot;}]&lt;br /&gt;
&lt;br /&gt;
Invite Participant:  {&amp;quot;7&amp;quot;=&amp;gt;{&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;James Bond&amp;quot;, &amp;quot;email&amp;quot;=&amp;gt;&amp;quot;james.bond@example.com&amp;quot;, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;OK&amp;quot;}, &amp;quot;status&amp;quot;=&amp;gt;&amp;quot;0 left to send&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PHP Example=&lt;br /&gt;
&lt;br /&gt;
To include JSON-RPC in your application, you can write an application based on the tiny jsonRPCClient from [http://jsonrpcphp.org/ | jsonrpcphp.org]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once &#039;jsonRPCClient.php&#039;;&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_BASEURL&#039;, &#039;http://localhost/limesurvey/&#039;);  // adjust this one to your actual LimeSurvey URL&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_USER&#039;, &#039;rpcuser&#039; );&lt;br /&gt;
&lt;br /&gt;
define( &#039;LS_PASSWORD&#039;, &#039;mypassword&#039; );&lt;br /&gt;
&lt;br /&gt;
// the survey to process&lt;br /&gt;
&lt;br /&gt;
$survey_id=374699;&lt;br /&gt;
&lt;br /&gt;
// instanciate a new client&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient = new jsonRPCClient( LS_BASEURL.&#039;/admin/remotecontrol&#039; );&lt;br /&gt;
&lt;br /&gt;
// receive session key&lt;br /&gt;
&lt;br /&gt;
$sessionKey= $myJSONRPCClient-&amp;gt;get_session_key( LS_USER, LS_PASSWORD );&lt;br /&gt;
&lt;br /&gt;
// receive all ids and info of groups belonging to a given survey&lt;br /&gt;
&lt;br /&gt;
$groups = $myJSONRPCClient-&amp;gt;list_groups( $sessionKey, $survey_id );&lt;br /&gt;
&lt;br /&gt;
print_r($groups, null );&lt;br /&gt;
&lt;br /&gt;
// release the session key&lt;br /&gt;
&lt;br /&gt;
$myJSONRPCClient-&amp;gt;release_session_key( $sessionKey );&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JAVA example=&lt;br /&gt;
To decode and code your json calls you can use the library gson as you can see in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.UnsupportedEncodingException;&lt;br /&gt;
&lt;br /&gt;
import org.apache.http.HttpEntity;&lt;br /&gt;
import org.apache.http.HttpResponse;&lt;br /&gt;
import org.apache.http.client.methods.HttpPost;&lt;br /&gt;
import org.apache.http.entity.StringEntity;&lt;br /&gt;
import org.apache.http.impl.client.DefaultHttpClient;&lt;br /&gt;
import org.apache.http.util.EntityUtils;&lt;br /&gt;
&lt;br /&gt;
import com.google.gson.JsonElement;&lt;br /&gt;
import com.google.gson.JsonObject;&lt;br /&gt;
import com.google.gson.JsonParser;&lt;br /&gt;
&lt;br /&gt;
public class TestHttpClient {&lt;br /&gt;
	&lt;br /&gt;
    public static String parse(String jsonLine) {&lt;br /&gt;
	 JsonElement jelement = new JsonParser().parse(jsonLine);&lt;br /&gt;
	 JsonObject  jobject = jelement.getAsJsonObject();&lt;br /&gt;
	 String result = jobject.get(&amp;quot;result&amp;quot;).toString();&lt;br /&gt;
	 return result;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
    public static void main(String[] args) throws UnsupportedEncodingException {&lt;br /&gt;
      DefaultHttpClient client = new DefaultHttpClient();          &lt;br /&gt;
         &lt;br /&gt;
      HttpPost post = new HttpPost(&amp;quot;http://PATH_OF_YOUR_SERVER/index.php/admin/remotecontrol&amp;quot;);&lt;br /&gt;
      post.setHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
      post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;get_session_key\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;username\&amp;quot;: \&amp;quot;YOUR_USERNAME\&amp;quot;, \&amp;quot;password\&amp;quot;: \&amp;quot;YOUR_PASSWORD\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
      try {&lt;br /&gt;
        HttpResponse response = client.execute(post);&lt;br /&gt;
        if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
            HttpEntity entity = response.getEntity();&lt;br /&gt;
            String sessionKey = parse(EntityUtils.toString(entity));&lt;br /&gt;
            post.setEntity( new StringEntity(&amp;quot;{\&amp;quot;method\&amp;quot;: \&amp;quot;list_groups\&amp;quot;, \&amp;quot;params\&amp;quot;: {\&amp;quot;sSessionKey \&amp;quot;: &amp;quot;+sessionKey+&amp;quot;, \&amp;quot;iSurveyID \&amp;quot;: \&amp;quot;ID_SURVEY\&amp;quot; }, \&amp;quot;id\&amp;quot;: 1}&amp;quot;));&lt;br /&gt;
            response = client.execute(post);&lt;br /&gt;
            if(response.getStatusLine().getStatusCode() == 200){&lt;br /&gt;
                entity = response.getEntity();&lt;br /&gt;
                System.out.println(EntityUtils.toString(entity));&lt;br /&gt;
                }&lt;br /&gt;
           }&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } catch (IOException e) {&lt;br /&gt;
        e.printStackTrace();&lt;br /&gt;
      }&lt;br /&gt;
    }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=JSON-RPC notes=&lt;br /&gt;
&lt;br /&gt;
The content-type of the HTTP request must be application/json.  Most formatting errors or a failure to set the content-type header will result in a null response from the server (not a JSON response).  Below is an example of a valid request and response pair.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Request:&lt;br /&gt;
&lt;br /&gt;
 HTTP headers:&lt;br /&gt;
&lt;br /&gt;
   content-type=application/json&lt;br /&gt;
&lt;br /&gt;
   connection=Keep-Alive&lt;br /&gt;
&lt;br /&gt;
   host=mylimesurveyhost.com&lt;br /&gt;
&lt;br /&gt;
   content-length=65&lt;br /&gt;
&lt;br /&gt;
   user-agent=Apache-HttpClient/4.2.2 (java 1.5)&lt;br /&gt;
&lt;br /&gt;
 Post body:&lt;br /&gt;
&lt;br /&gt;
   {&amp;quot;method&amp;quot;:&amp;quot;get_session_key&amp;quot;,&amp;quot;params&amp;quot;:{&amp;quot;username&amp;quot;:&amp;quot;admin&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;mypassword&amp;quot;},&amp;quot;id&amp;quot;:1}&lt;br /&gt;
&lt;br /&gt;
Response body:&lt;br /&gt;
&lt;br /&gt;
 {&amp;quot;id&amp;quot;:1,&amp;quot;result&amp;quot;:&amp;quot;6htqat38fyr4v7iu72nqgv7xgavkvfcz&amp;quot;,&amp;quot;error&amp;quot;:null}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
2.0a Only three functions are supported right now: getSessionKey, releaseSessionKey, deleteSurvey&lt;br /&gt;
&lt;br /&gt;
2.0b Added function add_participants&lt;br /&gt;
&lt;br /&gt;
2.0RC5 Added import_survey, activate_survey, activate_tokens&lt;br /&gt;
&lt;br /&gt;
2.0 (build 121030) Added subquestions, attributes, attributes_lang and answeroptions properties for get_question_properties&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
for further changes check the Limesurvey release notes, thanks!&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Survey_settings&amp;diff=43940</id>
		<title>Survey settings</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Survey_settings&amp;diff=43940"/>
		<updated>2013-07-01T06:26:52Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Overview= &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
To create a new survey, click on the Add button [[File:add.png]] on the right side of the administration button bar and a &amp;quot;Create New Survey&amp;quot; screen will appear. You can edit most of these settings later again by click the &#039;Edit survey settings&#039; icon [[File:token_manage_30.png]] in the &#039;Survey properties&#039; dropdown menu of the survey toolbar.&lt;br /&gt;
&lt;br /&gt;
=Settings= &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
All survey settings and functions are organized in tabs. The following is a description of each tab and field.&lt;br /&gt;
&lt;br /&gt;
==General== &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Base language&#039;&#039;&#039;: This sets the base language for the survey. Once saved, you cannot change it later. The language-set is the base language for possible translations of the survey. That way you can have multilingual surveys. During survey creation you cannot add additional languages. You will be able do that if you edit the survey properties again, later.&lt;br /&gt;
#&#039;&#039;&#039;Title&#039;&#039;&#039;: This is the brief descriptive name of the survey (ie: &amp;quot;Enterprise Bargaining Survey 2003&amp;quot;, or &amp;quot;Views on Ice Cream&amp;quot;). This title will be displayed on every page of the public survey.&lt;br /&gt;
#&#039;&#039;&#039;Description&#039;&#039;&#039;: This allows you to enter a description of the survey. (ie: &amp;quot;A survey to collect your ideas on the next round of enterprise bargaining&amp;quot; or &amp;quot;A survey to find out the popularity of chocolate ice cream&amp;quot;). You can incorporate HTML elements such as images or videos in this section using the WYSIWYG editor. By default, description is used on invitation email.&lt;br /&gt;
#&#039;&#039;&#039;Welcome message&#039;&#039;&#039;: This allows you to enter a message that will display when a participant first logs into your survey. (ie: &amp;quot;Thank you for taking the time to participate in this survey..&amp;quot;) You can incorporate HTML elements such as images or videos in this section using the WYSIWYG editor.&lt;br /&gt;
#&#039;&#039;&#039;End message&#039;&#039;&#039;: This allows you to enter a message that will display when a participant completes your survey. (ie: &amp;quot;Thank you for completing our survey. We will publish results soon.&amp;quot;). You can incorporate HTML elements such as images or videos in this section using the WYSIWYG editor.&lt;br /&gt;
#&#039;&#039;&#039;End URL&#039;&#039;&#039;: This URL will be presented as a link at the end of the survey, and allows you to direct your participants back to your home page (or, in fact, anywhere). The End URL has to be entered with &amp;quot;http://&amp;quot; at the beginning, eg. http://www.limesurvey.org. &amp;lt;br /&amp;gt;You can use they placeholder {SAVEDID}, {TOKEN}, {SID} and {LANG} in this URL.&amp;lt;br /&amp;gt;SAVEDID is the id assigned to this particular submission, TOKEN is the token used to participate in the survey, SID is the survey ID and LANG is the language code&amp;lt;br /&amp;gt;eg. http://www.limesurvey.org/test.php?var1={SAVEDID}&amp;amp;var2;={TOKEN}&amp;amp;var3;={SID}&amp;amp;lang;={LANG} &amp;lt;br /&amp;gt;From version 1.82+ you can use [[URL fields]] with this field to pass parameters from the start URL to then end URL. &amp;lt;br /&amp;gt;You can also use {INSERTANS:SGQA} in this URL (since 1.82+). This allows adding the response to a specific question in the survey to the final url. This can be useful for sending a response to an external script (ie an email address collected during the survey). eg: &amp;quot;http://www.limesurvey.org/test.php?email={INSERTANS:1234X56X7}&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;URL description&#039;&#039;&#039;: The description for the link using the End URL.&lt;br /&gt;
#&#039;&#039;&#039;Administrator&#039;&#039;&#039;: This is the name of the contact person who administers the survey. It will be included in emails sent out inviting participants to respond.&lt;br /&gt;
#&#039;&#039;&#039;Admin email&#039;&#039;&#039;: This is the email address of the administrator (as above) and is used as the &#039;reply to:&#039; address on any emails sent. You can also enter several email addresses separated with a semicolon - that way survey administrator notifications are sent to more than one person. (Example: &amp;quot;firstaddress@test.com;secondaddress@test.com&amp;quot;)&lt;br /&gt;
#&#039;&#039;&#039;Bounce email&#039;&#039;&#039;: This is the email address where a delivery error notification email should be sent. By default, this is the same as the administrator&#039;s email address. If you want to use a custom script to parse delivery error emails, then use a special Bounce Email address here and automatically process emails reaching this address with your script. This script could then update the Email Status field of the token line corresponding to this email address (see tokens).&lt;br /&gt;
#&#039;&#039;&#039;Fax to&#039;&#039;&#039;: This field is used to give a fax number on the &amp;quot;printable survey&amp;quot; - ie: when you want to send someone a hard copy because they cannot use the online survey.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Caution&#039;&#039;&#039;: the HTML WYSIWYG editor doesn&#039;t allow you to upload files during the survey creation process. Trying to do so will end up with an error message like: &amp;quot;&#039;&#039;This file uploader is disabled&#039;&#039;&amp;quot;. If you need to upload pictures or any other ressources, please do so after survey creation, by editing the newly created survey.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Presentation &amp;amp; navigation== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Format&#039;&#039;&#039;: Choose from &amp;quot;Question by question&amp;quot;, &amp;quot;Group by group&amp;quot; or &amp;quot;All in one&amp;quot;.&lt;br /&gt;
#:[[File:Setting_Pres_Format_EN.png]]&lt;br /&gt;
#*&#039;&#039;&#039;Question by Question&#039;&#039;&#039;: Public survey will display one question per page.&lt;br /&gt;
#*&#039;&#039;&#039;Group by Group&#039;&#039;&#039;: Public survey will display all questions in a group per page. Group at a time surveys still have a separate &amp;quot;welcome&amp;quot; page and &amp;quot;submit&amp;quot; page, like &amp;quot;Question by Question&amp;quot; surveys.&lt;br /&gt;
#*&#039;&#039;&#039;All in one&#039;&#039;&#039;: Public survey will display all questions in one single page. Activated All in one surveys do not have a &amp;quot;welcome&amp;quot; page or &amp;quot;submit&amp;quot; page - the welcome message and submit button all appear on the same page.&lt;br /&gt;
#&#039;&#039;&#039;Template&#039;&#039;&#039;: Choose from the installed templates in your system. The default template is rather dull, but functional. More information on creating your own templates is available [[The template editor|here]].&lt;br /&gt;
#&#039;&#039;&#039;Show welcome screen&#039;&#039;&#039;:  Yes/No. If Yes, then the welcome message defined in Text Elements section will be displayed.    Default is Yes.&lt;br /&gt;
#&#039;&#039;&#039;Navigation delay&#039;&#039;&#039;:  Number of seconds before Previous and Next buttons are enabled.   Default 0 seconds&lt;br /&gt;
#&#039;&#039;&#039;Show &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&amp;lt;&amp;lt; Prev] button&#039;&#039;&#039;: This option defaults to yes, however if you set it to &amp;quot;No&amp;quot; then users will not have the option of moving to a previous page while completing the survey.&lt;br /&gt;
#&#039;&#039;&#039;Show question index / allow jumping&#039;&#039;&#039;:  Yes/No. Default No.  When Yes, an index will be displayed on the right side.    Users can jump to any section in the survey. In 2.05 the options have changed to Disabled / Incremental / Full. Disabled and Incremental represent the current No and Yes options. Full always shows all groups / questions, this allows the user to freely navigate through the survey. This might not work for all kinds of conditions.&lt;br /&gt;
#&#039;&#039;&#039;Keyboard-less operation&#039;&#039;&#039;: By activating this setting there will be a virtual keyboard available for certain question types.&lt;br /&gt;
#&#039;&#039;&#039;Show progress bar&#039;&#039;&#039;: Yes/No.  Default Yes.   Allow the administrator to turn off the Progress bar&lt;br /&gt;
#&#039;&#039;&#039;Participants may print answers?&#039;&#039;&#039;: This option defaults to no. When it is set to yes, a participant can print a summary of responses at submit time.&lt;br /&gt;
#&#039;&#039;&#039;Public statistics&#039;&#039;&#039;: Yes/No.   Default No.   If set to &amp;quot;Yes&amp;quot; users who have submitted the survey will be presented a link to statistics of the current survey. The admin can set which questions should be included at these statistics by [[Advanced question settings#public_statistics|applying the according question attribute]].&lt;br /&gt;
#&#039;&#039;&#039;Show graphs in public statistics&#039;&#039;&#039;: (&#039;&#039;since 1.80&#039;&#039;) Determines if public statistics for this survey include graphs or only show a tabular overview. Creating graphs for huge surveys with lots of answers takes some time and server resources so this is the switch to turn them on/off (default setting: &#039;&#039;off&#039;&#039;).&lt;br /&gt;
#&#039;&#039;&#039;Automatically load URL when survey complete&#039;&#039;&#039;:  Yes/No.  Default No.   If yes, when the survey is submitted, it will automatically redirect to the End URL. The end URL can be defined in the Text Elements Section. Please note that this only works on an active survey.&lt;br /&gt;
#&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:  Yes/No.  Default Yes.   If Yes, the message will be displayed on the Welcome Screen.    This option will not affect the print version.&lt;br /&gt;
#&#039;&#039;&#039;Show group name and/or group description&#039;&#039;&#039;:  Will control the display of Group Names and Descriptions.   This option will not affect the print version. Four Options:&lt;br /&gt;
#*&#039;&#039;&#039;Show Both&#039;&#039;&#039; - Default&lt;br /&gt;
#*&#039;&#039;&#039;Show Group Names Only&#039;&#039;&#039;&lt;br /&gt;
#*&#039;&#039;&#039;Show group description Only&#039;&#039;&#039;&lt;br /&gt;
#*&#039;&#039;&#039;Hide Both&#039;&#039;&#039;&lt;br /&gt;
#&#039;&#039;&#039;Show question number and/or code&#039;&#039;&#039;:&lt;br /&gt;
#*&#039;&#039;&#039;Show Both&#039;&#039;&#039; - Default&lt;br /&gt;
#*&#039;&#039;&#039;Show Question Number Only&#039;&#039;&#039;&lt;br /&gt;
#*&#039;&#039;&#039;Show Question Code Only&#039;&#039;&#039;&lt;br /&gt;
#*&#039;&#039;&#039;Hide Both&#039;&#039;&#039;&lt;br /&gt;
#&#039;&#039;&#039;Show &amp;quot;No answer&amp;quot;&#039;&#039;&#039;: Yes/No.  Default Yes.   When Yes, the No Answer will be displayed as the default option for non-mandatory single-select questions. Be aware that if you switch this off, the participant won&#039;t be able to unselect a chosen answer option in a non-mandatory question.&lt;br /&gt;
&lt;br /&gt;
==Publication &amp;amp; access control== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;List survey publicly&#039;&#039;&#039;: Yes/No.  Default No. When it is set to yes, your survey will be listed in the &#039;available surveys&#039; portal&lt;br /&gt;
# &#039;&#039;&#039;Start date/time&#039;&#039;&#039;: Set this to some date if you want your survey to start on a certain date. The survey will start on midnight of that day and only then will people be able to answer to it. To disable this just clear the date from the input field.&lt;br /&gt;
#&#039;&#039;&#039;Expiry date/time&#039;&#039;&#039;: Set this to some date if you want your survey to expire on a special date. This is the last date on which the public survey script will let people participate. (Example: If you set it for the 31st of December, then people will no longer be able to use the survey script on the 1st of January). To disable this just clear the date from the input field.&lt;br /&gt;
#&#039;&#039;&#039;Set cookie to prevent repeated participation?&#039;&#039;&#039;: If you set this to &#039;Yes&#039;, and your survey does not use a tokens table to control participant access, then a cookie will be saved to the client computer of each survey participant once they have submitted a survey. This cookie will stop the same user on that computer from accessing the survey more than once. There are inherent limitations in the &#039;security&#039; strength of such a system, but, in general, it allows you to retain some control over multiple entries on public surveys.&lt;br /&gt;
#&#039;&#039;&#039;Use CAPTCHA for&#039;&#039;&#039;: With this option you can decide when you want a CAPTCHA to be used. Default is to enable CAPTCHA only for the public Registration page, but you can also enable it before accessing the survey, and before Load/Saving partial answers.&lt;br /&gt;
&lt;br /&gt;
==Notification &amp;amp; data management== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Send basic admin notification email to:&#039;&#039;&#039; and &#039;&#039;&#039;Send detailed admin notification email to:&#039;&#039;&#039; These fields allow you to send notifications or survey responses to additional email addresses once the survey is submitted. You can edit the templates for these emails under &#039;Email templates&#039;. Multiple recipients can be set by seperating the entries with a semicolon (;) - eg &amp;quot;yourname@test.com; myname@test.com;hisname@test.com&amp;quot; OR when using placeholders &amp;quot;yourname@test.com;{INSERTANS:82733X12X73};{TOKEN:EMAIL}&amp;quot;. Make sure that at least your administrator email is set properly in the survey settings - otherwise no email will be sent or there will be an &#039;Invalid address:&#039; message when a participant finishes a survey. Please note that there are three different ways for entering an address:&lt;br /&gt;
##Enter a specific &#039;&#039;email address&#039;&#039; (ie: yourname@test.com)&lt;br /&gt;
##Enter a &#039;&#039;SGQA code&#039;&#039; and the response will be sent to an email address entered as an answer to that particular question (use the format {INSERTANS:9999X88X12}, in the same way you would [[Adding a question#Information from previous answers|Re-use information from previous answers]])&lt;br /&gt;
##Enter a &#039;&#039;Token code&#039;&#039; (only possible if your survey is &#039;&#039;not&#039;&#039; anonymous) and the response will be sent to an email address retrieved from a token field (use the format {TOKEN:EMAIL} or {TOKEN:ATTRIBUTE_1} in the same way you would [[Adding a question#Information from tokens table|Re-use Information from the Tokens Table]])&lt;br /&gt;
##&#039;&#039;As of Version 1.92:&#039;&#039; Enter a valid expression conforming to [[Expression Manager|Expression Manager]] syntax.  This lets you use question code instead of SGQA syntax (for easier readability), plus conditional logic (e.g. route the notifications to different people depending upon the data entered into the survey).&lt;br /&gt;
#&#039;&#039;&#039;Date stamp?&#039;&#039;&#039;: This field allows you to determine whether the survey will datestamp all responses. If you choose &amp;quot;Yes&amp;quot;, then when a response is submitted, a field will be included in that response indicating the time and date that the response was made. (See configuration settings for $timeadjust setting.)&lt;br /&gt;
#&#039;&#039;&#039;Save IP address?&#039;&#039;&#039;: This field allows you to determine whether the survey will save an IP-address for all responses. If you choose &amp;quot;Yes&amp;quot;, then when a response is submitted, a field will be included in that response indicating the ip-address of the participant.&lt;br /&gt;
#&#039;&#039;&#039;Save referrer URL?&#039;&#039;&#039;: This field allows you to determine whether the survey will save the referrer URL for all responses. If you choose &amp;quot;Yes&amp;quot;, then when a response is submitted, a field will be included in that response where this URL is saved. A referrer URL is the URL from which the user was led to your survey URL.&lt;br /&gt;
#&#039;&#039;&#039;Enable assessment mode?&#039;&#039;&#039;: With this setting you can enable/disable [[Assessments|assessments]] for this survey.&lt;br /&gt;
#&#039;&#039;&#039;Save timings&#039;&#039;&#039;: If activate then on survey activation a separate table will be created where timings for your questions will be saved, e.g. how long a user stays on one page during taking the survey.&lt;br /&gt;
#&#039;&#039;&#039;Participant may save and resume later?&#039;&#039;&#039;: This setting allows a participant to save his responses and resume to answer the survey at a later time. Please note that this makes most sense with open surveys or surveys with anonymized answer. If you are using tokens and the survey is not anonymous in most cases it is better to activate &#039;Token-based response persistence&#039; in the token tab.&lt;br /&gt;
#&#039;&#039;&#039;Google Analytics API Key for this survey&#039;&#039;&#039;:  Allows for integration with Google Analytics. The API key can be inserted into templates using {GOOGLE_ANALYTICS_API_KEY}. The full JavaScript that Google Analytics expects (including the key) can be included in templates via {GOOGLE_ANALYTICS_JAVASCRIPT}&lt;br /&gt;
#&#039;&#039;&#039;Google Analytics Style for this Survey&#039;&#039;&#039;:  Choices are:&lt;br /&gt;
##&#039;&#039;&#039;Do not use Google Analytics&#039;&#039;&#039; - so {GOOGLE_ANALYTICS_JAVASCRIPT} is an empty string&lt;br /&gt;
##&#039;&#039;&#039;Default Google Analytics&#039;&#039;&#039; - {GOOGLE_ANALYTICS_JAVASCRIPT} uses the standard Google Analytics code, inserting the proper Google Analytics Key&lt;br /&gt;
##&#039;&#039;&#039;SurveyName-&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;SID]/GroupName&#039;&#039;&#039; - {GOOGLE_ANALYTICS_JAVASCRIPT} contains customized Google Analytics code to log the URL as {SURVEYNAME}-&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;{SID}]/{GROUPNAME}.  This can be  helpful if you want to analyze navigation paths through your survey, time spent per page, and drop-off rates per page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Google API howto&#039;&#039;&#039;:&lt;br /&gt;
# Register/login on Google Analytics (GA): [http://www.google.com/analytics/ www.google.com/analytics/]&lt;br /&gt;
# Create a key (the site should not point to the survey, but to the part before &#039;index.php?&#039;) The key should be UA-xxxxx.&lt;br /&gt;
# Go to your survey&#039;s global settings in LimeSurvey.&lt;br /&gt;
# Put the key in appropriate field (Google Analytics API Key). It&#039;s probably the best to set GA Style to track all pages as you can have more info.&lt;br /&gt;
# You don&#039;t need to do anything in shipped templates, as the {GOOGLE_ANALYTICS_JAVASCRIPT} part is already there.&lt;br /&gt;
# Activate the survey.&lt;br /&gt;
# Do the survey.&lt;br /&gt;
# Go to GA panel mainsite. (select appropriate account in left-hand upper corner if you have more than one). You should see some graphs with the statistics. Beware of the dates in upper right corner.&lt;br /&gt;
&lt;br /&gt;
==Tokens== &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
#&#039;&#039;&#039;Anonymized responses?&#039;&#039;&#039;: This allows you to determine whether responses to your survey are matched up with information from your surveys tokens table, or kept &#039;anonymous&#039;. The default is &#039;No&#039;. If you choose &#039;Yes&#039; then your survey is set to radically anonymize responses - there is really no way to connect answers and participants. Even the admin can&#039;t link response data and participant/token data. However you will always be able to specifically view each response entered by your participants in the survey. Thus individual, but anonymous, statistics is still possible to do. &#039;&#039;&#039;&#039;&#039;Attention:&#039;&#039;&#039;&#039;&#039;: If this feature is activated the response submission date and the token completed date are always set to 1980-01-01 00:00, no matter of other settings. Why? Invalidating the submission date ensures no match with webserver logs where the token key might show up when a survey is started. Invalidating the token completed date makes sure that you can&#039;t align the order of submitted responses to the order of the token date/time.&lt;br /&gt;
#&#039;&#039;&#039;Allow multiple responses or update responses with one token?&#039;&#039;&#039;: Default: No If you activate this setting the participants may return to his survey by clicking the invitation link, even if he already submitted the survey. If survey is anonymous, this add a new responses. If survey is not anonymous, user update existing responses.&lt;br /&gt;
#&#039;&#039;&#039;Enable token-based response persistence&#039;&#039;&#039;: If your survey uses tokens and your responses are not anonymized, then you may want to enable this feature. If you turn this on, then your participants can leave your survey and resume later at any time without using the &#039;Resume later&#039; function - for example if he/she gets distracted or his browser crashes. Upon clicking the invitation link again he will find his survey answers so far still in place when returns to the survey and will even continue on the last page seen.&lt;br /&gt;
#&#039;&#039;&#039;Allow public registration&#039;&#039;&#039;: If you use tokens to control access to your survey, the only people who can use the survey are those who have an entry and a unique token from the token table. If you would like to use tokens, but also allow public registration, set this to &amp;quot;Yes&amp;quot;.  The &amp;quot;Yes&amp;quot; setting will allow a visitor to register his name and email address. The script will create a new entry in your tokens table for this person, then send them an invitation email. The script will ensure that only one person per email address can complete your survey.&lt;br /&gt;
#&#039;&#039;&#039;Use HTML format for token emails?&#039;&#039;&#039;: When set to yes, all emails sent by the token management interface (invite, reminder, confirmation) will be formatted as HTML. You&#039;ll then be able to use rich formatting for this emails. Default is Yes at survey creation. Caution, when you switch on/off this feature, you&#039;ll have to double check that your email templates are still displayed as you want.&lt;br /&gt;
#&#039;&#039;&#039;Set token length to&#039;&#039;&#039;: Usually you don&#039;t need to change this, the default setting of 15 digits (max. supported value: 99) is fine. If changing this setting please enter a number (X) which should be greater than 5 (if the number entered is &amp;lt;5 it will be converted to the default value of 15). When generating tokens all tokens will use a length of X digits.&lt;br /&gt;
&lt;br /&gt;
==Import== &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
Alternatively you can [[Importing a survey structure|import a survey structure]] from this tab on survey creation. You have the option to let LimeSurvey automatically convert relative URLs to local images/media files and INSERTANS tags (recommended).&lt;br /&gt;
&lt;br /&gt;
==Copy== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
Alternatively you can copy an existing survey from this tab on survey creation. You have the option to let LimeSurvey automatically convert relative URLs to local images/media files and INSERTANS tags (recommended). The other options are pretty self-explaining. Please note that when copying a survey the start date and the end date of a survey cleared.&lt;br /&gt;
&lt;br /&gt;
==Panel integration (URL parameters)== &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Please note that this tab is currently not visible on survey creation but only when you edit the survey settings after saving them for the first time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
On this tab you can set which additional URL parameters will be accepted by your survey. If you like you can also save the value as a response of a &amp;quot;Short text question&amp;quot; or &amp;quot;Multiple short text question&amp;quot; type (you will be able to select any short text question to save it to). Even if you do NOT save the value of the URL parameter you will be able to use this parameter in the end URL. Please have a look at the documentation of the End-URL for further information.&lt;br /&gt;
&lt;br /&gt;
==Resources== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
This tab lets you manage files (pictures, media files) that were uploaded in the HTML Editor and it is only visible if you edit a survey - not during survey creation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You can:&lt;br /&gt;
* Browse available files&lt;br /&gt;
* Export files as a ZIP archive&lt;br /&gt;
* Import a ZIP archive of files&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
Important hints:&lt;br /&gt;
* Authorized files extensions are defined in config-defaults.php.&lt;br /&gt;
* Files for the survey are in the upload/surveys/&amp;lt;sid&amp;gt; subdirectory.&lt;br /&gt;
* Uploaded files will only been seen while browsing resources on this survey (groups, questions, answers) not in other surveys or objects (labels).&lt;br /&gt;
* Do not expect this limited visibility to ensure confidentiality of the resources as they are reachable with a simple browser to anyone who know the URL to the file.&lt;br /&gt;
* You can&#039;t import a ZIP file containing subdirectories.&lt;br /&gt;
&lt;br /&gt;
=2nd Step - Additional languages= &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
To add more language to a survey you have to create and save it - then edit it again. Now you can add and remove additional languages to the survey. If you remove a language from a survey the complete contents of that language in that survey is deleted permanently so be careful what you are doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
By clicking on the button &#039;Save and continue&#039; on the first page in the survey settings you will be taken to the language-specific page which lets you change all texts for each language like &#039;&#039;Survey name&#039;&#039;, &#039;&#039;Welcome Text&#039;&#039;, etc. You can also edit the date format which should be used for a certain language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
Previous [[Creating surveys - Introduction]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
Next [[Importing a survey structure]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=43745</id>
		<title>Coding guidelines</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=43745"/>
		<updated>2013-06-28T08:06:52Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: /* Localization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=General=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This is a free development, everything you do can be useful for others. If the feature is very personal there is a way to turn it into a universal solution. This is the challenge!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;quot;The difficulty within a solution is to solve it in a simple way&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Lance Burton, magician)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some general rules:&lt;br /&gt;
*Be efficient and save resources (memory and runtime). Things might work for a small survey but also try out your new feature with a survey that has 400 question, 5 languages and 20,000 responses (Yes, there are surveys like this out there).&lt;br /&gt;
*Keep a fluid dialog with the others coders, they have their own thoughts about what you are doing.&lt;br /&gt;
*Ask if you are in doubt.&lt;br /&gt;
&lt;br /&gt;
=Naming convention=&lt;br /&gt;
*Use the Hungarian Rule for variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[t]NameOfVariable&lt;br /&gt;
&lt;br /&gt;
 | &amp;lt;strike&amp;gt;-&amp;lt;/strike&amp;gt;&amp;lt;strike&amp;gt;+&amp;lt;/strike&amp;gt;----&lt;br /&gt;
&lt;br /&gt;
 |        +--&amp;gt; Descriptive name&lt;br /&gt;
&lt;br /&gt;
 +--&amp;gt; Datatype stored (for example start with &amp;quot;a&amp;quot; if it is an array)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
aQuestionAttributes: Array to store the questions attributes, Mixed values&lt;br /&gt;
&lt;br /&gt;
dSurveyEnds: Date when the survey ends&lt;br /&gt;
&lt;br /&gt;
sContditionsOutput: String used to create the JS for conditions&lt;br /&gt;
*In case a function is declared &#039;&#039;&#039;do not&#039;&#039;&#039; use the Hungarian rule for the function name, instead use &amp;quot;Lower CamelCase&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
function questionsRetrieve( $iQID, $iSurvey)&lt;br /&gt;
*What about files? Unless Yii requires it in some way always name your files in lowercase - this prevents problems on systems using case-aware filesystems&lt;br /&gt;
&lt;br /&gt;
Here a list of prefixes:&lt;br /&gt;
*o=Object&lt;br /&gt;
*a=Array&lt;br /&gt;
*i=Integer&lt;br /&gt;
*f=Float&lt;br /&gt;
*s=String&lt;br /&gt;
&lt;br /&gt;
=Documentation=&lt;br /&gt;
&lt;br /&gt;
Please refer to this introduction: [[How to document your source code]].&lt;br /&gt;
&lt;br /&gt;
=Structures=&lt;br /&gt;
*Indent using spaces instead of TAB, or be gentle to announce how many spaces are your TABs long. There is wide ranging debate about tabs vs. spaces, many people prefer using tabs, others prefer spaces, others are happy with a mix of tabs and spaces. Because LimeSurvey is developed collaboratively, we ask that you leave your preference and follow this standard.&lt;br /&gt;
*The opening curly brace must be below the structure opening:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (condition)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Using one line for a simple condition is very &amp;quot;fashionable&amp;quot;, a taste of &amp;quot;hacker&amp;quot;, but it is not clear at all:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true} else {do false}&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true}&lt;br /&gt;
&lt;br /&gt;
        else {do false}&lt;br /&gt;
&lt;br /&gt;
 RIGHT: if (condition)&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do true&lt;br /&gt;
&lt;br /&gt;
        } else&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do false&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
 RIGHT: swith $sSelector&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
              case X:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
                   break;&lt;br /&gt;
&lt;br /&gt;
              case Y:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
              default:&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: It&amp;amp;acute;s true that sometimes the &amp;quot;WRONG&amp;quot; way can be useful, but if it makes the straight reading difficult, please use the &amp;quot;RIGHT&amp;quot; way instead. Be gentle with your fellow developers.&lt;br /&gt;
*SQL sentences must respect the same rule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $sSQL = &amp;quot;SELECT field1, field2, field3 &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;WHERE condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;AND condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;OR condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;ORDER BY field1, field2&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*The same for HTML in views tags:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;td colspan=&#039;2&#039;&lt;br /&gt;
&lt;br /&gt;
     height=&#039;4&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Some Text&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=HTML=&lt;br /&gt;
*As you will notice, a very customized HTML element can take a lot of lines (very expensive if you paid each one (:wink:) ) to avoid that, use &#039;CSS classes&#039;. In general, use classes to aesthetic related stuff: color, borders, backgrounds, font faces, sizes, etc.&lt;br /&gt;
*Respect W3C standards, and try to use the HTML understandable for all browsers. If one of them has a special feature, think if this feature is so special to break down the HTML in other browsers.&lt;br /&gt;
*Do not use PHP short tags &amp;lt;? ?&amp;gt;. Always use full PHP tags &amp;lt;?php ?&amp;gt;&lt;br /&gt;
*Any rules of the mentioned before: about CSS, well closed HTML tags and JS respect XHTML standards. Give it a try!.&lt;br /&gt;
&lt;br /&gt;
=Localization=&lt;br /&gt;
&lt;br /&gt;
Currently we are using the gT(),eT(),ngT() and neT() functions of the limesurvey_lang object for translations.&lt;br /&gt;
&lt;br /&gt;
Since LimeSurvey is available in 60 languages it is very important that your original English string (which will be picked up automatically for translation by our translators) is done right from the start. Imagine if we have to correct only one string at a later time - then 60 strings become invalid across the project and need to be re-translated by the poor translator souls.&lt;br /&gt;
* gT() is the original translation function. It will return a translated version of the string in the currently selected language. ie: echo &#039;&#039;gT(&amp;quot;Hello&amp;quot;);&#039;&#039;&lt;br /&gt;
* ngT() returns multiple translations of a sentence or phrase for which alternate plural forms may apply. ie: &#039;&#039;echo sprintf(ngT(&#039;Please select at least %s answer&#039;,&#039;Please select at least %s answers&#039;,iMinimumAnswers),$iMinimumAnswers)&#039;&#039;;&lt;br /&gt;
* eT() echos the translation directly. (ie: instead of &#039;&#039;echo gT(&amp;quot;Hello&amp;quot;);&#039;&#039; you can use &#039;&#039;eT(&amp;quot;Hello&amp;quot;);&#039;&#039;&lt;br /&gt;
* neT() echos the multiple translations of the sentence or phrase for which alternate plural forms may apply directly.&lt;br /&gt;
&lt;br /&gt;
Please follow these important rules:&lt;br /&gt;
*&#039;&#039;&#039;Do not embed margin spaces&#039;&#039;&#039; in your translation. Instead use proper CSS formatting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: eT(&#039;Visible? &#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: eT(&#039;Visible?&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not capitalize words&#039;&#039;&#039; except where grammatically correct (like at the beginning of a sentence or for a brand name). LimeSurvey is not a newspaper.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: eT(&#039;Create A New Label Set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: eT(&#039;Create a new label set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: eT(&#039;Google Maps API Key&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: eT(&#039;Google Maps API key&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not concatenate&#039;&#039;&#039; several translations to form a sentence or concatenate to an additional information (like a number or string). Instead use the sprint() or sprintf() function with placeholders.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The sum must not be bigger than&#039;).$iMaxSum;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The sum must not be bigger than %s&#039;),$iMaxSum);&lt;br /&gt;
&lt;br /&gt;
This comes from the problem that in other languages the setting of a sentence can be much different and the information $iMaxSum from the example above might be needed in the middle of the sentence.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The user&#039;).$sUsername.$clang-&amp;gt;gT(&#039;was deleted.&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The user %s was deleted.&#039;),$sUsername);&lt;br /&gt;
*&#039;&#039;&#039;Use the n*T functions where applicable&#039;&#039;&#039;. These functions show a different translation depending the number of items. Currently LimeSurvey only supports the numbers/situations 1 and &amp;gt;1.&lt;br /&gt;
&lt;br /&gt;
+Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;Please select at least %s answer(s).&#039;),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;ngT(&#039;Please select at least %s answer&#039;,&#039;Please select at least %s answers&#039;,iMinimumAnswers),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
=Bug tracker=&lt;br /&gt;
#First consider if the reported issue is really a bug. If it is a feature request please point the reporter to http://ideas.limesurvey.org and set the issue status to &#039;Closed&#039;.&lt;br /&gt;
#If you would like to work on a bug assign it to yourself.&lt;br /&gt;
#Try to reproduce the issue.&lt;br /&gt;
##If you cannot reproduce ask the user to provide a small example survey to demonstrate the issue. Then set the issue to &#039;Feedback&#039;. After the user added the necessary information it will automatically be set to &#039;Assigned&#039; again.&lt;br /&gt;
##If the user does not responds for more than a week ask once again for feedback by adding a comment. After a further week without feedback close the issue.&lt;br /&gt;
#After you resolved the issue set the status to resolved AND provide the &#039;Fixed in version&#039; information.&lt;br /&gt;
#After you committed your fix add a comment to the resolved issue &#039;Fixed in rev. &amp;lt;Subversion revision number&amp;gt;&#039;&lt;br /&gt;
#After a release the release technician will set all issues to &#039;Closed&#039; that were fixed for this release. That signals to the reporter that a fix is available in the version and it was just released.&lt;br /&gt;
&lt;br /&gt;
=Cross-DB compatibility=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey targets several database types it can run on: MySQL, Postgres and Microsoft SQL Server. This demands certain precautions when coding&lt;br /&gt;
&lt;br /&gt;
==Parameter binding==&lt;br /&gt;
&lt;br /&gt;
Yii/PDO supports parameter binding - use it. Don&#039;t inject variables directly into the query or into conditions because this might create a security issue.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$oResult = Yii::app()-&amp;gt;db&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;createCommand()&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;select(&#039;somefield&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;where(&amp;quot;sid = :sid&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;from(&#039;{{sometable}}&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;bindParam(&amp;quot;:sid&amp;quot;, $surveyid, PDO::PARAM_INT);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you bind the same value several times do NOT use the same parameter name, instead use a different named parameter for each bind:&lt;br /&gt;
&lt;br /&gt;
WRONG:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$oResult = Yii::app()-&amp;gt;db&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;createCommand()&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;select(&#039;somefield&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;where(&amp;quot;sid = :sid and parent_sid= :sid &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;from(&#039;{{sometable}}&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;bindParam(&amp;quot;:sid&amp;quot;, $surveyid, PDO::PARAM_INT);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RIGHT:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$oResult = Yii::app()-&amp;gt;db&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;createCommand()&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;select(&#039;somefield&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;where(&amp;quot;sid = :sid1 and parent_sid= :sid2 &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;from(&#039;{{sometable}}&#039;)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;bindParam(&amp;quot;:sid1&amp;quot;, $surveyid, PDO::PARAM_INT)&lt;br /&gt;
&lt;br /&gt;
                    -&amp;gt;bindParam(&amp;quot;:sid2&amp;quot;, $surveyid, PDO::PARAM_INT);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Miscellaneous=&lt;br /&gt;
*Do not use &amp;quot;global&amp;quot; to access to a declared variable in another process. Pass variables or arrays by reference, use the session or the configuration object.&lt;br /&gt;
*If using an auxiliary variable makes clear the code or process, just do it. If you are coding a very complex expression, calling to functions with parameters that are other functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WRONG:&lt;br /&gt;
&lt;br /&gt;
iAResult= fa(fb(p1,p2),fc(fd(p3),p4),p5)&lt;br /&gt;
&lt;br /&gt;
It will be more readable:&lt;br /&gt;
&lt;br /&gt;
iAuxB = fb(p1,p2)&lt;br /&gt;
&lt;br /&gt;
iAuxD = fd(p3)&lt;br /&gt;
&lt;br /&gt;
iAuxC = fc(iAuxD,p4)&lt;br /&gt;
&lt;br /&gt;
iAResult = fa(iAuxB, iAuxC, p5)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyway, if you are in doubt about someone missing the point or you are afraid that your expression is obscure, take the chance of writing it in a more simple way, even if that involves the use of one or more auxiliary variables.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=2416</id>
		<title>Plugins - advanced</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugins_-_advanced&amp;diff=2416"/>
		<updated>2013-03-05T10:31:38Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Starting from Limesurvey 2.05, Limesurvey will officially support plugins.&lt;br /&gt;
&lt;br /&gt;
Plugins allow users to customize the functionality of their installation while still being able to benefit from regular software updates.&lt;br /&gt;
&lt;br /&gt;
This documentation is meant for developers that are extending Limesurvey for their own use or for their clients; end users will not be helped by this documentation.&lt;br /&gt;
&lt;br /&gt;
Plugins must implement the [https://github.com/LimeSurvey/LimeSurvey/blob/2.05/application/libraries/PluginManager/iPlugin.php iPlugin] interface. We recommend&lt;br /&gt;
&lt;br /&gt;
extending your plugin class from the [https://github.com/LimeSurvey/LimeSurvey/blob/2.05/application/libraries/PluginManager/PluginBase.php PluginBase] class.&lt;br /&gt;
&lt;br /&gt;
By extending you benefit from common functionality required by plugins that we already have implemented for you. One of these function is the implementation of the getPluginSettings function. This function must return an array describing the configuration options for the user.&lt;br /&gt;
&lt;br /&gt;
The example plugin exposes just 1 configurable setting, the message it&#039;ll show.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;protected $settings = array(&lt;br /&gt;
&lt;br /&gt;
       &#039;logo&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
               &#039;type&#039; =&amp;gt; &#039;logo&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;path&#039; =&amp;gt; &#039;assets/logo.png&#039;&lt;br /&gt;
&lt;br /&gt;
           ),&lt;br /&gt;
&lt;br /&gt;
       &#039;message&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
           &#039;type&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
&lt;br /&gt;
           &#039;label&#039; =&amp;gt; &#039;Message&#039;&lt;br /&gt;
&lt;br /&gt;
       )&lt;br /&gt;
&lt;br /&gt;
   );&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array contains a name for each setting as a key. The values are arrays containing the required meta data.&lt;br /&gt;
&lt;br /&gt;
Supported types are:&lt;br /&gt;
&lt;br /&gt;
- logo&lt;br /&gt;
&lt;br /&gt;
- string&lt;br /&gt;
&lt;br /&gt;
- html&lt;br /&gt;
&lt;br /&gt;
- choice&lt;br /&gt;
&lt;br /&gt;
- relevance&lt;br /&gt;
&lt;br /&gt;
Besides type a number of other keys are available:&lt;br /&gt;
&lt;br /&gt;
- label, defines a label (use English, the label specified here will be passed through the translation functions)&lt;br /&gt;
&lt;br /&gt;
- default, defines a value to show if no value is specified.&lt;br /&gt;
&lt;br /&gt;
- current, defines the current value.&lt;br /&gt;
&lt;br /&gt;
- readOnly, specifies the setting is read only.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_signature&amp;diff=2546</id>
		<title>Question signature</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_signature&amp;diff=2546"/>
		<updated>2013-02-25T22:25:17Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Question signature=&lt;br /&gt;
&lt;br /&gt;
Since question types can no longer be uniquely identified their object names, we have created a signature scheme.&lt;br /&gt;
&lt;br /&gt;
While in a single limesurvey instance question objects must be uniquely named, there might be different plugins defining the question objects with the same name.&lt;br /&gt;
&lt;br /&gt;
To make sure we can identify what the type of a question is, we derive a unique identifier (GUID) from a signature.&lt;br /&gt;
&lt;br /&gt;
Each question object MUST therefore define a protected static $signature field. This field is used to derive the signature using a hashing approach.&lt;br /&gt;
&lt;br /&gt;
It is the developers task to make this signature as unique as possible, yet, it MUST never change. If the signature of a question object changes it is recognized as a new question type, while this is not necessarily a problem, the fact that the old question type is no longer available is. Since Limesurvey cannot find the old question type it will not be able to execute, import, or maybe even edit, surveys containing this now unknown question type.&lt;br /&gt;
&lt;br /&gt;
An example of a signature is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
protected static $signature = array(&lt;br /&gt;
&lt;br /&gt;
   &#039;orignalAuthor&#039; =&amp;gt; &#039;Sam Mousa&#039;,&lt;br /&gt;
&lt;br /&gt;
   &#039;originalName&#039; =&amp;gt; &#039;Yes / No&#039;,&lt;br /&gt;
&lt;br /&gt;
   &#039;startDev&#039; =&amp;gt; &#039;2013-30-1&#039;&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that you are free to use any format / data type you want. The GUID is derived using the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* This function derives a unique identifier for identifying a question type.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
public static function getGUID()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // We use json_encode because it is faster than serialize.&lt;br /&gt;
&lt;br /&gt;
   return md5(json_encode(static::$signature));&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_plugins&amp;diff=2541</id>
		<title>Question plugins</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_plugins&amp;diff=2541"/>
		<updated>2013-02-25T22:16:45Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Question object considerations.&lt;br /&gt;
&lt;br /&gt;
Questions are plugins.&lt;br /&gt;
&lt;br /&gt;
   - No difference between core and thirdparty questions&lt;br /&gt;
&lt;br /&gt;
   - Questions can include views.&lt;br /&gt;
&lt;br /&gt;
- MM: All question related texts can make use of placeholders (EM).&lt;br /&gt;
&lt;br /&gt;
Questions can have database columns.&lt;br /&gt;
&lt;br /&gt;
   - A question may define a column type for storing its answer.&lt;br /&gt;
&lt;br /&gt;
Questions may have subquestions.&lt;br /&gt;
&lt;br /&gt;
   - A question may have subquestions; these are Question objects, possible of another type.&lt;br /&gt;
&lt;br /&gt;
   - Questions are rendered recursively; a parent question is responsible for telling its children when to render.&lt;br /&gt;
&lt;br /&gt;
   - Answercolumns are discovered recursively; a parent question is responsible for getting column meta data (upon survey activation) from its children.&lt;br /&gt;
&lt;br /&gt;
Questions may have AnswerSets.&lt;br /&gt;
&lt;br /&gt;
   - Multiple questions may share the same AnswerSet.&lt;br /&gt;
&lt;br /&gt;
   - An answer set is a numerically indexed array; assigning each text option an numeric value.&lt;br /&gt;
&lt;br /&gt;
   - Texts inside answer sets can be localized.&lt;br /&gt;
&lt;br /&gt;
Questions belong to 1 Category.&lt;br /&gt;
&lt;br /&gt;
interface iQuestionPlugin {&lt;br /&gt;
&lt;br /&gt;
   public&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4304</id>
		<title>Defining attributes</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4304"/>
		<updated>2013-02-25T22:15:20Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Defining attributes for question types.=&lt;br /&gt;
&lt;br /&gt;
Attributes for question types are all configurable, non default, aspects of a question. A good example of an attribute is question text.&lt;br /&gt;
&lt;br /&gt;
Question attributes are defined using an array with the name of the attribute as a key. An attribute definition supports several keys.&lt;br /&gt;
*type - string: The data type of the attribute. Supported types are (&#039;html&#039;, &#039;string&#039;, &#039;boolean&#039;, &#039;select&#039;)&lt;br /&gt;
*localized - boolean: Whether this attribute should be configurable per language.&lt;br /&gt;
*advanced - boolean: Whether this attribute should be shown in the default or advanced tab.&lt;br /&gt;
*label - string: The label of the attribute in English (this is localized by the admin interface).&lt;br /&gt;
*options - array(string-string): Contains the options for an attribute of type &#039;select&#039;.&lt;br /&gt;
*default - mixed: Contains the default value for the attribute.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
protected $attributes = array(&lt;br /&gt;
&lt;br /&gt;
   &#039;question&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Question text:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;help&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Help text:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;mandatory&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;boolean&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Mandatory:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;display&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Display using:&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt;  &#039;select&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;options&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
           &#039;radio&#039; =&amp;gt; &#039;Radio buttons&#039;,&lt;br /&gt;
&lt;br /&gt;
           &#039;dropdown&#039; =&amp;gt; &#039;Dropdown list&#039;&lt;br /&gt;
&lt;br /&gt;
       ),&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
       &#039;advanced&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
       &#039;default&#039; =&amp;gt; &#039;dropdown&#039;&lt;br /&gt;
&lt;br /&gt;
   )&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4305</id>
		<title>Defining attributes</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4305"/>
		<updated>2013-02-25T22:12:30Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Defining attributes for question types.=&lt;br /&gt;
&lt;br /&gt;
Attributes for question types are all configurable, non default, aspects of a question. A good example of an attribute is question text.&lt;br /&gt;
&lt;br /&gt;
Question attributes are defined using an array with the name of the attribute as a key. An attribute definition supports several keys.&lt;br /&gt;
*type - string: The data type of the attribute. Supported types are (&#039;html&#039;, &#039;string&#039;, &#039;boolean&#039;, &#039;select&#039;)&lt;br /&gt;
*localized - boolean: Whether this attribute should be configurable per language.&lt;br /&gt;
*advanced - boolean: Whether this attribute should be shown in the default or advanced tab.&lt;br /&gt;
*label - string: The label of the attribute in English (this is localized by the admin interface).&lt;br /&gt;
*options - array(string-string): Contains the options for an attribute of type &#039;select&#039;.&lt;br /&gt;
*default - mixed: Contains the default value for the attribute.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
protected $attributes = array(&lt;br /&gt;
&lt;br /&gt;
   &#039;question&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Question text:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;help&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Help text:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;mandatory&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt; &#039;boolean&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Mandatory:&#039;&lt;br /&gt;
&lt;br /&gt;
   ),&lt;br /&gt;
&lt;br /&gt;
   &#039;display&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
       &#039;label&#039; =&amp;gt; &#039;Display using:&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;type&#039; =&amp;gt;  &#039;select&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;options&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
           &#039;radio&#039; =&amp;gt; &#039;Radio buttons&#039;,&lt;br /&gt;
&lt;br /&gt;
           &#039;dropdown&#039; =&amp;gt; &#039;Dropdown list&#039;&lt;br /&gt;
&lt;br /&gt;
       ),&lt;br /&gt;
&lt;br /&gt;
       &#039;localized&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
       &#039;advanced&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
       &#039;default&#039; =&amp;gt; &#039;dropdown&#039;&lt;br /&gt;
&lt;br /&gt;
   )&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4306</id>
		<title>Defining attributes</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Defining_attributes&amp;diff=4306"/>
		<updated>2013-02-25T22:11:48Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Defining attributes for question types.=&lt;br /&gt;
&lt;br /&gt;
Attributes for question types are all configurable, non default, aspects of a question. A good example of an attribute is question text.&lt;br /&gt;
&lt;br /&gt;
Question attributes are defined using an array with the name of the attribute as a key. An attribute definition supports several keys.&lt;br /&gt;
*type - string: The data type of the attribute. Supported types are (&#039;html&#039;, &#039;string&#039;, &#039;boolean&#039;, &#039;select&#039;)&lt;br /&gt;
*localized - boolean: Whether this attribute should be configurable per language.&lt;br /&gt;
*advanced - boolean: Whether this attribute should be shown in the default or advanced tab.&lt;br /&gt;
*label - string: The label of the attribute in English (this is localized by the admin interface).&lt;br /&gt;
*options - array(string-string): Contains the options for an attribute of type &#039;select&#039;.&lt;br /&gt;
*default - mixed: Contains the default value for the attribute.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;protected $attributes = array(&lt;br /&gt;
&lt;br /&gt;
           &#039;question&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
               &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
               &#039;label&#039; =&amp;gt; &#039;Question text:&#039;&lt;br /&gt;
&lt;br /&gt;
           ),&lt;br /&gt;
&lt;br /&gt;
           &#039;help&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
               &#039;type&#039; =&amp;gt; &#039;html&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;localized&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
               &#039;label&#039; =&amp;gt; &#039;Help text:&#039;&lt;br /&gt;
&lt;br /&gt;
           ),&lt;br /&gt;
&lt;br /&gt;
           &#039;mandatory&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
               &#039;type&#039; =&amp;gt; &#039;boolean&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;label&#039; =&amp;gt; &#039;Mandatory:&#039;&lt;br /&gt;
&lt;br /&gt;
           ),&lt;br /&gt;
&lt;br /&gt;
           &#039;display&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
               &#039;label&#039; =&amp;gt; &#039;Display using:&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;type&#039; =&amp;gt;  &#039;select&#039;,&lt;br /&gt;
&lt;br /&gt;
               &#039;options&#039; =&amp;gt; array(&lt;br /&gt;
&lt;br /&gt;
                   &#039;radio&#039; =&amp;gt; &#039;Radio buttons&#039;,&lt;br /&gt;
&lt;br /&gt;
                   &#039;dropdown&#039; =&amp;gt; &#039;Dropdown list&#039;&lt;br /&gt;
&lt;br /&gt;
               ),&lt;br /&gt;
&lt;br /&gt;
               &#039;localized&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
               &#039;advanced&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
               &#039;default&#039; =&amp;gt; &#039;dropdown&#039;&lt;br /&gt;
&lt;br /&gt;
           )&lt;br /&gt;
&lt;br /&gt;
       );&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_Objects&amp;diff=2536</id>
		<title>Question Objects</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_Objects&amp;diff=2536"/>
		<updated>2013-02-25T21:40:16Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=DEPRECATED DEPRECATED DEPRECATED DEPRECATED=&lt;br /&gt;
&lt;br /&gt;
As of LimeSurvey 2.0, questions type were internally identified by a single character. That is, a display question was represented by &#039;X&#039; while a list question was represented by &#039;L&#039; etc. Unfortunately, this made adding and altering question types incredibly difficult since code for each question type was spread across literally dozens of files. To make it easier for independent developers to add and modify question types, each question will have it&#039;s own class in the application/modules folder. These classes will contain all question-type-specific code.&lt;br /&gt;
&lt;br /&gt;
There are 3 abstract question classes: QuestionModule, ArrayQuestion, and TextQuestion. All the question classes (including Array and Text) extend QuestionModule and end in &amp;quot;Question.&amp;quot; Below is a list of class names and descriptions.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Description||Class Prefix||Legacy Character Code||Parent (if blank assume QuestionModule)&lt;br /&gt;
|-&lt;br /&gt;
|5 point choice||FiveList||5||&lt;br /&gt;
|-&lt;br /&gt;
|List (dropdown)||Select||!||List&lt;br /&gt;
|-&lt;br /&gt;
|List (radio)||List||L||&lt;br /&gt;
|-&lt;br /&gt;
|List with comment||CommentList||O||List&lt;br /&gt;
|-&lt;br /&gt;
|Array||RadioArray||F||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (10 point choice)||TenRadioArray||B||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (5 point choice)||FiveRadioArray||A||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (Increase/Same/Decrease)||IDRadioArray||E||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (Numbers)||NumberArray||:||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (Texts)||TextArray||;||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (Yes/No/Uncertain)||YNRadioArray||C||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array by column||ColumnRadioArray||H||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array dual scale||DualRadioArray||1||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Date/Time||Date||D||&lt;br /&gt;
|-&lt;br /&gt;
|Equation||Equation||*||&lt;br /&gt;
|-&lt;br /&gt;
|File upload||File||pipe character||&lt;br /&gt;
|-&lt;br /&gt;
|Gender||Gender||G||&lt;br /&gt;
|-&lt;br /&gt;
|Language switch||Language||I||&lt;br /&gt;
|-&lt;br /&gt;
|Multiple numerical input||Multinumerical||K||&lt;br /&gt;
|-&lt;br /&gt;
|Numerical input||Numerical||N||&lt;br /&gt;
|-&lt;br /&gt;
|Ranking||Ranking||R||&lt;br /&gt;
|-&lt;br /&gt;
|Text display||Display||X||&lt;br /&gt;
|-&lt;br /&gt;
|Yes/No||YN||Y||&lt;br /&gt;
|-&lt;br /&gt;
|Huge free text||HugeText||U||Text&lt;br /&gt;
|-&lt;br /&gt;
|Long free text||LongText||T||Text&lt;br /&gt;
|-&lt;br /&gt;
|Multiple short text||Multitext||Q&lt;br /&gt;
|-&lt;br /&gt;
|Short free text||ShortText||S||Text&lt;br /&gt;
|-&lt;br /&gt;
|Multiple choice||Check||M||&lt;br /&gt;
|-&lt;br /&gt;
|Multiple choice with comments||CommentCheck||P||Check&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each of these classes contains (or inherits) a number of public methods that are abstracted by the QuestionModule class. To execute this question specific code, the question class is loaded out of the database, the object is dynamically instantiated and the relevant function is called. The question objects store question id, group id, survey id, question text, and other relevant data. Question objects then become a very useful way to pass around data instead of the previously used arrays.&lt;br /&gt;
&lt;br /&gt;
These question objects come with two new database tables. First, a question types table stores a list of type ids, group ids, description, and legacy character code. There is a new int tid column in the questions table that replaces the type column and maps to the tid column in the new question types table. In addition, there is a new question type groups table that contains a group id, a description, and an order. This configuration will allow for backend configuration in the future, and ultimately, custom question types that can be shared among the community.&lt;br /&gt;
&lt;br /&gt;
One of the biggest advantages of switching from procedural code to object-oriented code is that it will both allow developers to easily create custom question types by extending any of the existing question types. In order to do this, a developer can either extend one of the predefined question types and override one or more of the methods (such as getAnswerHTML() which returns the HTML code that renders each question) or by extending the base QuestionModule class or one of the other abstract classes and implementing its abstract methods.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Abstract Method&amp;amp;dagger;||Functionality&lt;br /&gt;
|-&lt;br /&gt;
|getAnswerHTML||Returns the HTML for the question&lt;br /&gt;
|-&lt;br /&gt;
|getDataEntry||Returns the HTML for manually entering survey data from the backend&lt;br /&gt;
|-&lt;br /&gt;
|availableAttributes||Returns an array of attributes the question can have in the question_attributes table&lt;br /&gt;
|-&lt;br /&gt;
|questionProperties||Returns an array of question properties including description, group name, whether the class has subquestions, css class name, whether the class has default values, whether the class is assessable, and whether the class has answer scales&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;dagger;Once the porting of the question objects is completed, a table will be added with a complete list of methods both abstract and extendable.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Naming_conventions&amp;diff=2234</id>
		<title>Naming conventions</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Naming_conventions&amp;diff=2234"/>
		<updated>2013-01-18T21:18:41Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Having moved to a (partial) MVC architecture we should adopt some conventions for naming our models and controllers. I realize that functionally naming conventions don&#039;t have any benefit, however they do increase maintainability. Currently we don&#039;t have naming conventions (or I am unaware of them AND they have not been consistently obeyed in the current code base).&lt;br /&gt;
&lt;br /&gt;
The folks at cakephp (http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html#model-and-database-conventions) came up with some nice naming conventions.&lt;br /&gt;
&lt;br /&gt;
I suggest we use these for new concepts we introduce to our architecture.&lt;br /&gt;
&lt;br /&gt;
In short:&lt;br /&gt;
&lt;br /&gt;
- Models are singular: Plugin not Plugins.&lt;br /&gt;
&lt;br /&gt;
- Database tables backing the model are plural, lowercase: plugins, not plugin or Plugins.&lt;br /&gt;
&lt;br /&gt;
- Controllers are plural if they are &amp;quot;directly&amp;quot; backed by a model: PluginsController, not PluginController.&lt;br /&gt;
&lt;br /&gt;
- Controllers are singular if they are not backed by a model: AdministrationController (which we shortened to AdminController)&lt;br /&gt;
&lt;br /&gt;
- Controllers backed by a main model handle most stuff related to that model. This modularization makes it easy to find the code we are interested in when bugs need fixing.&lt;br /&gt;
&lt;br /&gt;
Table field names:&lt;br /&gt;
&lt;br /&gt;
- Table field names are all lowercase.&lt;br /&gt;
&lt;br /&gt;
- Each table has a primary key named id [[Do we want this for join tables??]]&lt;br /&gt;
&lt;br /&gt;
- Each table has either a name or title field, whichever is more appropriate for the model in question. The name / title field should be used for easy identification of a model isntance.&lt;br /&gt;
&lt;br /&gt;
- Foreign keys are named after their model postfixed with _id; so model PluginSetting belongsTo Plugin results in a plugin_id field in the pluginsettings table.&lt;br /&gt;
&lt;br /&gt;
- Join tables (for many2many relations) are either named after the concept they implement, or by concatening the participating models in alphabetical order separated by underscores. For example: user HABTM groups could be stored either in a table called memberships, which would then introduce a model Membership with relations User hasMany Membership and Group hasMany Membership, or alternatively in a table called groups_users.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Naming_conventions&amp;diff=2235</id>
		<title>Naming conventions</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Naming_conventions&amp;diff=2235"/>
		<updated>2013-01-18T21:10:43Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Having moved to a (partial) MVC architecture we should adopt some conventions for naming our models and controllers.&lt;br /&gt;
&lt;br /&gt;
The folks at cakephp (http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html#model-and-database-conventions) came up with some nice naming conventions.&lt;br /&gt;
&lt;br /&gt;
I suggest we use these for new concepts we introduce to our architecture.&lt;br /&gt;
&lt;br /&gt;
In short:&lt;br /&gt;
&lt;br /&gt;
- Models are singular: Plugin not Plugins.&lt;br /&gt;
&lt;br /&gt;
- Database tables backing the model are plural, lowercase: plugins, not plugin or Plugins.&lt;br /&gt;
&lt;br /&gt;
- Controllers are plural if they are &amp;quot;directly&amp;quot; backed by a model: PluginsController, not PluginController.&lt;br /&gt;
&lt;br /&gt;
- Controllers are singular if they are not backed by a model: AdministrationController (which we shortened to AdminController)&lt;br /&gt;
&lt;br /&gt;
- Controllers backed by a main model handle most stuff related to that model. This modularization makes it easy to find the code we are interested in when bugs need fixing.&lt;br /&gt;
&lt;br /&gt;
I realize that functionally naming conventions don&#039;t have any benefit, however they do increase maintainability. Currently we don&#039;t have naming conventions (or I am unaware of them AND they have not been consistently obeyed in the current code base).&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_plugins&amp;diff=2543</id>
		<title>Question plugins</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_plugins&amp;diff=2543"/>
		<updated>2013-01-18T09:08:27Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Question object considerations.&lt;br /&gt;
&lt;br /&gt;
Questions are plugins.&lt;br /&gt;
&lt;br /&gt;
   - No difference between core and thirdparty questions&lt;br /&gt;
&lt;br /&gt;
   - Questions can include views.&lt;br /&gt;
&lt;br /&gt;
Questions can have database columns.&lt;br /&gt;
&lt;br /&gt;
   - A question may define a column type for storing its answer.&lt;br /&gt;
&lt;br /&gt;
Questions may have subquestions.&lt;br /&gt;
&lt;br /&gt;
   - A question may have subquestions; these are Question objects, possible of another type.&lt;br /&gt;
&lt;br /&gt;
   - Questions are rendered recursively; a parent question is responsible for telling its children when to render.&lt;br /&gt;
&lt;br /&gt;
   - Answercolumns are discovered recursively; a parent question is responsible for getting column meta data (upon survey activation) from its children.&lt;br /&gt;
&lt;br /&gt;
Questions may have AnswerSets.&lt;br /&gt;
&lt;br /&gt;
   - Multiple questions may share the same AnswerSet.&lt;br /&gt;
&lt;br /&gt;
   - An answer set is a numerically indexed array; assigning each text option an numeric value.&lt;br /&gt;
&lt;br /&gt;
   - Texts inside answer sets can be localized.&lt;br /&gt;
&lt;br /&gt;
Questions belong to 1 Category.&lt;br /&gt;
&lt;br /&gt;
interface iQuestionPlugin {&lt;br /&gt;
&lt;br /&gt;
   public&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Plugin_system_architecture&amp;diff=2415</id>
		<title>Plugin system architecture</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Plugin_system_architecture&amp;diff=2415"/>
		<updated>2013-01-08T10:27:07Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Some random stuff on plugin architecture.&lt;br /&gt;
&lt;br /&gt;
The plugins will extend a base class.&lt;br /&gt;
&lt;br /&gt;
The base plugin class will initialize a storage interface and create wrapper functions for the get and set implemented in the interface.&lt;br /&gt;
&lt;br /&gt;
Code below might contain mistakes, textarea doesnt have syntax checking :p&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;interface PluginStorage {&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
&lt;br /&gt;
 Returns plugin data.&lt;br /&gt;
&lt;br /&gt;
 @param object $plugin The plugin object getting its data.&lt;br /&gt;
&lt;br /&gt;
 @param string | null $key The storage key, if null will return all data for the plugin.&lt;br /&gt;
&lt;br /&gt;
 @param string $model Name of a model in case its model specific plugin data, like for a specific question or survey.&lt;br /&gt;
&lt;br /&gt;
 @param int $id Id of the model for which the data is retreived&lt;br /&gt;
&lt;br /&gt;
 @return mixed The data stored.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
public function get($plugin, $key = null, $model = null, $id = null);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
&lt;br /&gt;
 Stores plugin data.&lt;br /&gt;
&lt;br /&gt;
 @param object $plugin The plugin object getting its data.&lt;br /&gt;
&lt;br /&gt;
 @param string $key The storage key to identify the data.&lt;br /&gt;
&lt;br /&gt;
 @param mixed $data The data to be stored, serialized using serialize.&lt;br /&gt;
&lt;br /&gt;
 @param string $model Name of a model in case its model specific plugin data, like for a specific question or survey.&lt;br /&gt;
&lt;br /&gt;
 @param int $id Id of the model for which the data is retreived&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
public function set ($plugin, $key, $data, $model = null, $id = null);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class PluginBase {&lt;br /&gt;
&lt;br /&gt;
   protected $storage = &#039;PluginStorage&#039;;&lt;br /&gt;
&lt;br /&gt;
   private $store = null;&lt;br /&gt;
&lt;br /&gt;
   public function &#039;&#039;&#039;construct()&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       $this-&amp;gt;store = Plugin::getStore($this-&amp;gt;storage);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /**&lt;br /&gt;
&lt;br /&gt;
     This function stores plugin data.&lt;br /&gt;
&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   protected function set($key, $data, $model = null, $id = null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       if (isset($this-&amp;gt;store))&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           return $this-&amp;gt;store-&amp;gt;set($this, $key, $model, $id);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       return false;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /**&lt;br /&gt;
&lt;br /&gt;
     This function retrieves plugin data. Do not cache this data; the plugin storage&lt;br /&gt;
&lt;br /&gt;
     engine will handling caching. After the first call to this function, subsequent&lt;br /&gt;
&lt;br /&gt;
     calls will only consist of a few function calls and array lookups.&lt;br /&gt;
&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   protected function get($key = null, $model = null, $id = null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       if (isset($this-&amp;gt;store))&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           return $this-&amp;gt;store-&amp;gt;get($this, $key, $model, $id);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       return false;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Email_templates&amp;diff=4361</id>
		<title>Email templates</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Email_templates&amp;diff=4361"/>
		<updated>2012-12-20T11:39:25Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
To edit the email templates select the according entry from the survey menu:&lt;br /&gt;
&lt;br /&gt;
[[File:emailtemplates.png]]&lt;br /&gt;
&lt;br /&gt;
=Email attachment feature.=&lt;br /&gt;
&lt;br /&gt;
From 2.1 forwards, LimeSurvey will officially support adding file attachments to emails sent by the system.&lt;br /&gt;
&lt;br /&gt;
The following templates support adding attachments:&lt;br /&gt;
*invitation&lt;br /&gt;
*reminder&lt;br /&gt;
*admin notification&lt;br /&gt;
*detailed admin notification&lt;br /&gt;
*confirmation&lt;br /&gt;
&lt;br /&gt;
Attachments can be added at the bottom of the email template editing interface. Email attachments are uploaded on a per survey basis.&lt;br /&gt;
&lt;br /&gt;
To decide if an attachment should be sent on an individual basis it is possible to add a relevance equation to each attachment.&lt;br /&gt;
&lt;br /&gt;
All functions supported by the [[Expression Manager|Expression Manager]] can be used, as well as token attributes if the survey uses tokens.&lt;br /&gt;
&lt;br /&gt;
In case of a notification or confirmation template it is also possible to use [http://docs.limesurvey.org/Expression+Manager#Access_to_Variables question codes] used in the survey.&lt;br /&gt;
&lt;br /&gt;
==Things to watch out for==&lt;br /&gt;
*When a &#039;&#039;&#039;file can not be found&#039;&#039;&#039; on the file system, the email will be &#039;&#039;&#039;sent without attachment&#039;&#039;&#039;.&lt;br /&gt;
*&#039;&#039;&#039;Exporting / importing&#039;&#039;&#039; a survey does not export the uploaded files. The settings for attachments will be maintained, as will the relevance equations.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Email_templates&amp;diff=4364</id>
		<title>Email templates</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Email_templates&amp;diff=4364"/>
		<updated>2012-12-19T13:16:24Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Email attachment feature.=&lt;br /&gt;
&lt;br /&gt;
From 2.1 forwards, LimeSurvey will officially support adding file attachments to emails sent by the system.&lt;br /&gt;
&lt;br /&gt;
The following templates support adding attachments: invitation, reminder, admin notification, detailed admin notification and confirmation.&lt;br /&gt;
&lt;br /&gt;
Attachments can be added in the email template editing interface. Email attachments are uploaded on a per survey basis.&lt;br /&gt;
&lt;br /&gt;
To decide if an attachment should be sent on an individual basis it is possible to add a relevance equation to each attachment.&lt;br /&gt;
&lt;br /&gt;
All functions supported by the Expression Manager can be used, as well as token attributes if the survey uses tokens.&lt;br /&gt;
&lt;br /&gt;
In case of a notification or confirmation template it is also possible to use question codes used in the survey.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039;: When a file can not be found on the file system, the email will be send without attachment.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039;: Exporting / importing a survey does not export the uploaded files. The settings for attachments will be maintained, as will the relevance equations.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Controllers&amp;diff=3210</id>
		<title>Controllers</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Controllers&amp;diff=3210"/>
		<updated>2012-08-14T12:01:46Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is a proposal for (re)organizing the controller structure for LS2.1&lt;br /&gt;
&lt;br /&gt;
Currently we have very few but fat controllers. It is desirable to have skinny controllers for easier maintenance.&lt;br /&gt;
&lt;br /&gt;
Several main tasks can be identified within LS.&lt;br /&gt;
&lt;br /&gt;
- Survey taking&lt;br /&gt;
&lt;br /&gt;
- Survey creation&lt;br /&gt;
&lt;br /&gt;
- Token management&lt;br /&gt;
&lt;br /&gt;
Since survey taking is what LS is all about we should try to decrease the complexity of this process.&lt;br /&gt;
&lt;br /&gt;
A survey hasMany groups and a group hasMany questions. For taking a survey (which is creating a survey entry) four controllers should be used.&lt;br /&gt;
&lt;br /&gt;
SurveyController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a survey.&lt;br /&gt;
&lt;br /&gt;
GroupController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a group.&lt;br /&gt;
&lt;br /&gt;
QuestionController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a question.&lt;br /&gt;
&lt;br /&gt;
EntryController&lt;br /&gt;
&lt;br /&gt;
- Responsible for managing the creation of new entries for surveys.&lt;br /&gt;
&lt;br /&gt;
Example process for a 1-question-at-a-time survey:&lt;br /&gt;
&lt;br /&gt;
/entry/create?sid=12345&lt;br /&gt;
&lt;br /&gt;
- Initialize session.&lt;br /&gt;
&lt;br /&gt;
- Store survey ID in session.&lt;br /&gt;
&lt;br /&gt;
- Redirect to /survey/welcome&lt;br /&gt;
&lt;br /&gt;
/survey/welcome&lt;br /&gt;
&lt;br /&gt;
- If applicable show welcome screen.&lt;br /&gt;
&lt;br /&gt;
- Store group ID in session.&lt;br /&gt;
&lt;br /&gt;
- Redirect to /group/welcome&lt;br /&gt;
&lt;br /&gt;
/group/welcome&lt;br /&gt;
&lt;br /&gt;
- Show welcome screen for group.&lt;br /&gt;
&lt;br /&gt;
- Store question ID in session.&lt;br /&gt;
&lt;br /&gt;
- Redirect to /question/render&lt;br /&gt;
&lt;br /&gt;
/question/render&lt;br /&gt;
&lt;br /&gt;
- Show question, form action = /entry/addanswer&lt;br /&gt;
&lt;br /&gt;
/entry/addanswer&lt;br /&gt;
&lt;br /&gt;
- Store the result for the current answered question.&lt;br /&gt;
&lt;br /&gt;
- Use answer to find next question / group &amp;amp; store ID.&lt;br /&gt;
&lt;br /&gt;
- Redirect appropriately.&lt;br /&gt;
&lt;br /&gt;
And so on... This does not cause a lot of extra redirects since redirecting after a HTTP POST is standard procedure, we just change the POST ACTION.&lt;br /&gt;
&lt;br /&gt;
This approach allows us to divide large complex controller(s) into smaller and easier to manage pieces.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Controllers&amp;diff=3211</id>
		<title>Controllers</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Controllers&amp;diff=3211"/>
		<updated>2012-08-14T10:28:16Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is a proposal for (re)organizing the controller structure for LS2.1&lt;br /&gt;
&lt;br /&gt;
Currently we have very few but fat controllers. It is desirable to have skinny controllers for easier maintenance.&lt;br /&gt;
&lt;br /&gt;
Several main tasks can be identified within LS.&lt;br /&gt;
&lt;br /&gt;
- Survey taking&lt;br /&gt;
&lt;br /&gt;
- Survey creation&lt;br /&gt;
&lt;br /&gt;
- Token management&lt;br /&gt;
&lt;br /&gt;
Since survey taking is what LS is all about we should try to decrease the complexity of this process.&lt;br /&gt;
&lt;br /&gt;
A survey hasMany groups and a group hasMany questions. For taking a survey (which is creating a survey entry) four controllers should be used.&lt;br /&gt;
&lt;br /&gt;
SurveyController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a survey.&lt;br /&gt;
&lt;br /&gt;
GroupController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a group.&lt;br /&gt;
&lt;br /&gt;
QuestionController&lt;br /&gt;
&lt;br /&gt;
- Actions for creating and editing a question.&lt;br /&gt;
&lt;br /&gt;
EntryController&lt;br /&gt;
&lt;br /&gt;
- Responsible for managing the creation of new entries for surveys.&lt;br /&gt;
&lt;br /&gt;
Example process:&lt;br /&gt;
&lt;br /&gt;
- EntryController-&amp;gt; create entry for survey 1&lt;br /&gt;
&lt;br /&gt;
- Redirect to SurveyController -&amp;gt; welcome screen (which has a post button that goes to entrycontroller)&lt;br /&gt;
&lt;br /&gt;
- Redirect to GroupController -&amp;gt; welcome screen&lt;br /&gt;
&lt;br /&gt;
And so on... This does not cause a lot of extra redirects since redirecting after a HTTP POST is standard procedure, we just change the POST ACTION.&lt;br /&gt;
&lt;br /&gt;
This approach allows us to divide large complex controller(s) into smaller and easier to manage pieces.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4326</id>
		<title>Directory structure</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4326"/>
		<updated>2012-08-14T10:10:32Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page should explain the directory hierarchy for the Yii branch.&lt;br /&gt;
&lt;br /&gt;
Root&lt;br /&gt;
* application -- Contains the Yii limesurvey application, back-end stuff should mostly be in here.&lt;br /&gt;
** config -- Contains the configuration for the framework and Limesurvey.&lt;br /&gt;
** controllers -- Contains the controllers from the MVC paradigm.&lt;br /&gt;
** core&lt;br /&gt;
** errors&lt;br /&gt;
** helpers&lt;br /&gt;
** hooks&lt;br /&gt;
** language&lt;br /&gt;
** libraries&lt;br /&gt;
** logs&lt;br /&gt;
** models&lt;br /&gt;
** tests&lt;br /&gt;
** third_party -- Contains third party libraries that are used by the backend and do not have to be available directly from a browser.&lt;br /&gt;
** views&lt;br /&gt;
* docs&lt;br /&gt;
* fonts&lt;br /&gt;
* framework -- The Yii framework. This directory should not be changed unless you are updating Yii.&lt;br /&gt;
* images&lt;br /&gt;
* installer -- Contains files for initial installation and upgrading.&lt;br /&gt;
* locale&lt;br /&gt;
* scripts -- Contains javascript files.&lt;br /&gt;
* styles-public -- Contains css files (difference with normal styles dir?)&lt;br /&gt;
* styles -- Contains css files&lt;br /&gt;
* templates&lt;br /&gt;
* third-party -- This contains (scripting) libraries that must be available directly via the browser. For example jquery. Only place original libraries here, put configuration in the scripts dir. Create a subdirectory for each library, but don&#039;t include the version number in the directory; this allows for easy upgrading.&lt;br /&gt;
* tmp&lt;br /&gt;
* upload&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Question_Objects&amp;diff=2537</id>
		<title>Question Objects</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Question_Objects&amp;diff=2537"/>
		<updated>2012-08-12T23:44:12Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
As of LimeSurvey 2.0, questions type were internally identified by a single character. That is, a display question was represented by &#039;X&#039; while a list question was represented by &#039;L&#039; etc. Unfortunately, this made adding and altering question types incredibly difficult since code for each question type was spread across literally dozens of files. To make it easier for independent developers to add and modify question types, each question will have it&#039;s own class in the application/modules folder. These classes will contain all question-type-specific code.&lt;br /&gt;
&lt;br /&gt;
There are 3 abstract question classes: QuestionModule, ArrayQuestion, and TextQuestion. All the question classes (including Array and Text) extend QuestionModule and end in &amp;quot;Question.&amp;quot; Below is a list of class names and descriptions.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Description||Class Prefix||Legacy Character Code||Parent (if blank assume QuestionModule)&lt;br /&gt;
|-&lt;br /&gt;
|5 point choice||FiveList||5||&lt;br /&gt;
|-&lt;br /&gt;
|List (dropdown)||Select||!||List&lt;br /&gt;
|-&lt;br /&gt;
|List (radio)||List||L||&lt;br /&gt;
|-&lt;br /&gt;
|List with comment||CommentList||O||List&lt;br /&gt;
|-&lt;br /&gt;
|Array||RadioArray||F||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (10 point choice)||TenRadioArray||B||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (5 point choice)||FiveRadioArray||A||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (Increase/Same/Decrease)||IDRadioArray||E||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array (Numbers)||NumberArray||:||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (Texts)||TextArray||;||Array&lt;br /&gt;
|-&lt;br /&gt;
|Array (Yes/No/Uncertain)||YNRadioArray||C||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array by column||ColumnRadioArray||H||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Array dual scale||DualRadioArray||1||RadioArray&lt;br /&gt;
|-&lt;br /&gt;
|Date/Time||Date||D||&lt;br /&gt;
|-&lt;br /&gt;
|Equation||Equation||*||&lt;br /&gt;
|-&lt;br /&gt;
|File upload||File||pipe character||&lt;br /&gt;
|-&lt;br /&gt;
|Gender||Gender||G||&lt;br /&gt;
|-&lt;br /&gt;
|Language switch||Language||I||&lt;br /&gt;
|-&lt;br /&gt;
|Multiple numerical input||Multinumerical||K||&lt;br /&gt;
|-&lt;br /&gt;
|Numerical input||Numerical||N||&lt;br /&gt;
|-&lt;br /&gt;
|Ranking||Ranking||R||&lt;br /&gt;
|-&lt;br /&gt;
|Text display||Display||X||&lt;br /&gt;
|-&lt;br /&gt;
|Yes/No||YN||Y||&lt;br /&gt;
|-&lt;br /&gt;
|Huge free text||HugeText||U||Text&lt;br /&gt;
|-&lt;br /&gt;
|Long free text||LongText||T||Text&lt;br /&gt;
|-&lt;br /&gt;
|Multiple short text||Multitext||Q&lt;br /&gt;
|-&lt;br /&gt;
|Short free text||ShortText||S||Text&lt;br /&gt;
|-&lt;br /&gt;
|Multiple choice||Check||M||&lt;br /&gt;
|-&lt;br /&gt;
|Multiple choice with comments||CommentCheck||P||Check&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each of these classes contains (or inherits) a number of public methods that are abstracted by the QuestionModule class. To execute this question specific code, the question class is loaded out of the database, the object is dynamically instantiated and the relevant function is called. The question objects store question id, group id, survey id, question text, and other relevant data. Question objects then become a very useful way to pass around data instead of the previously used arrays.&lt;br /&gt;
&lt;br /&gt;
These question objects come with two new database tables. First, a question types table stores a list of type ids, group ids, description, and legacy character code. There is a new int tid column in the questions table that replaces the type column and maps to the tid column in the new question types table. In addition, there is a new question type groups table that contains a group id, a description, and an order. This configuration will allow for backend configuration in the future, and ultimately, custom question types that can be shared among the community.&lt;br /&gt;
&lt;br /&gt;
One of the biggest advantages of switching from procedural code to object-oriented code is that it will both allow developers to easily create custom question types by extending any of the existing question types. In order to do this, a developer can either extend one of the predefined question types and override one or more of the methods (such as getAnswerHTML() which returns the HTML code that renders each question) or by extending the base QuestionModule class or one of the other abstract classes and implementing its abstract methods.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|Abstract Method&amp;amp;dagger;||Functionality&lt;br /&gt;
|-&lt;br /&gt;
|getAnswerHTML||Returns the HTML for the question&lt;br /&gt;
|-&lt;br /&gt;
|getDataEntry||Returns the HTML for manually entering survey data from the backend&lt;br /&gt;
|-&lt;br /&gt;
|availableAttributes||Returns an array of attributes the question can have in the question_attributes table&lt;br /&gt;
|-&lt;br /&gt;
|questionProperties||Returns an array of question properties including description, group name, whether the class has subquestions, css class name, whether the class has default values, whether the class is assessable, and whether the class has answer scales&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;dagger;Once the porting of the question objects is completed, a table will be added with a complete list of methods both abstract and extendable.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=The_bugtracker_and_git&amp;diff=3332</id>
		<title>The bugtracker and git</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=The_bugtracker_and_git&amp;diff=3332"/>
		<updated>2012-08-09T12:40:57Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This article should help developers on the LimeSurvey when resolving issues.&lt;br /&gt;
&lt;br /&gt;
General process outline.&lt;br /&gt;
&lt;br /&gt;
1. Bug reported by user.&lt;br /&gt;
&lt;br /&gt;
2. Bug assigned to developer (by the developer himself or someone else)&lt;br /&gt;
&lt;br /&gt;
3. Bug fixed github.com&lt;br /&gt;
&lt;br /&gt;
4. Issue assigned to LimeSurvey repository owner (c_schmitz), status set to resolved.&lt;br /&gt;
&lt;br /&gt;
5. When a new version is released c_schmitz closes the resolved bugs.&lt;br /&gt;
&lt;br /&gt;
This method of working should allow for efficient bug fixing with multiple developers without getting c_schmitz overworked..?&lt;br /&gt;
&lt;br /&gt;
Please respond on what you think of this process, or what should be changed.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=The_bugtracker_and_git&amp;diff=3333</id>
		<title>The bugtracker and git</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=The_bugtracker_and_git&amp;diff=3333"/>
		<updated>2012-08-09T10:19:10Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This article should help developers on the LimeSurvey when resolving issues.&lt;br /&gt;
&lt;br /&gt;
General process outline.&lt;br /&gt;
&lt;br /&gt;
1. Bug reported by user.&lt;br /&gt;
&lt;br /&gt;
2. Bug assigned to developer (by the developer himself or someone else)&lt;br /&gt;
&lt;br /&gt;
3. Bug fixed in fork on github.com (each developer has his own fork?)&lt;br /&gt;
&lt;br /&gt;
4. Pull request generated on github.com&lt;br /&gt;
&lt;br /&gt;
5. Issue assigned to LimeSurvey repository owner (c_schmitz), status set to resolved.&lt;br /&gt;
&lt;br /&gt;
6. Pull request fulfilled and bug status set to closed (done by c_schmitz)&lt;br /&gt;
&lt;br /&gt;
This method of working should allow for efficient bug fixing with multiple developers without getting c_schmitz overworked..?&lt;br /&gt;
&lt;br /&gt;
Please respond on what you think of this process, or what should be changed.&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4327</id>
		<title>Directory structure</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4327"/>
		<updated>2012-08-08T20:57:03Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page should explain the directory hierarchy for the Yii branch.&lt;br /&gt;
&lt;br /&gt;
Root&lt;br /&gt;
* admin -- Contains just a redirect to keep the old /admin URL available; dont put any files in there.&lt;br /&gt;
* application -- Contains the Yii limesurvey application, back-end stuff should mostly be in here.&lt;br /&gt;
** config -- Contains the configuration for the framework and Limesurvey.&lt;br /&gt;
** controllers -- Contains the controllers from the MVC paradigm.&lt;br /&gt;
** core&lt;br /&gt;
** errors&lt;br /&gt;
** helpers&lt;br /&gt;
** hooks&lt;br /&gt;
** language&lt;br /&gt;
** libraries&lt;br /&gt;
** logs&lt;br /&gt;
** models&lt;br /&gt;
** tests&lt;br /&gt;
** third_party -- Contains third party libraries that are used by the backend and do not have to be available directly from a browser.&lt;br /&gt;
** views&lt;br /&gt;
* docs&lt;br /&gt;
* fonts&lt;br /&gt;
* framework -- The Yii framework. This directory should not be changed unless you are updating Yii.&lt;br /&gt;
* images&lt;br /&gt;
* installer -- Contains files for initial installation and upgrading.&lt;br /&gt;
* locale&lt;br /&gt;
* scripts -- Contains javascript files.&lt;br /&gt;
* styles-public -- Contains css files (difference with normal styles dir?)&lt;br /&gt;
* styles -- Contains css files&lt;br /&gt;
* templates&lt;br /&gt;
* third-party -- This contains (scripting) libraries that must be available directly via the browser. For example jquery. Only place original libraries here, put configuration in the scripts dir. Create a subdirectory for each library, but don&#039;t include the version number in the directory; this allows for easy upgrading.&lt;br /&gt;
* tmp&lt;br /&gt;
* upload&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4328</id>
		<title>Directory structure</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4328"/>
		<updated>2012-08-08T20:52:37Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page should explain the directory hierarchy for the Yii branch.&lt;br /&gt;
&lt;br /&gt;
Root&lt;br /&gt;
* admin -- Contains just a redirect to keep the old /admin URL available; dont put any files in there.&lt;br /&gt;
* application -- Contains the Yii limesurvey application, back-end stuff should mostly be in here.&lt;br /&gt;
** config&lt;br /&gt;
** controllers&lt;br /&gt;
** core&lt;br /&gt;
** errors&lt;br /&gt;
** helpers&lt;br /&gt;
** hooks&lt;br /&gt;
** language&lt;br /&gt;
** libraries&lt;br /&gt;
** logs&lt;br /&gt;
** models&lt;br /&gt;
** tests&lt;br /&gt;
** third_party -- Contains third party libraries that are used by the backend and do not have to be available directly from a browser.&lt;br /&gt;
** vies&lt;br /&gt;
* docs&lt;br /&gt;
* fonts&lt;br /&gt;
* framework -- The Yii framework. This directory should not be changed unless you are updating Yii.&lt;br /&gt;
* images&lt;br /&gt;
* installer -- Contains files for initial installation and upgrading.&lt;br /&gt;
* locale&lt;br /&gt;
* scripts -- Contains javascript files.&lt;br /&gt;
* styles-public -- Contains css files (difference with normal styles dir?)&lt;br /&gt;
* styles -- Contains css files&lt;br /&gt;
* templates&lt;br /&gt;
* third-party -- This contains (scripting) libraries that must be available directly via the browser. For example jquery. Only place original libraries here, put configuration in the scripts dir. Create a subdirectory for each library, but don&#039;t include the version number in the directory; this allows for easy upgrading.&lt;br /&gt;
* tmp&lt;br /&gt;
* upload&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4329</id>
		<title>Directory structure</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Directory_structure&amp;diff=4329"/>
		<updated>2012-08-08T20:47:24Z</updated>

		<summary type="html">&lt;p&gt;Sammousa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page should explain the directory hierarchy for the Yii branch.&lt;br /&gt;
&lt;br /&gt;
Root&lt;br /&gt;
* admin&lt;br /&gt;
* application&lt;br /&gt;
* docs&lt;br /&gt;
* fonts&lt;br /&gt;
* framework -- The Yii framework. This directory should not be changed unless you are updating Yii.&lt;br /&gt;
* images&lt;br /&gt;
* installer -- Contains files for initial installation and upgrading.&lt;br /&gt;
* locale&lt;br /&gt;
* scripts -- Contains javascript files.&lt;br /&gt;
* styles-public -- Contains css files (difference with normal styles dir?)&lt;br /&gt;
* styles -- Contains css files&lt;br /&gt;
* templates&lt;br /&gt;
* third-party -- This contains (scripting) libraries that must be available directly. For example jquery. Only place original libraries here, put configuration in the scripts dir. Create a subdirectory for each library, but don&#039;t include the version number in the directory; this allows for easy upgrading.&lt;br /&gt;
* tmp&lt;br /&gt;
* upload&lt;/div&gt;</summary>
		<author><name>Sammousa</name></author>
	</entry>
</feed>