<?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=Rakete</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=Rakete"/>
	<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/Special:Contributions/Rakete"/>
	<updated>2026-08-11T13:35:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2915</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2915"/>
		<updated>2010-08-05T09:21:04Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &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 is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
==Known issues (and workarounds)==&lt;br /&gt;
* PHP 5.3.0 has a bug ([http://bugs.php.net/bug.php?id=49014 here] and [http://bugs.php.net/bug.php?id=49094 here]) which prevents createding/reading wsdl files. We strongly recommend to update to a later PHP version.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
Please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC is disabled. In order to use LSRC you must first enable the service, and then adjust the settings to suit your needs.&lt;br /&gt;
* To &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes it&#039;s own log. This log is particularly helpful when implementing new features. If some functions of LSRC don&#039;t work look for where it stops functioning in this log. Once you have finished setting up or developing new features you should turn the log off by setting this value to false.&lt;br /&gt;
** $lsrcDebugLog, The name of the file where the log should be written.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment this line out (put two forward slashes at the beginning of the line &amp;quot;//&amp;quot;) once you have finished setting up and have put your LSRC service into production.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. &#039;&#039;&#039;Note:&#039;&#039;&#039;Turning this on simply changes the internal addressing to either &amp;quot;https:&amp;quot; or &amp;quot;http:&amp;quot; in order to work over a SSL connection, nothing more.&lt;br /&gt;
** set the directories, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
** (optional) set $export4lsrc = true; if you want to export surveys, groups and questions to remotecontrol folders for importing remotely. They must be writeable.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&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;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&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;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for 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;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the primary matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&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;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.client.php (used by lsrc.testclient.php) set the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2916</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2916"/>
		<updated>2010-08-03T19:40:03Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &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 is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
==Known issues (and workarounds)==&lt;br /&gt;
* PHP 5.3.0 has a bug ([http://bugs.php.net/bug.php?id=49014 here] and [http://bugs.php.net/bug.php?id=49094 here]) which prevents createding/reading wsdl files. We strongly recommend to update to a later PHP version.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
Please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC is disabled. In order to use LSRC you must first enable the service, and then adjust the settings to suit your needs.&lt;br /&gt;
* To &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes it&#039;s own log. This log is particularly helpful when implementing new features. If some functions of LSRC don&#039;t work look for where it stops functioning in this log. Once you have finished setting up or developing new features you should turn the log off by setting this value to false.&lt;br /&gt;
** $lsrcDebugLog, The name of the file where the log should be written.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment this line out (put two forward slashes at the beginning of the line &amp;quot;//&amp;quot;) once you have finished setting up and have put your LSRC service into production.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. &#039;&#039;&#039;Note:&#039;&#039;&#039;Turning this on simply changes the internal addressing to either &amp;quot;https:&amp;quot; or &amp;quot;http:&amp;quot; in order to work over a SSL connection, nothing more.&lt;br /&gt;
** set the directories, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&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;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&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;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for 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;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the primary matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&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;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.client.php (used by lsrc.testclient.php) set the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2468</id>
		<title>Project ideas for GSOC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2468"/>
		<updated>2010-04-01T13:06:27Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)!! Please check if you are an [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#student_eligibility eligible candidate] for the GSoC program.&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at #limesurvey on irc.freenode.net. Then submit &#039;&#039;&#039;your&#039;&#039;&#039; proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Example Format...==&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;Probable Mentors&#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;
==Limesurvey I: Modularisation of basic functions, that are needed by LSRC==&lt;br /&gt;
&lt;br /&gt;
Currently the LSRC is suffering from a lack of experience back in the days I began to implement its features. Unfortunaly some functions tend to become buggy when limesurvey-development takes steps forwards, because the LSRC functions are mostly an adapted copy of code from limesurveys original scripts.&lt;br /&gt;
&lt;br /&gt;
The main Idea is to realize the vital functions (at least: importSurvey and activateSurvey) in a way, that Limesurvey and the LSRC can use it together and the code have to be maintained only once.&lt;br /&gt;
&lt;br /&gt;
Primary Goals:&lt;br /&gt;
&lt;br /&gt;
- analyse the current differences between lsrc.helper functions and the original Limesurvey scripts. Especially for activateSurvey and importSurvey&lt;br /&gt;
&lt;br /&gt;
- make a concept on how to realize a modular function from the original script, which can be called from limesurvey and the lsrc (see statistics.php and statistics_function.php in comparison as example)&lt;br /&gt;
&lt;br /&gt;
- modularize the script to a function and build it in.&lt;br /&gt;
&lt;br /&gt;
Secondary Goals:&lt;br /&gt;
&lt;br /&gt;
- modularize insertParticipant or implement new functions, which can be used by limesurvey and LSRC in the same manner.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, AdoDb/sql, PHP:SOAP&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
intermediate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Tim Wahrendorff (rakete)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: Email bounce tracking &amp;amp; handling of international email addresses==&lt;br /&gt;
&lt;br /&gt;
Currently there is no way to process email bounces of invitation or reminders in an automated way. If a bounce is received the administrator has to manually process every bounce - either by finding out a correct email address or removing the participant completely. Additionally it would be great if LimeSurvey could handle International email addressing - although the RFC for this kind of features are still experimental it would be great if we can be ahead of time. Primary goals of this task:&lt;br /&gt;
&lt;br /&gt;
- Create a facility to handle email bounces using various methods. Easier to install methods which run without CRON jobs and with a single email account - more advanced and safer methods which require certain email server setups. Make it quick and easy to configure and handle. Create followup actions in case an email is bounced. Differentiate between bounces and other &#039;away-messages&#039;.&lt;br /&gt;
&lt;br /&gt;
- Extend the PHPmailer library and LimeSurvey so it can handle international email addressing (including configuration)&lt;br /&gt;
&lt;br /&gt;
Skills&lt;br /&gt;
&lt;br /&gt;
PHP, knowledge of email handling and RFCs, some HTML &amp;amp; JS&lt;br /&gt;
&lt;br /&gt;
Difficulty&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
Probable Mentors&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Thibault LeMeur (lemeur)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: File Upload question type==&lt;br /&gt;
&lt;br /&gt;
The idea is to have a question type in LimeSurvey1 where survey participants can upload one (or more) files. Often in surveys the participant is asked to create some content (pictures, movies, documents, etc.)  to upload as an answer to a question. The following goals are  primary in this task:&lt;br /&gt;
*Easy handling for the participant (uploading one or more files should be a piece of cake - also removing files if accidentally the wrong file was uploaded)&lt;br /&gt;
*Extensive configuration options for the question type like&lt;br /&gt;
**How many files are required, minimum and maxim number of files,&lt;br /&gt;
**maximum/minimum upload size,&lt;br /&gt;
**Allowed file types&lt;br /&gt;
*Safe!! storage in the file system, checks for file contents&lt;br /&gt;
*Implementation in statistics / data entry / printable survey / response browsing / response editing &amp;amp; RemoteControl&lt;br /&gt;
*Administrator can download one or more files (zip-packaging files for download) from one response and across responses&lt;br /&gt;
*Provide possible hooks for third party processing tools&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, jQuery, AJAX - existing knowledge on the general idea and related security would be of big advantage&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;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz (Carsten Schmitz)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: Authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a generic authentication framework for LimeSurvey 1 as well as some authentication modules. The Authentication framework will make it possible to implement any kind of authentication backend apart from the already existing internal-DB and Web server delegation schemes. Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or GET/POST parameters or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisionning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the correspoding survey (only if the token for this user has not been already added).&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Authentication protocols (openID, CAS, LDAP-bind, ...)&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;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lemeur (Thibault Le Meur)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please read the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010++Authentication+framework#FAQ FAQ about this project]&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Db Storage Engine==&lt;br /&gt;
&lt;br /&gt;
Develop an extensible plugin survey storage engine for LimeSurvey 2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other than survey design, everything that happens in LimeSurvey centres around the ability to save responses to questions to a database, and retrieve the responses again when required. Historically these functions have been incorporated within the various functions of LimeSurvey and this has locked LimeSurvey to a single methodology for data storage and retrieval and made future modifications and improvements difficult if not possible.&lt;br /&gt;
&lt;br /&gt;
For this project we are looking for students to write a &#039;middleware&#039; that exposes abstract high-level functions to LimeSurvey 2 (e.g.: storing these answers related to this question, running statistical analysis etc.) but is built in top of Cake&#039;s &#039;low-level&#039; operations (such as find, save etc). The aim is to abstract away from a specific DB implementation and provide an intuitive and rich API for LS2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Rationale&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the interface with the data storage system is so critical to practically every other function in LimeSurvey we want to develop a stand-alone module that is transportable and extensible for the future. And by keeping the logic of data and survey storage separate from the rest of LimeSurvey&amp;amp;rsquo;s functions we will the ease with which LimeSurvey can be developed in the long term.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Implementation&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is such an important project that we would consider multiple students undertaking the task. In conjunction with a strong understanding of data structures, php coding and api principles the students would also have to display a capacity to work in a team and with the broader community.&lt;br /&gt;
&lt;br /&gt;
The implementation would focus on becoming a plugin/addon module under CakePHP which uses the default CakePHP database systems to the absolute minimum. In a well implemented version of this proposal only simple SQL inserts, queries and updates would be required. All other logic would be managed by the engine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Requirements &amp;amp; Considerations&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DB Engine must be able to do the following&lt;br /&gt;
* ease development of additional &#039;&#039;&#039;question types, which will be developed as plugins&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;efficient data retrieval&#039;&#039;&#039;, especially summaries (e.g. display 100 last responses)&lt;br /&gt;
* support &#039;&#039;&#039;generic&#039;&#039;&#039; data storage and retrieval - aside surveys, imagine running online admission tests, polls, sign-up forms, volunteer campaign etc. etc.&lt;br /&gt;
* easily support conditions, looped question, or generally, &#039;&#039;&#039;non-linear data&#039;&#039;&#039;. Think of a survey that asks how many children you have and then asks information about each of them.&lt;br /&gt;
* support questions that have multiple &#039;&#039;&#039;answers and multiple types of answers&#039;&#039;&#039;. Think of a question asking &amp;quot;What is your favourite ice cream?&amp;quot;, offering 3 fixed options and last one allowing user to enter a custom answer.&lt;br /&gt;
* support survey resuming (where applicable)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Use Cases &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Think of these when writing your proposal&lt;br /&gt;
# Questionnaire which has a special section displayed only if a user answers a chosen question in a specific way (i.e. branching)&lt;br /&gt;
# Question on your favourite ice-cream, with an option &amp;quot;Other&amp;quot;, upon which the user will be asked to enter his own choice (i.e. multi-datatype question types)&lt;br /&gt;
# Questionnaire, which asks how many children you have and then loops a set of predefined questions that many times. (i.e. looping)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt; Your proposal &amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your proposal needs to be fairly detailed and must dig deep down to the implementation level, with good analysis of the performance. &amp;quot;Read the data from the user and store it in the database&amp;quot; is no good! How are you going to store it? What is the schema going to be? Does it satisfy the requirements, for branching, conditions, pluggable question types? Does it scale well? Is it efficient - what is the time complexity? Can I get summaries out of it in a reasonable time? All this needs to be addressed. Early submissions are accepted by both mentors and suggestions and comments will be given (:wink:).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Field Naming and Database Extensibility Methodologies&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An ongoing debate in the LimeSurvey community has been the method in which the database stores survey results. In LimeSurvey 1 a flat database schema was used whereby once the survey designer had finished setting up the survey a database table was created with a field for every individual question/answer combination. The advantages of this database schema were speed of retrieval for reporting and exporting and searching. The disadvantages were that the survey system had to &amp;amp;lsquo;freeze&amp;amp;rsquo; the structure in place once the table was created (therefore the activate/de-activate rules in LimeSurvey 1). The single table method doesn&amp;amp;rsquo;t allow easy storage of metadata for individual question/answer combinations (such as timestamps). Nor does it lend itself to surveys with enormous quantities of question/answer combinations &amp;amp;ndash; sometimes running up against database limitations regarding the number of fields per table.&lt;br /&gt;
&lt;br /&gt;
An alternative is a &amp;amp;lsquo;normalised&amp;amp;rsquo; database topology where a single table is created to store all survey responses &amp;amp;ndash; one database row per question/answer combination. A related table would store metadata that is directly related to the survey sitting/session rather than the answer (e.g.: username, ip address, geographical location, user demographic). The advantage to this methodology is the increased flexibility (extensible) which would allow modification of surveys at any stage even after data has been collected (see requirements). The disadvantages are that searching and compilation of data is complicated and resource intensive.&lt;br /&gt;
&lt;br /&gt;
In a perfect world LimeSurvey would allow users to choose either methodology &amp;amp;ndash; either at an installation level or even on a per-survey level.&lt;br /&gt;
&lt;br /&gt;
Having a database storage engine effectively acting as an API would allow this functionality to be built, but the choice of database topology would be invisible to the related LimeSurvey functions that require data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Database Schema Design, Sound knowledge of Algorithms and Data Structures&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
jasebo (Jason Cleeland)&lt;br /&gt;
&lt;br /&gt;
macduy (Mac Duy Hai)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template Editor==&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2 needs a nice and powerful template editor so everyone can create a template which matches their requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
One needs to know about the details of the [http://dwoo.org/ dwoo template engine] which is used at LS2. There is some cakePHP coding needed to create an interface and write changes to the template files as well as some HTML/CSS to create a nice interface.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You don&#039;t have to create difficult algorithms for this task. It&#039;s useful if you have worked with templates for another web-application or take a detailled look at [http://docs.limesurvey.org/tiki-index.php?page=Themes%3A+Templates+and+Styles&amp;amp;structure;=English+Instructions+for+LimeSurvey how templates work in Limesurvey]. Some design/usability background would be nice but is not a must.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mazi&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Mini-projects==&lt;br /&gt;
&lt;br /&gt;
Mini-projects is a collection of small-to-medium sized projects, which you mix-and-match according to your tastes. Heck, you can even roll your own idea and once reviewed and approved, you can code away. Some recommended/important mini-projects and their brief descriptions:&lt;br /&gt;
*&#039;&#039;&#039;Smarter installer:&#039;&#039;&#039; LS2.0 comes with its own installer, though it may not be the friendliest to use. Your task is to make it juicier to use:&lt;br /&gt;
** Resume installation - if the user aborts the installation mid-way, make it easy for him to resume it. It should be able to clean up databases, revert files and basically be prepared for any eventuality.&lt;br /&gt;
** Better error handling - meaningful error reports, suggestions how to fix them: e.g. &amp;quot;Database does not exist&amp;quot; is better than &amp;quot;Database error&amp;quot; (and excellent opportunity for a &amp;quot;Would you like to create it?&amp;quot; button)&lt;br /&gt;
** Customization - invite the user to customize his installation of LimeSurvey - from security settings such as salt, to interface such as the header title.&lt;br /&gt;
*&#039;&#039;&#039;User management:&#039;&#039;&#039; When the number of users grow, it becomes increasingly harder to manage them. Implement functionality and provide interface for features that would make this task easier. Inspire yourself by the big players, such as the infamous you-know-which-one social website.&lt;br /&gt;
**&#039;&#039;&#039;Groups within groups:&#039;&#039;&#039; LS2 users can belong to a group, but groups cannot belong to other groups.&lt;br /&gt;
**&#039;&#039;&#039;Contact lists:&#039;&#039;&#039; There is already something called AssignmentGroups. Study this concept carefully and generalize to a Contact List&lt;br /&gt;
**&#039;&#039;&#039;GUI:&#039;&#039;&#039; Design a GUI which allows you easily manage users, groups and contact lists.&lt;br /&gt;
**&#039;&#039;&#039;Searching:&#039;&#039;&#039; Provide an efficient but simple-to-use search interface and functionality&lt;br /&gt;
**&#039;&#039;&#039;Batch import:&#039;&#039;&#039; import users through CSV, XML, etc...&lt;br /&gt;
**&#039;&#039;&#039;Batch processing:&#039;&#039;&#039; Add an interface to manipulate (add &amp;amp; modify) several users at once&lt;br /&gt;
*&#039;&#039;&#039;Announcements:&#039;&#039;&#039; Make it easy to send customizable announcements to desired audience. Obviously, you don&#039;t want to send reminder e-mails to those people who&#039;ve taken a survey already.&lt;br /&gt;
**&#039;&#039;&#039;Filtering:&#039;&#039;&#039; Filter users on various suitable criteria&lt;br /&gt;
**&#039;&#039;&#039;Templates:&#039;&#039;&#039; Design a template system announcement beyond a simple find-and-replace. We don&#039;t want you to build the next Smarty or Django templates replacement, but dazzle the users with something cool and usable&lt;br /&gt;
**&#039;&#039;&#039;Management:&#039;&#039;&#039; Folders, counters,&lt;br /&gt;
*&#039;&#039;&#039;Inbox:&#039;&#039;&#039; Build a system that would allow users to communicate among each other without the need for e-mail. (&#039;&#039;&#039;Not chat&#039;&#039;&#039;)!&lt;br /&gt;
**&#039;&#039;&#039;Message Type:&#039;&#039;&#039; Categorise the messages&lt;br /&gt;
**&#039;&#039;&#039;Linking with Announcements:&#039;&#039;&#039; Use it as an alternative to e-mail.&lt;br /&gt;
**&#039;&#039;&#039;E-mail notifications:&#039;&#039;&#039; Is it a good idea? How often is good? Allow people to choose if they want it?&lt;br /&gt;
*&#039;&#039;&#039;Assignments&#039;&#039;&#039;: Assignment is how a Survey is deployed. It can be time-restricted or region-restricted etc. Make improvements on the Assignment features and its design GUI.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JavaScript &amp;amp; jQuery, Creativity, UI Design&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;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mac Duy Hai (macduy)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template/Theme Editor - &amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;This project has no mentor!&amp;lt;/span&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The idea is to develop a theme / template framework similar to one in jquery [http://jqueryui.com/themeroller/ | Jquery Theme Roller] and thus making the UI design of the surveys easier.The current template editor is based on dwoo template engine which actually loads the files exposing the css etc for us to edit, which of course require some skill set to proceed. Using this template editor we can make everything UI based and thus requiring no developer skills to edit the templates.&lt;br /&gt;
&lt;br /&gt;
The overview of the modules can be seen here:&lt;br /&gt;
&lt;br /&gt;
[[File:theme_roller.png]]&lt;br /&gt;
&lt;br /&gt;
It&amp;amp;rsquo;ll be implemented using Jquery to use the more advanced UI experiences.(:biggrin:)&lt;br /&gt;
&lt;br /&gt;
The following mock-up will give us a better view:&lt;br /&gt;
&lt;br /&gt;
Moderate[[File:theme_editor_small.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, CSS, AJAX, JavaScript &amp;amp; jQuery.&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;
==-LimeSurvey 2: Lime Survey Social - Facebook Application - &amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;This project has no mentor!&amp;lt;/span&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
The idea aims at developing a Facebook app which gives a social touch to LS 2.0. The application will be integrated in several Facebook integration points like News Feed, Applications boxes, Wall etc so that the user participation will be more. Adding a social touch can drive us more user participation and increase the popularity. The ability to control the Facebook app can be provided in the LS2.0 Admin Dashboard and also in the FB user application window with varied options.&lt;br /&gt;
&lt;br /&gt;
The facebook has the following modules (we can add more. This is primary draft.)&lt;br /&gt;
*All Survey related core features. (Create, Edit, Delete, Administer etc)&lt;br /&gt;
*Gain reward points.&lt;br /&gt;
*Use reward points to create more surveys.&lt;br /&gt;
*Spread the surveys ...... and more&lt;br /&gt;
&lt;br /&gt;
The idea can be extended to other social networks&lt;br /&gt;
&lt;br /&gt;
[[File:fb_overview.png]]&lt;br /&gt;
&lt;br /&gt;
The mock-ups :&lt;br /&gt;
&lt;br /&gt;
[[File:facebook app.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:canvas.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Facebook API.&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;
==LimeSurvey 2: Integration of Poll Questions &amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;This project has no mentor!&amp;lt;/span&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
Polls are one of the most popular and quick response getting tools once can use. Implementing polls in LS 2.0 will be an added advantage. Since every one of us know what polls are about, this idea focuses on the implementation part.&lt;br /&gt;
&lt;br /&gt;
The idea is to integrate the ability to create a POLL Module in Admin dashboard, where he can administer (Create | Edit | Delete | View Responses etc) the Polls.We can even get feedback &amp;amp;ldquo;about the survey&amp;amp;rdquo; at the end on how the user feels by creating a custom poll (we can even redirect the user to this poll).&lt;br /&gt;
*Chat Bots and Polls: An another idea is to create chat bots so that whenever we create a poll, all the friends (who added the bot) of that bot will be pinged by the question followed by options. Getting an answer is very easy (Bot friends just need to type a single letter stating the answer) and its a push model which ensures the delivery to everyone (even offline).We can even extend this to deliver certain type of surveys question by question through the bot.&lt;br /&gt;
&lt;br /&gt;
A simple mock-up for this:&lt;br /&gt;
&lt;br /&gt;
[[File:chat.png]]&lt;br /&gt;
*Alternate Solution: An alternate solution provided by Mazi is clubbing this idea with the Facebook app idea. Instead of porting parts of the admin backend to facebook or other social networks we&#039;ll have options in Admin panel to &amp;quot;publish as: common survey |mobile device survey | facebook poll | homepage poll |  ... etc &amp;quot; Everything will be put together at the usualm admin backend but you can choose which way(s) you want publish your survey.&lt;br /&gt;
&lt;br /&gt;
We can further extend this idea by giving additional options to publish as widgets for websites and blogs etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, XMPP Protocol (Knowledge of developing bots), Knowledge of Polls.&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;
==LimeSurvey 2: Survey Community Project==&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that connects to a central repository of survey resources, such as demographic questions, answer styles and templates. Integrating with a login system, allow LimeSurvey users to easily publish their work to a community resource or use other published works from the same location.&lt;br /&gt;
&lt;br /&gt;
For many finding already written question texts, or standardised demographic questions would really simplify their use of a survey tool. LimeSurvey could leverage on the community spirit of an open source product and encourage users to share their own work. By integrating a &amp;quot;Publish to the LimeSurvey Library&amp;quot; button in the administration system with questions, or templates, or anything else that can be shared, LimeSurvey could develop a library of tools that simplifies Survey Creation even further.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Web and User Interface Design Skills&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;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jasebo)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Condition Engine==&lt;br /&gt;
&lt;br /&gt;
[[File:addNewCondition1.png]]&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that will let survey administrators design, store and evaluate conditions. Conditions can be used in several features such as question branching (survey logic), assessments, quotas, ...&lt;br /&gt;
&lt;br /&gt;
This projects will at least end up with:&lt;br /&gt;
* A working GUI to design complex conditions:&lt;br /&gt;
** several atomic conditions can be combined by AND or OR logical operators and will support for grouping conditions with parentheses&lt;br /&gt;
** an atomic condition representation can be&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;left operand&amp;gt; &amp;lt;operator&amp;gt; &amp;lt;right operand&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** an atomic condition editor will implement&lt;br /&gt;
*** several operators (equality, inequality, string-comparisons, numerical-comparisons, regexp),...&lt;br /&gt;
*** meta operators surch as &#039;Not displayed&#039;&lt;br /&gt;
** left and right operands can be answers from previous questions, or a static values. It should be extensible so that we are able in the future to use more complex operand such as the result of a specific function (for instance the sum of some previous integer questions)&lt;br /&gt;
* A working DB storage backend using a string in [http://en.wikipedia.org/wiki/Reverse_Polish_Notation RPN] (Reverse Polish Notation) to describe each condition&lt;br /&gt;
* A first version of the evaluation of conditions for the question branching feature. This part will require interaction with other parts of the projects (Survey Engine, and DB engine).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JQuery and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thibault Le Meur (lemeur)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please read the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010+Condition+engine FAQ about this project]&lt;br /&gt;
&lt;br /&gt;
=We want your ideas!=&lt;br /&gt;
&lt;br /&gt;
What floats your boat? Do you have another idea that gets you excited? Discuss your ideas in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing lists] or at #limesurvey on irc.freenode.net.&lt;br /&gt;
&lt;br /&gt;
=More Information=&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Google&#039;s Summer of Code 2010==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010 Limesurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
An introduction to LimeSurvey and our application for this years Google Summer of Code&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started How to get started with LimeSurvey&#039;s GSoC]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google&#039;s Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2928</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2928"/>
		<updated>2010-01-28T14:34:07Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &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 is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
* first of all you have to &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&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;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; , &amp;quot;surveyDescription&amp;quot;, &amp;quot;welcomeText&amp;quot;, &amp;quot;endText&amp;quot;, &amp;quot;surveyAdmins@email.adress&amp;quot;, &amp;quot;Survey Adminsname&amp;quot;, &amp;quot;http://end.url&amp;quot;, &amp;quot;Description of End Url&amp;quot;, &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&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;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for 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;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&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;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2929</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2929"/>
		<updated>2009-11-27T12:19:34Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &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 is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
* first of all you have to &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&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;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; , &amp;quot;surveyDescription&amp;quot;, &amp;quot;welcomeText&amp;quot;, &amp;quot;endText&amp;quot;, &amp;quot;surveyAdmins@email.adress&amp;quot;, &amp;quot;Survey Adminsname&amp;quot;, &amp;quot;http://end.url&amp;quot;, &amp;quot;Description of End Url&amp;quot;, &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&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;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for 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;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&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;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to change this vars in lsrc.client.php (between lines 20 and 30)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl in the lsrc.client.php class is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2931</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2931"/>
		<updated>2009-11-19T08:44:39Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &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 is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
* first of all you have to &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&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;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&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;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&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;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; , &amp;quot;surveyDescription&amp;quot;, &amp;quot;welcomeText&amp;quot;, &amp;quot;endText&amp;quot;, &amp;quot;surveyAdmins@email.adress&amp;quot;, &amp;quot;Survey Adminsname&amp;quot;, &amp;quot;http://end.url&amp;quot;, &amp;quot;Description of End Url&amp;quot;, &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&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;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for 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;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&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;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to change this vars in lsrc.client.php (between lines 20 and 30)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl in the lsrc.client.php class is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Workarounds&amp;diff=3751</id>
		<title>Workarounds</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Workarounds&amp;diff=3751"/>
		<updated>2009-11-16T16:54:59Z</updated>

		<summary type="html">&lt;p&gt;Rakete: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&#039;&#039;&#039;Please keep in mind that the workarounds published here are no official Limesurvey extensions but solutions that other users created for themselves.&amp;lt;br/&amp;gt;&amp;lt;span style=&#039;color:#EE0000,#FFFFFF&#039;&amp;gt;Therefore we can&#039;t give support for any solution on this page.&amp;lt;/span&amp;gt;&amp;lt;br/&amp;gt;Please contact the users that, thankfully, shared their solutions with the community if you have any questions.&#039;&#039;&#039;&amp;lt;/center&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you have successfully tested a workaround please update the &amp;quot;tested with:...&amp;quot; entry. Thanks!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=Question Design, Layout, Templating=&lt;br /&gt;
&lt;br /&gt;
==Getting rid of the question mark symbol (help.gif)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.80+ (6536)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To get rid of the question mark symbol that LimeSurvey displays at the end of a question, you can either upload an empty help.gif into the template folder (as discussed in the forum) - or - you can use the Template editor: Open the &#039;&#039;template.css&#039;&#039; of your template and search for &#039;&#039;div.questionhelp img&#039;&#039;, then add a &#039;&#039;visibility:hidden;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will look something like this:&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;
div.questionhelp img&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  margin:5px;&lt;br /&gt;
&lt;br /&gt;
  visibility:hidden;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Use komma/virgule (komma: German data format) (virgule: french format) instead of dot when entering numbers==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LS1.53, LS1.70&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use kommas instead of dots when entering numbers make the following changes:&lt;br /&gt;
&lt;br /&gt;
Search the &amp;quot;qanda.php&amp;quot; for the function &amp;quot;function do_numerical&amp;quot; which should look like this &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;inhibited_keypress=\&amp;quot;return goodchars(event,&#039;0123456789.&#039;)\&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and replace the dot with a comma.&lt;br /&gt;
&lt;br /&gt;
==Require users to check a box agreeing to privacy statement before registering for a survey==&lt;br /&gt;
&lt;br /&gt;
If you need to have users positively acknowledge a privacy statement before submitting a registration form, the following will help you do this.&lt;br /&gt;
&lt;br /&gt;
It involves a minor modification to common.php in versions up to 1.85. Later versions may not require this.&lt;br /&gt;
&lt;br /&gt;
Edit common.php and look for the line (at approximately line 3014)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$registerform .= &amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;input class=&#039;submit&#039; type=&#039;submit&#039; value=&#039;&amp;quot;.$clang-&amp;gt;gT(&amp;quot;Continue&amp;quot;).&amp;quot;&#039; /&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$registerform .= &amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;input id=&#039;registercontinue&#039; class=&#039;submit&#039; type=&#039;submit&#039; value=&#039;&amp;quot;.$clang-&amp;gt;gT(&amp;quot;Continue&amp;quot;).&amp;quot;&#039; /&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then save common.php. This gives you DOM access to the &amp;quot;continue&amp;quot; button on the register form, but will have no other practical effect or change to LimeSurvey&#039;s operations.&lt;br /&gt;
&lt;br /&gt;
Next, you need to edit the template you are using (see the documentation on the Template editor if you don&#039;t know how to do this).&lt;br /&gt;
&lt;br /&gt;
In the template editor, open the screen &amp;quot;Register page&amp;quot; and select the file &amp;quot;register.pstpl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are two modifications you need to make to this file. The first is to add the following code after the line that says &#039;&#039;{REGISTERFORM}&#039;&#039;.&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;script type=&#039;text/javascript&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code disables the &amp;quot;Continue&amp;quot; button so that nobody can process the registration form until they&#039;ve clicked the checkbox.&lt;br /&gt;
&lt;br /&gt;
The second modification to make is to be done between the lines {REGISTERMESSAGE2} and {REGISTERFORM}. Add:&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;center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;label&amp;gt; Accept&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&#039;radio&#039;&lt;br /&gt;
&lt;br /&gt;
          name=&amp;quot;privacy&amp;quot;&lt;br /&gt;
&lt;br /&gt;
          value=&amp;quot;YES&amp;quot;&lt;br /&gt;
&lt;br /&gt;
          onChange=&amp;quot;if(this.checked) {&lt;br /&gt;
&lt;br /&gt;
                      document.getElementById(&#039;registercontinue&#039;).disabled=false;&lt;br /&gt;
&lt;br /&gt;
                    }&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/label&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;label&amp;gt;I don&#039;t accept&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&#039;radio&#039;&lt;br /&gt;
&lt;br /&gt;
          name=&amp;quot;privacy&amp;quot;&lt;br /&gt;
&lt;br /&gt;
          value=&amp;quot;NO&amp;quot;&lt;br /&gt;
&lt;br /&gt;
          CHECKED&lt;br /&gt;
&lt;br /&gt;
          onChange=&amp;quot;if(this.checked) {&lt;br /&gt;
&lt;br /&gt;
                      document.getElementById(&#039;registercontinue&#039;).disabled=true;&lt;br /&gt;
&lt;br /&gt;
                    }&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/label&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/center&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the users will have to agree to whatever text you replace &amp;quot;Do you agree to privacy stuff?&amp;quot; before they continue on and register.&lt;br /&gt;
&lt;br /&gt;
(Thanks to &#039;&#039;Pippo_Jedi&#039;&#039; for helping work this out)&lt;br /&gt;
&lt;br /&gt;
==Different progress indicator==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User [http://www.limesurvey.org/component/option,com_comprofiler/task,userProfile/Itemid,76/user,5344/lang,en/ Ypse] implemented a new kind of progress indicator. Instead of showing the progress in percent his solution marks the progress like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;3/6 (3 step of 6) Progress 14 %&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The code and a short tutorial on how to integrate this solution can be found in the [http://bugs.limesurvey.org/view.php?id=1893 bug and feature tracker].&lt;br /&gt;
&lt;br /&gt;
==Delete unwanted gaps in question title==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When copying data (questions, answers, ...) from MS Word or other applications into the editor there might occur some gaps in the question title.&lt;br /&gt;
&lt;br /&gt;
There are two solutions to this:&lt;br /&gt;
# Use popup mode and manually delete unwanting extra html tags (requires html knowledge).&lt;br /&gt;
# Disable paste word feature: Tweak your limesurvey-config.js file in limesurvey/admin/scripts/fckeditor.26 and set the following option to true:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;FCKConfig.ForcePasteAsPlainText = true ;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After that clear you browser cache and try again.&lt;br /&gt;
&lt;br /&gt;
==Removing the * (asterisk) from mandatory questions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mandatory questions are always preceded with a * to indicate that they are mandatory. You can modify the colour of this, or hide it completely by editing the css style in the template you are using.&lt;br /&gt;
&lt;br /&gt;
The default template uses the following, in the &amp;quot;startpage.pstpl&amp;quot; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;    .asterisk&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
       color: #FF0000;&lt;br /&gt;
&lt;br /&gt;
       font-size: 9pt;&lt;br /&gt;
&lt;br /&gt;
       font-family: verdana;&lt;br /&gt;
&lt;br /&gt;
       }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To hide the asterisk completely, add a line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;display: none;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To change the colour, change the colour code.&lt;br /&gt;
&lt;br /&gt;
Some templates don&#039;t have a style defined for .asterisk, and in this case you&#039;ll need to add one in the style sheet.&lt;br /&gt;
&lt;br /&gt;
==How to change the &amp;lt;font-size&amp;gt; tags using CSS==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This workaround was deleted because it is outdated. Such changes can be done by [http://docs.limesurvey.org/tiki-index.php?page=Template+editor&amp;amp;structure;=English+Instructions+for+LimeSurvey#Styling_questions_with_CSS adjusting template.css] of your template.&lt;br /&gt;
&lt;br /&gt;
==Question type variation: Scale with bars (one and two sided)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some methodogical issues to think about: Very often a common scale as 1 to 5 or -2 to +2 fits all needs, as the shown subject is clearly defined as positive or negative. As soon as you would reduce the influence from the question and scale on the respondent, you will need something neutral to determine tendences, emphases and so on.&lt;br /&gt;
&lt;br /&gt;
So I put up a new variation of the one and two sided array question:&lt;br /&gt;
&lt;br /&gt;
ttp://www.limesurvey.org/images/fbfiles/images/example_bar_scale.jpg&lt;br /&gt;
&lt;br /&gt;
In my example the left side reads &amp;quot;strategical planning&amp;quot; and the right side &amp;quot;operative business&amp;quot;. None of these are purely negative or positive, so the bars only show in which direction the balancing point moves.&lt;br /&gt;
&lt;br /&gt;
To realize a question as shown above just do as follows:&lt;br /&gt;
&lt;br /&gt;
Set up as many bars as you will need (in my example there are four different bars in total) with a graphic program like PAINT .NET, GIMP or similar ones (yes, you may also use commercial software like Photoshop). To prevent the bars from looking twitchy, designate the size in advance. I did one bar 60x15 px, one 45x15px, one 30x15px and at last 15x15px. Save them as PNG, JPG or GIF.&lt;br /&gt;
# Create a new label set within Lime. Call it whatever you like.&lt;br /&gt;
# Enter a code number at first, then press the pencil symbol to enter the editor.&lt;br /&gt;
#Press the &amp;quot;Insert / edit image&amp;quot; button and upload the bar you want to insert with the FCK upload tool. Then choose the uploaded picture, save and leave the FCK editor.&lt;br /&gt;
#The row in the lable editor now shows an &amp;lt;img&amp;gt;-tag which refers to your bar picture.&lt;br /&gt;
#Repeat the above described steps as often as needed to build up your bar scale.&lt;br /&gt;
&lt;br /&gt;
==Doing a Likert Scale==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A Likert Scale is a special type of the Semantic Differential question where several item shall be rated on different scales, each marked at the beginning and at the end with opposite statements. See example:&lt;br /&gt;
&lt;br /&gt;
ttp://www.limesurvey.org/images/fbfiles/images/lickert.jpg&lt;br /&gt;
&lt;br /&gt;
To do this in LimeSurvey just follow these steps:&lt;br /&gt;
#Create a label set with values from 0 to 7 (for the classic Likert Scale - feel free to choose other ranges).&lt;br /&gt;
#Create a new question and choose Array (Flexible Labels) as question type.&lt;br /&gt;
#Assign the Likert Scale label set to this question.&lt;br /&gt;
#Enter your answers as follows:&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;DIV style=&amp;quot;white-space: nowrap;&amp;quot;&amp;gt;ITEM statement1|statement2&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The white-space style is to avoid line breaks which would ruin the whole scale. feel free to insert non-breakable spaces between the ITEM and statement1 to define the margin between these to strings.&lt;br /&gt;
&lt;br /&gt;
==Alternate background colour of questions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7191)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To alternate the background colour of questions, open the &#039;&#039;template.css&#039;&#039; of your template with the Template Editor or a text editor and modify the &#039;&#039;Question styles&#039;&#039; section to include the following style.&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;
div#question2 td.questiontext,&lt;br /&gt;
&lt;br /&gt;
div#question4 td.questiontext,&lt;br /&gt;
&lt;br /&gt;
div#question6 td.questiontext {&lt;br /&gt;
&lt;br /&gt;
   background-color: #E0EBF8;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to apply the style to all of the questions you would like modified using their question IDs (&#039;&#039;question2, question4, question6&#039;&#039; in this case). Question IDs are displayed when creating or editing questions - see below:&lt;br /&gt;
&lt;br /&gt;
[[File:qid_1_493x173.gif]]&lt;br /&gt;
&lt;br /&gt;
Here are links to a couple of screenshots - [http://www.limesurvey.org/images/fbfiles//images/questionBgColourBefore_750x550.gif before] the styles change and [http://www.limesurvey.org/images/fbfiles//images/questionBgColourAfter_750x550.gif after]. The darker blue (#E0EBF8 in the &amp;quot;after&amp;quot; shot) is kinda subtle but could be more pronounced with something like #BACFEB.&lt;br /&gt;
&lt;br /&gt;
==Embedding audio in questions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7191), IE 7, FireFox 3&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Audio clips can be embedded in most question text or answer text. In this example, using the default template, I&#039;ve embedded clips into the answers of an &#039;&#039;&#039;&#039;&#039;Array (Yes/No/Uncertain)&#039;&#039;&#039;&#039;&#039; question to ask respondents how they feel about some sounds. The resulting question will look like this.&lt;br /&gt;
&lt;br /&gt;
[[File:audioTest_595x202.gif]]&lt;br /&gt;
&lt;br /&gt;
It&#039;s accomplished by placing the following code in each of the answers.&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;embed height=&amp;quot;20&amp;quot; width=&amp;quot;128&amp;quot; autostart=&amp;quot;false&amp;quot; controls=&amp;quot;console&amp;quot;&lt;br /&gt;
&lt;br /&gt;
loop=&amp;quot;true&amp;quot; volume=&amp;quot;50&amp;quot; src=&amp;quot;{TEMPLATEURL}audio_1.mp3&amp;quot;&amp;gt;&amp;lt;/embed&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The &#039;&#039;audio_1.mp3&#039;&#039; part will be different for each answer (it&#039;s the audio file name).&lt;br /&gt;
*In this case the audio files are residing in the template folder being used for this survey (that&#039;s where &#039;&#039;{TEMPLATEURL}&#039;&#039; points to) but they can be placed anywhere if you use an absolute URL in the &#039;&#039;src&#039;&#039; parameter - something like &#039;&#039;src=&amp;quot;http://mysite.com/audio/audio_1.mp3&amp;quot;&#039;&#039;&lt;br /&gt;
*If the audio file doesn&#039;t exist where the &#039;&#039;src&#039;&#039; parameter indicates, the player will not appear.&lt;br /&gt;
*You&#039;ll need to insert the code into the answers using the source screen - click on &amp;quot;Edit answers&amp;quot;, click the pencil beside the text box, click &amp;quot;Source&amp;quot; in the pop-up, enter the code and save it with the little diskette icon.&lt;br /&gt;
*You may need to turn off the XSS filter - see the documentation for [http://http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;highlight;=filterxsshtml#Security Configuration Optional Settings / Security].&lt;br /&gt;
&lt;br /&gt;
Although the above example places the audio in the answer text of the question, the same principles can be used to place it in the question text itself. Something like this perhaps.&lt;br /&gt;
&lt;br /&gt;
[[File:audioTest_595x154.gif]]&lt;br /&gt;
&lt;br /&gt;
==Hiding inputs of a &amp;quot;Multiple options with comments&amp;quot; question==&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&lt;br /&gt;
&lt;br /&gt;
There may be times when you want to hide some of the input boxes of a &#039;&#039;&#039;&#039;&#039;Multiple options with comments&#039;&#039;&#039;&#039;&#039; question as in the image below.&lt;br /&gt;
&lt;br /&gt;
[[File:hidden_inputs_541x168.gif]]&lt;br /&gt;
&lt;br /&gt;
This can be accomplished with CSS (see [http://docs.limesurvey.org/tiki-index.php?page=Template+editor&amp;amp;structure;=English+Instructions+for+LimeSurvey#Styling_questions_in_LimeSurvey_1.8 Styling questions in LimeSurvey 1.8]). For each input that you want to hide, add the following style to your template.css file:&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;
#answer11111X22X33Acomment {&lt;br /&gt;
&lt;br /&gt;
   display: none;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Where 11111 is your survey ID, 22 is your group ID, 33 is your question ID and A is the answer code.&lt;br /&gt;
&lt;br /&gt;
Note that you will still see columns for the hidden inputs in your data but they will be empty.&lt;br /&gt;
&lt;br /&gt;
== Multiple question types in array==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2 (Yes/No question styles need tweaking in Safari)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to present multiple question types in what appears to be an array - as depicted in the image below and [http://www.partnersinc.biz/surveys//index.php?sid=52381&amp;amp;newtest;=Y&amp;amp;lang;=en demonstrated here]. This example uses the default template shipped with 7557 but should be adaptable to any template using divisions for question containers.&lt;br /&gt;
&lt;br /&gt;
[[File:inline_questions_700x228.png]]&lt;br /&gt;
&lt;br /&gt;
Basically what we do is take groups of questions (5 in this case), wrap them in a division and make them line up nicely horizontally and vertically. The width of the survey is also fixed to prevent wrapping issues. We do this with an onload function that inserts the necessary wrappers and then modifies styles so everything behaves properly. The top row is 5 boilerplate questions with the &amp;quot;column headers&amp;quot; as question text (the first just has a blank space). The following rows are a boilerplate with the &amp;quot;row headers&amp;quot; followed by 4 assorted questions.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here]).&lt;br /&gt;
#Set up the template to use custom onload functions (see the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here]).&lt;br /&gt;
#Create your questions keeping in mind how they will lay out when grouped into rows (in this example - boilerplate, yes/no, short text, numeric, dropdown, and repeat).&lt;br /&gt;
#In the source of the first boilerplate question add the following onload function (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]).&lt;br /&gt;
#Modify the question IDs in the first section of the code to match your survey.&lt;br /&gt;
&lt;br /&gt;
The code may look intimidating at first but it&#039;s actually fairly simple. I&#039;ve layed it out as sequentially as possible and purposely used few shortcuts and many comments to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
Some brief notes about the code:&lt;br /&gt;
#The first section just assigns attributes to questions so we can handle them as rows or columns later - in this case 190-194 are row 1 (the top boilerplates), 195-199 are row 2, etc.&lt;br /&gt;
#The second section fixes the width of the survey (not necessary with fixed-width templates), inserts wrapper elements around each group of questions (rows) and forces each group to display horizontally.&lt;br /&gt;
#The next section adjusts column widths.&lt;br /&gt;
#The final section applies styles to the different question types to hide unnecessary elements and ensure that vertical alignment, question height, etc are consistent.&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   /***********&lt;br /&gt;
&lt;br /&gt;
   Display multiple questions side by side&lt;br /&gt;
&lt;br /&gt;
   ***********/&lt;br /&gt;
&lt;br /&gt;
   //////// Define question attributes for later use ////////&lt;br /&gt;
&lt;br /&gt;
   // Give questions row specific attributes so we can easily manipulate them by row&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question190, #question191, #question192, #question193, #question194&#039;).attr(&#039;name&#039;, &#039;qRow1&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question195, #question196, #question197, #question198, #question199&#039;).attr(&#039;name&#039;, &#039;qRow2&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question200, #question201, #question202, #question203, #question204&#039;).attr(&#039;name&#039;, &#039;qRow3&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question205, #question206, #question207, #question208, #question209&#039;).attr(&#039;name&#039;, &#039;qRow4&#039;);&lt;br /&gt;
&lt;br /&gt;
   // Give questions column specific attributes so we can easily manipulate them by column&lt;br /&gt;
&lt;br /&gt;
   // I know, not the correct use of &amp;quot;rel&amp;quot; attribute but...too bad!&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question190, #question195, #question200, #question205&#039;).attr(&#039;rel&#039;, &#039;qCol1&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question191, #question196, #question201, #question206&#039;).attr(&#039;rel&#039;, &#039;qCol2&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question192, #question197, #question202, #question207&#039;).attr(&#039;rel&#039;, &#039;qCol3&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question193, #question198, #question203, #question208&#039;).attr(&#039;rel&#039;, &#039;qCol4&#039;);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question194, #question199, #question204, #question209&#039;).attr(&#039;rel&#039;, &#039;qCol5&#039;);&lt;br /&gt;
&lt;br /&gt;
   //////// Survey layout manipulation ////////&lt;br /&gt;
&lt;br /&gt;
   // Fix the width of the survey&lt;br /&gt;
&lt;br /&gt;
   $( &#039;table.outerframe&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;900px&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Wrap each row in a div&lt;br /&gt;
&lt;br /&gt;
   // This is kinda verbose but IE won&#039;t let me use jQuery shortcuts&lt;br /&gt;
&lt;br /&gt;
   var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
&lt;br /&gt;
   el.setAttribute(&#039;id&#039;,&#039;inlineWrapper1&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;div[name=&amp;quot;qRow1&amp;quot;]&#039;).wrapAll($(&#039;#inlineWrapper1&#039;));&lt;br /&gt;
&lt;br /&gt;
   el.setAttribute(&#039;id&#039;,&#039;inlineWrapper2&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;div[name=&amp;quot;qRow2&amp;quot;]&#039;).wrapAll($(&#039;#inlineWrapper2&#039;));&lt;br /&gt;
&lt;br /&gt;
   el.setAttribute(&#039;id&#039;,&#039;inlineWrapper3&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el);&lt;br /&gt;
&lt;br /&gt;
   $(&#039;div[name=&amp;quot;qRow3&amp;quot;]&#039;).wrapAll($(&#039;#inlineWrapper3&#039;));&lt;br /&gt;
&lt;br /&gt;
   el .setAttribute(&#039;id&#039;,&#039;inlineWrapper4&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el );&lt;br /&gt;
&lt;br /&gt;
   $(&#039;div[name=&amp;quot;qRow4&amp;quot;]&#039;).wrapAll($(&#039;#inlineWrapper4&#039;));&lt;br /&gt;
&lt;br /&gt;
   // Style the wrapper divs&lt;br /&gt;
&lt;br /&gt;
   $( &#039;#inlineWrapper1, #inlineWrapper2, #inlineWrapper3, #inlineWrapper4&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;850px&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;margin&#039;: &#039;0 auto 0 auto&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;clear&#039;: &#039;both&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Get all the questions to sit politely side by side&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div[name=&amp;quot;qRow1&amp;quot;], div[name=&amp;quot;qRow2&amp;quot;], div[name=&amp;quot;qRow3&amp;quot;], div[name=&amp;quot;qRow4&amp;quot;]&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;float&#039;: &#039;left&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;display&#039;: &#039;inline&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   //////// Column manipulation ////////&lt;br /&gt;
&lt;br /&gt;
   // Set the column widths - can be set individually if necessary&lt;br /&gt;
&lt;br /&gt;
   // Must add up to less than 100%&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div[rel=&amp;quot;qCol1&amp;quot;]&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;12%&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div[rel=&amp;quot;qCol2&amp;quot;], div[rel=&amp;quot;qCol3&amp;quot;], div[rel=&amp;quot;qCol4&amp;quot;], div[rel=&amp;quot;qCol5&amp;quot;]&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;22%&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   //////// Question manipulation ////////&lt;br /&gt;
&lt;br /&gt;
   // Hide the answer element in boilerplate questions&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.boilerplate td.answer&#039; ).parent().hide();&lt;br /&gt;
&lt;br /&gt;
   // Hide the question text elements in non-boilerplate questions&lt;br /&gt;
&lt;br /&gt;
   $(&#039;div.text-short td.questiontext, div.list-dropdown td.questiontext,&lt;br /&gt;
&lt;br /&gt;
  // CAUTION: Manually introduced line break, should be &amp;quot;...td.questiontext, div.yes-no td.questiontext, ...&lt;br /&gt;
&lt;br /&gt;
  div.yes-no td.questiontext, div.numeric td.questiontext&#039;).parent().hide();&lt;br /&gt;
&lt;br /&gt;
   // Push the question tables to 100%&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div[name=&amp;quot;qRow1&amp;quot;] table, div[name=&amp;quot;qRow2&amp;quot;] table, div[name=&amp;quot;qRow3&amp;quot;] table, div[name=&amp;quot;qRow4&amp;quot;] table&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;100%&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Get everything to line up nicely vertically&lt;br /&gt;
&lt;br /&gt;
   $( &#039;td.questiontext, td.answer p&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;text-align&#039;: &#039;center&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Adjust cell heights so everything lines up nicely horizontally&lt;br /&gt;
&lt;br /&gt;
   $( &#039;td.answer, td.questiontext&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;height&#039;:&#039;35px&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Yes-no question styles&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.yes-no ul&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;text-align&#039;: &#039;center&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;font-size&#039;: &#039;90%&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;margin&#039;: &#039;0&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;padding-bottom&#039;: &#039;5px&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.yes-no td.answer&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;padding-bottom&#039;: &#039;0&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Short-text question styles&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.text-short input&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;125px&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;margin-left&#039;: &#039;0&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Numeric question styles&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.numeric input&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;width&#039;: &#039;125px&#039;,&lt;br /&gt;
&lt;br /&gt;
     &#039;margin-left&#039;: &#039;0&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div.numeric p.tip&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;display&#039;: &#039;none&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Get rid of the margins around select boxes&lt;br /&gt;
&lt;br /&gt;
   $( &#039;p.question&#039; ).css({&#039;margin&#039;:&#039;0&#039;});&lt;br /&gt;
&lt;br /&gt;
   // Reduce the space caused by the question help table&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div[name=&amp;quot;qRow1&amp;quot;], div[name=&amp;quot;qRow2&amp;quot;], div[name=&amp;quot;qRow3&amp;quot;]&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
     &#039;margin-bottom&#039;: &#039;-8px&#039;&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;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Star Rating System==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://www.fyneworks.com/jquery/star-rating/ jQuery Star Rating Plugin] to display a series of stars that are used to generate a rating value. This value is then passed to either a hidden numeric input question or a hidden list radio question. Both methods are outlined below - use one or both depending on whether you want to use [http://docs.limesurvey.org/tiki-index.php?page=Assessments&amp;amp;structure;=English+Instructions+for+LimeSurvey assessments].&lt;br /&gt;
&lt;br /&gt;
The plugin uses a series of radio inputs to generate the stars (more about these below). It allows the use of whole or partial stars as shown in [http://www.partnersinc.biz/surveys//index.php?sid=47586&amp;amp;newtest;=Y&amp;amp;lang;=en this demo] and the image below.&lt;br /&gt;
&lt;br /&gt;
[[File:star_rating_700x324.png]]&lt;br /&gt;
&lt;br /&gt;
=== Star Rating System Using Numeric Input Question===&lt;br /&gt;
&lt;br /&gt;
Use this method if you would like your rating data to be collected as a numeric value and don&#039;t want to use [http://docs.limesurvey.org/tiki-index.php?page=Assessments&amp;amp;structure;=English+Instructions+for+LimeSurvey assessments] - it&#039;s a little easier to implement. There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=47586&amp;amp;newtest;=Y&amp;amp;lang;=en here] (first question).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation is as follows:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
&lt;br /&gt;
2. Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
&lt;br /&gt;
3. [http://www.fyneworks.com/jquery/star-rating/ Download the plugin] and place the following included files in your template folder:&lt;br /&gt;
*jquery.MetaData.js&lt;br /&gt;
*jquery.rating.css&lt;br /&gt;
*jquery.rating.js&lt;br /&gt;
*delete.gif&lt;br /&gt;
*star.gif&lt;br /&gt;
&lt;br /&gt;
4. In the &amp;lt;head&amp;gt; section of your startpage.pstpl, add the following code to link to the files.&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;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.rating.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.MetaData.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.rating.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Create a numeric input question and then in the source of the question add as many radio inputs as star segments. For example, if you would like 5 stars, each with half-segments (as in the demo Q1), you would need 10 radio inputs and that would give rating values from 1-10.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t confuse these inputs with the actual question, they are just for the plugin&#039;s use.&lt;br /&gt;
&lt;br /&gt;
At this point your question source code should look something like below. Make sure that all inputs have the same name. Each input must have the same title as value and these must be sequential. Don&#039;t worry about how all of this looks in the WSYSWYG editor - the plugin is going to hide these inputs and replace them with stars.&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;
Q1 - Some question text here.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;starContainer&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;2&amp;quot; value=&amp;quot;2&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;3&amp;quot; value=&amp;quot;3&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;4&amp;quot; value=&amp;quot;4&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;5&amp;quot; value=&amp;quot;5&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;6&amp;quot; value=&amp;quot;6&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;7&amp;quot; value=&amp;quot;7&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;8&amp;quot; value=&amp;quot;8&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;9&amp;quot; value=&amp;quot;9&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;10&amp;quot; value=&amp;quot;10&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. A note on split stars. The stars in the above example are split in half by the &#039;&#039;{split:2}&#039;&#039; metadata. So if you don&#039;t want split stars, your inputs would look like:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
And stars split into third-segments would look like:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:3}&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
7. Finally, in the source of the question add the following onload function after your inputs. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here])&lt;br /&gt;
&lt;br /&gt;
Some notes on the code:&lt;br /&gt;
*Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
*The code will hide the numeric input and pass the rating values into it as they are changed. If the rating is canceled the numeric input is nullified. If a respondent navigates away from the page then returns the code &amp;quot;remembers&amp;quot; the previous rating and displays the stars accordingly.&lt;br /&gt;
*If you want to apply it to more numeric questions on the same page simply add more calls with the appropriate IDs. (eg. handleRatingNumeric(11111, 22, 1); handleRatingNumeric(11111, 22, 2); ...) .&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
function handleRatingNumeric (sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
   // Hide the numeric input&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; td.answer&#039;).parent().hide();&lt;br /&gt;
&lt;br /&gt;
   // Get a previous rating (if any) and use it to initialize the star display&lt;br /&gt;
&lt;br /&gt;
   var rating = $(&#039;#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + &#039;&#039;).val();&lt;br /&gt;
&lt;br /&gt;
   if ( rating != &#039;&#039; ) {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; input.star&#039;).rating(&#039;select&#039;, rating);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Listener on the star rating cancel element&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; div.rating-cancel&#039;).click(function(event) {&lt;br /&gt;
&lt;br /&gt;
       // Nullify the rating if the Cancel element is clicked&lt;br /&gt;
&lt;br /&gt;
       rating = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + &#039;&#039;).val(rating);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Listener on the star rating elements&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; div.star-rating&#039;).click(function(event) {&lt;br /&gt;
&lt;br /&gt;
       // Find the value of the highest clicked star and pass it into the text input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; div.star-rating-on&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
           rating = $(this).children(&#039;a&#039;).html( );&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + &#039;&#039;).val(rating);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the function for the numeric question&lt;br /&gt;
&lt;br /&gt;
handleRatingNumeric (SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Star Rating System Using List (Radio) Question===&lt;br /&gt;
&lt;br /&gt;
Use this method if you would like to use [http://docs.limesurvey.org/tiki-index.php?page=Assessments&amp;amp;structure;=English+Instructions+for+LimeSurvey assessments]. There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=47586&amp;amp;newtest;=Y&amp;amp;lang;=en here] (second question).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation is as follows:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
&lt;br /&gt;
2. Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
&lt;br /&gt;
3. [http://www.fyneworks.com/jquery/star-rating/ Download the plugin] and place the following included files in your template folder:&lt;br /&gt;
*jquery.MetaData.js&lt;br /&gt;
*jquery.rating.css&lt;br /&gt;
*jquery.rating.js&lt;br /&gt;
*delete.gif&lt;br /&gt;
*star.gif&lt;br /&gt;
&lt;br /&gt;
4. In the &amp;lt;head&amp;gt; section of your startpage.pstpl, add the following code to link to the files.&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;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.rating.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.MetaData.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.rating.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Create a list (radio) question with the same amount of sequentially numbered answers as star ratings. For example, if you want 5 whole-stars, you would create 5 answers, as in the image below, and this would give you ratings from 1-5. Note that the &amp;quot;Codes&amp;quot; and &amp;quot;Answers&amp;quot; must be sequential numbers.&lt;br /&gt;
&lt;br /&gt;
[[File:star_rating_700x156_v2.png]]&lt;br /&gt;
&lt;br /&gt;
6. In the list (radio) question, set the [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#hide_tip hide_tip] question attribute to 1&lt;br /&gt;
&lt;br /&gt;
7. In the source of the question add as many radio inputs as star segments. So 5 whole-stars (as in the demo Q2), would need 5 radio inputs.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t confuse these inputs with the actual question, they are just for the plugin&#039;s use.&lt;br /&gt;
&lt;br /&gt;
At this point your question source code should look something like below. Make sure that all inputs have the same name. Each input must have the same title as value and these must be sequential. Don&#039;t worry about how all of this looks in the WSYSWYG editor - the plugin is going to hide these inputs and replace them with stars.&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;
Q2 - Some question text here.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;starContainer&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q2Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;2&amp;quot; value=&amp;quot;2&amp;quot; name=&amp;quot;q2Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;3&amp;quot; value=&amp;quot;3&amp;quot; name=&amp;quot;q2Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;4&amp;quot; value=&amp;quot;4&amp;quot; name=&amp;quot;q2Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star&amp;quot; title=&amp;quot;5&amp;quot; value=&amp;quot;5&amp;quot; name=&amp;quot;q2Rate&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. A note on split stars. The stars in the above example are whole-stars. If you want them split you need to add metadata to the class - something like &#039;&#039;{split:2}&#039;&#039;. So if you want half-stars your inputs would look like:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:2}&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
And stars split into third-segments would look like:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;input type=&amp;quot;radio&amp;quot; class=&amp;quot;star {split:3}&amp;quot; title=&amp;quot;1&amp;quot; value=&amp;quot;1&amp;quot; name=&amp;quot;q1Rate&amp;quot; /&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
9. Finally, in the source of the question add the following onload function after your inputs. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here])&lt;br /&gt;
&lt;br /&gt;
Some notes on the code:&lt;br /&gt;
*Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
*The code will hide the question radio buttons and toggle them as the rating values are changed. If the rating is canceled all question inputs are unchecked. If a respondent navigates away from the page then returns the code &amp;quot;remembers&amp;quot; the previous rating and displays the stars accordingly.&lt;br /&gt;
*If you want to apply it to more numeric questions on the same page simply add more calls with the appropriate IDs. (eg. handleRatingRadio(11111, 22, 1); handleRatingRadio(11111, 22, 2); ...) .&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
function handleRatingRadio (sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
   // Hide the radio input&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; td.answer&#039;).parent().hide();&lt;br /&gt;
&lt;br /&gt;
   // Get a previous rating (if any) and use it to initialize the star display&lt;br /&gt;
&lt;br /&gt;
   var rating = $(&#039;#question&#039; + qID + &#039; input.radio[checked=true]&#039;).attr(&#039;value&#039;);&lt;br /&gt;
&lt;br /&gt;
   //if ( rating != &#039;&#039; ) {&lt;br /&gt;
&lt;br /&gt;
   if ( rating ) {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; input.star&#039;).rating(&#039;select&#039;, rating);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Listener on the star rating cancel element&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; div.rating-cancel&#039;).click(function(event) {&lt;br /&gt;
&lt;br /&gt;
       // Nullify the rating if the Cancel element is clicked&lt;br /&gt;
&lt;br /&gt;
       rating = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; input.radio&#039;).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Listener on the star rating elements&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#question&#039; + qID + &#039; div.star-rating&#039;).click(function(event) {&lt;br /&gt;
&lt;br /&gt;
       // Find the value of the highest clicked star and pass it into the text input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; div.star-rating-on&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
           rating = $(this).children(&#039;a&#039;).html( );&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question&#039; + qID + &#039; input.radio[value=&#039; + rating + &#039;]&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the function for the radio question&lt;br /&gt;
&lt;br /&gt;
handleRatingRadio (SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Variable column widths in array==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define all column widths of an array question - as shown in the image below and [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest;=Y&amp;amp;lang;=en demonstrated here]. This example uses the default template shipped with 7557 but should be adaptable to any template.&lt;br /&gt;
&lt;br /&gt;
[[File:array_widths_701x226.gif]]&lt;br /&gt;
&lt;br /&gt;
We use a custom onload function to remove all of the widths imposed by the core code and then insert our own.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation is as follows:&#039;&#039;&#039;&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here]).&lt;br /&gt;
#Set up the template to use custom onload functions (see the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following onload function (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]).&lt;br /&gt;
#Replace all instances of QQ with the question ID.&lt;br /&gt;
#In the third section of code, adjust the widths and add/remove columns as necessary. This example is for an array with a question text column followed by 3 answer columns as shown above.&lt;br /&gt;
#In the final section adjust the question text alignment to your liking&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // Get rid of all the widths that the API imposes&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question col&#039; ).attr(&#039;width&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question thead td&#039; ).attr(&#039;width&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   // Define a width for the question table so we can do so for its children&lt;br /&gt;
&lt;br /&gt;
   // NOTE: Keep this to 95% or less so IE will behave&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question&#039; ).attr(&#039;width&#039;, &#039;95%&#039;);&lt;br /&gt;
&lt;br /&gt;
   // Define the column widths&lt;br /&gt;
&lt;br /&gt;
   // Add or remove columns and adjust widths as necessary but widths should add up to 100%&lt;br /&gt;
&lt;br /&gt;
   // NOTE: Columns must be sequentially numbered starting at 0 - eg, td:eq(0), td:eq(1), td:eq(2).....&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question tbody th:eq(0)&#039; ).css({&#039;width&#039;:&#039;10%&#039;}); // Answer text column&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question tbody td:eq(0)&#039; ).css({&#039;width&#039;:&#039;50%&#039;}); // First answer column&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question tbody td:eq(1)&#039; ).css({&#039;width&#039;:&#039;20%&#039;}); // Second answer column&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question tbody td:eq(2)&#039; ).css({&#039;width&#039;:&#039;20%&#039;}); // Third answer column&lt;br /&gt;
&lt;br /&gt;
   // Push the text input widths to 95% of their parent containers&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question input[type=&amp;quot;text&amp;quot;]&#039; ).css({&#039;width&#039;:&#039;95%&#039;});&lt;br /&gt;
&lt;br /&gt;
   // Align the answer text - feel free to experiment&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#questionQQ table.question tbody th&#039; ).css({&#039;text-align&#039;:&#039;center&#039;});&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changing radio buttons and checkboxes==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (7116), Googlechrome 3.0, IE 7, FireFox 3.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the jQuery imagetick.js to change the default radio buttons and checkboxes. Example:&lt;br /&gt;
&lt;br /&gt;
[[File:screenshot.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation is as follows:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects Turn off $filterxsshtml] to allow insertion of JavaScript in the questions.&lt;br /&gt;
&lt;br /&gt;
2. Set up the template to [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function&lt;br /&gt;
&lt;br /&gt;
|use custom onload functions].&lt;br /&gt;
&lt;br /&gt;
3. Download the plugin [here|http://boedesign.com/download.php?file=imagetick] and place the following files in your template folder:&lt;br /&gt;
*imagetick.js&lt;br /&gt;
*check.gif&lt;br /&gt;
*no_check.gif&lt;br /&gt;
*no_radio.gif&lt;br /&gt;
*radio.gif&lt;br /&gt;
&lt;br /&gt;
4. In the head section of your startpage.pstpl, add the following code to link to the files.&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;head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}imagetick.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. In the source of the question [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._&lt;br /&gt;
&lt;br /&gt;
|add the following onload function] after your inputs:&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;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
   // the selector can be a class as well, target your radios or checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&amp;quot;input.radio&amp;quot;).imageTick({&lt;br /&gt;
&lt;br /&gt;
       // the image you want to use as a selected state of the radio/checkbox&lt;br /&gt;
&lt;br /&gt;
       tick_image_path: &amp;quot;{TEMPLATEURL}radio.gif&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
       // image you want to use as a non selected state&lt;br /&gt;
&lt;br /&gt;
       // the class you want to apply to all images that are dynamically created&lt;br /&gt;
&lt;br /&gt;
       no_tick_image_path: &amp;quot;{TEMPLATEURL}no_radio.gif&amp;quot;, image_tick_class: &amp;quot;radios&amp;quot;});&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;input.checkbox&amp;quot;).imageTick({ // the selector can be a class as well&lt;br /&gt;
&lt;br /&gt;
           tick_image_path: &amp;quot;{TEMPLATEURL}check.gif&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
           no_tick_image_path: &amp;quot;{TEMPLATEURL}no_check.gif&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
           image_tick_class: &amp;quot;checkboxes&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to apply it to only one question on a page use selector&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&amp;quot;#questionQQ input.radio&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where QQ is the question ID&lt;br /&gt;
&lt;br /&gt;
If you want to apply it to a single radio button in a question (to maybe have different images for each option) use selector&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&amp;quot;input#answerSSSSSXGGXQQAA&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where SSSSS is the survey ID, GG is the group ID, QQ is the question ID, AA is the answer code.&lt;br /&gt;
&lt;br /&gt;
=Javascript=&lt;br /&gt;
&lt;br /&gt;
==How to &#039;&#039;add&#039;&#039; javascript workarounds==&lt;br /&gt;
&lt;br /&gt;
Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with &amp;quot;&#039;&#039;&#039;!!&#039;&#039;&#039;&amp;quot;. Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet &amp;lt;nowiki&amp;gt;&#039;&#039;Tested with: (enter Limesurvey version and maybe browser)&#039;&#039;&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Finally it&#039;s imported to mark all your code with code tags, other wise you might break this page.&lt;br /&gt;
*Start tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
*End tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==How to &#039;&#039;use&#039;&#039; Script (eg. JavaScript etc.)==&lt;br /&gt;
&lt;br /&gt;
If you want to use javascript within Limesurvey you previously have to disable a security filter before you can add your javascript in source code mode:&lt;br /&gt;
&lt;br /&gt;
FIRST, some info from config-default.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;//$filterxsshtml&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
// Enables filtering of suspicious html tags in survey, group, questions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
// and answer texts in the administration interface&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
// Only set this to false if you absolutely trust the users&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
// you created for the administration of  LimeSurvey and if you want to&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
// allow these users to be able to use Javascript etc. .&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
$filterxsshtml = true;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Follow these steps:&lt;br /&gt;
* In config.php add &#039;&#039;&#039;$filterxsshtml = false;&#039;&#039;&#039; (maybe as a last line before &#039;&#039;&#039;?&amp;gt;&#039;&#039;&#039;).&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Adding+A+Question Add a new question]&lt;br /&gt;
* In the question field, expande the tool bar by clicking the upper grey bar to get to the [http://docs.limesurvey.org/tiki-index.php?page=First+Login+%2F+You+user+preferences&amp;amp;structure;=English+Instructions+for+LimeSurvey#The_HTML_editor_mode source code editor]:&lt;br /&gt;
&lt;br /&gt;
[[File:InlineMode1.PNG]]&lt;br /&gt;
* Click on the button LimeFitWin to get full screen mode with even more buttons in the tool bar:&lt;br /&gt;
&lt;br /&gt;
[[File:InlineMode2.PNG]]&lt;br /&gt;
* Click on the button Source&lt;br /&gt;
&lt;br /&gt;
Now you can add your code. A simple test to see if javascript is enabled is to echo an alert. Use this 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sum up input values using Javascript==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is from a survey that is a invitation to a longer party, when the user clicks to the next page, the calculated results will be shown.&lt;br /&gt;
&lt;br /&gt;
If you wonder what the {INSERTANS:1X6X12} stuff is, look at [http://docs.limesurvey.org/tiki-index.php?page=SGQA+Identifier SGQA identifier] and [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers Using information from previous answers].&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;div style=&amp;quot;text-align: left&amp;quot;&amp;gt;These are your answers:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;script LANGUAGE=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
partyprice = 3;&lt;br /&gt;
&lt;br /&gt;
beadclothprice = 3;&lt;br /&gt;
&lt;br /&gt;
breakfastprice = 7;&lt;br /&gt;
&lt;br /&gt;
lunchprice = 8;&lt;br /&gt;
&lt;br /&gt;
dinnerprice = 10;&lt;br /&gt;
&lt;br /&gt;
foodtotal = 0;&lt;br /&gt;
&lt;br /&gt;
var isreallytrue = &amp;quot;Yes&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var noanswer = &amp;quot;No answer&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
document.write( &amp;quot;Can you come? = {INSERTANS:45251X1X1}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:45251X1X1}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X3}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
   else {answer = &amp;quot;{INSERTANS:45251X1X3}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   partypeople = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   partytotal = partyprice * partypeople;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;It&#039;s {INSERTANS:45251X1X3} persons who will come = &amp;quot; + partytotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X4}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
   else {answer = &amp;quot;{INSERTANS:45251X1X4}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   beadcloths = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   beadclothtotal = beadclothprice * beadcloths;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;You want to borrow {INSERTANS:45251X1X4} beadcloths = &amp;quot; + beadclothtotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there thursday? = {INSERTANS:45251X1X5}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;On friday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X71}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
   else {answer = &amp;quot;{INSERTANS:45251X1X71}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   breakfastfriday = parseInt(answer) * breakfastprice;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X72}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
   else {answer = &amp;quot;{INSERTANS:45251X1X72}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   lunchfriday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X73}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
   else {answer = &amp;quot;{INSERTANS:45251X1X73}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   dinnerfriday = parseInt(answer)* dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnerfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   foodtotal = breakfastfriday + lunchfriday + dinnerfriday;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there saturday? = {INSERTANS:45251X1X8}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X8}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On saturday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X91}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X91}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       breakfastsaturday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write(&amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X92}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X92}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       lunchsaturday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X93}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X93}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       dinnersaturday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsaturday + lunchsaturday + dinnersaturday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there sunday? = {INSERTANS:45251X1X10}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X10}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On sunday you will have these meals: &amp;lt;br&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X111}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X111}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       breakfastsunday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot;  );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X112}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X112}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       lunchsunday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X113}&amp;quot;== noanswer) {answer = 0;}&lt;br /&gt;
&lt;br /&gt;
       else {answer = &amp;quot;{INSERTANS:45251X1X113}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
       dinnersunday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersunday + &amp;quot;&amp;amp;euro;&amp;lt;p&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsunday + lunchsunday + dinnersunday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   total = partytotal + beadclothtotal + foodtotal;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&amp;lt;h3&amp;gt;In total it will cost you &amp;quot; + total + &amp;quot;&amp;amp;euro;&amp;lt;/h3&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Put that sum in this bank account 1234 5678 9012&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/SCRIPT&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Multiple Question Validation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround is in case you need to do some validation involving more than one question, it implies a very little JavaScript programming and the use of SQGA Identifiers; this should work on almost any version of LimeSurvey.&lt;br /&gt;
&lt;br /&gt;
Is easy to explain with an example, we need to do a survey of the percentage of males and females and we want to be sure that the sum is 100, to do this follow this steps (the necessary data that is not indicated in these instructions are not important i.e. question codes, etc.):&lt;br /&gt;
#Create a new survey of type &amp;amp;ldquo;group by group&amp;amp;rdquo;, set the &amp;amp;ldquo;Show |&amp;lt;&amp;lt; Prev| button&amp;amp;rdquo; to yes and note the SID.&lt;br /&gt;
#Add a new group called &amp;amp;ldquo;Group 1&amp;amp;rdquo; and note the GID.&lt;br /&gt;
#Add a new question &amp;amp;ldquo;Percent of males&amp;amp;rdquo; of type &amp;amp;ldquo;numeric&amp;amp;rdquo;, make it mandatory and note the QID (we will refer to this as QID1).&lt;br /&gt;
#Add a new question &amp;amp;ldquo;Percent of females&amp;amp;rdquo; of type &amp;amp;ldquo;numeric&amp;amp;rdquo;, make it mandatory and note the QID (we will refer to this as QID2).&lt;br /&gt;
#Add a new group called &amp;amp;ldquo;Group 2&amp;amp;rdquo;&lt;br /&gt;
#Add a new non mandatory question, here is the trick the question text has to be (be sure to replace the SID, GID, QID1 and QID2&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function validation()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   if [[{INSERTANS:SIDXGIDXQID1}+{INSERTANS:SIDXGIDXQID2}) != 100)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t sum 100! Check them&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;movelast&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 But this will show shortly the question and will jump to the end page, a little weird for the survey taker but works.&lt;br /&gt;
&lt;br /&gt;
 This is a proof of concept, and may have some problems, please if you notice something or improve it send me an e-mail to leochaton-limesurvey at yahoo dot com.&lt;br /&gt;
&lt;br /&gt;
 This will work for 2 questions that you want to be the same.  Works well for email and confirm email questions&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;
  function validation() {&lt;br /&gt;
&lt;br /&gt;
  if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; != &amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t match Check them&amp;quot;); document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ==Alternate exit==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 Using the same idea of the previous post, you can implement an alternate exit of your survey.&lt;br /&gt;
&lt;br /&gt;
 This script should be in the first question to be displayed in a next page after the question that should trigger the alternate exit. In this example the question that trigger the alternate exit is a Yes/No question, if the user chooses no, he is redirected to another page.&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; == &amp;quot;No&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
&lt;br /&gt;
   window.location=&amp;quot;http://www.limesurvey.org&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ==Custom onload function==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 This simple workaround describes how to &#039;&#039;&#039;add a custom onload function&#039;&#039;&#039; triggering when the page is being loaded. It may have numerous applications, especially when you deal with a custom JS/HTML code. It may be used to hide form elements (&amp;lt;input&amp;gt;  tags), make them read-only, display alert messages, etc.&lt;br /&gt;
&lt;br /&gt;
 1. First, the template&#039;s of your choice &amp;quot;end page&amp;quot; code needs to be tweaked (it&#039;s in endpage.pstpl file). This is the only permanent change we&#039;ll be making here. Please note, that this change is harmless. Even if you are not gonna use any custom onload functions, it may stay there and it will not affect other surveys/questions in any way.&lt;br /&gt;
&lt;br /&gt;
 The modified content of your endpage.pstpl file should be as follows (~060~script~062~ section has been inserted):&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;/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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
           // only call if it&#039;s defined&lt;br /&gt;
&lt;br /&gt;
           if(typeof Custom_On_Load == &#039;function&#039;){&lt;br /&gt;
&lt;br /&gt;
              Custom_On_Load();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
           &amp;lt;/body&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 2. Now, if you define a function called &amp;quot;Custom_On_Load&amp;quot; anywhere in your code, it will be executed when the page is being loaded. For example when you add the following code to one of your question definitions:&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
  alert(&#039;onload alert!&#039;);&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;It will display a pop-up message immediately after the page has been loaded.&lt;br /&gt;
&lt;br /&gt;
 Some of the applications of this trick I&#039;ve explored are:&lt;br /&gt;
&lt;br /&gt;
 a) Hiding the form elements by calling in your Custom_On_Load:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 b) Making the elements read only:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).readOnly=true;&amp;lt;/syntaxhighlight&amp;gt; where the &amp;quot;answer73166X16X54&amp;quot; structure has been described in one of other workarounds above.&lt;br /&gt;
&lt;br /&gt;
 c) For Hiding by a lot of elements by calling in your Customer_On_Load&lt;br /&gt;
&lt;br /&gt;
 jQuery searchs in html document for input-fields with radio type, if his answer text empty then do the display css set to none.&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;
 jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
            function() {&lt;br /&gt;
&lt;br /&gt;
              jQuery(&#039;input:radio&#039;).each(&lt;br /&gt;
&lt;br /&gt;
                function() {&lt;br /&gt;
&lt;br /&gt;
                  var s = jQuery(this);&lt;br /&gt;
&lt;br /&gt;
                  var c = s.parent().children(&#039;.answertext&#039;);&lt;br /&gt;
&lt;br /&gt;
                  for(var i=0; i &amp;lt; c.length; i++) {&lt;br /&gt;
&lt;br /&gt;
                    var a = jQuery(c[i]]);&lt;br /&gt;
&lt;br /&gt;
                    if(this.id &amp;lt;/u&amp;gt; a.attr(&#039;for&#039;) &amp;amp;&amp;amp; a.text() == &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
                      s.css({&#039;display&#039; : &#039;none&#039;});&lt;br /&gt;
&lt;br /&gt;
                      a.css({&#039;display&#039; : &#039;none&#039;});&lt;br /&gt;
&lt;br /&gt;
                      break;&lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                  }&lt;br /&gt;
&lt;br /&gt;
                }&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;
&lt;br /&gt;
 ==Custom onload function in multi-language survey==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 To use custom onload functions, as above, in multi-language surveys you must define the functions in the question source for &#039;&#039;&#039;all&#039;&#039;&#039; languages.&lt;br /&gt;
&lt;br /&gt;
 While this initially seems to be a bit tedious, it actually can be useful - you can alter your onload functions depending on the language in use. For example, you can dynamically display alerts or element contents in the current language.&lt;br /&gt;
&lt;br /&gt;
 ==Advanced way for (global) custom onload function:==&lt;br /&gt;
&lt;br /&gt;
 This way, you can get one or more global onload functions, which will load on every page of your survey.&lt;br /&gt;
&lt;br /&gt;
 Define a function in startpage.pstpl before the closing head tag, or in template.js.&lt;br /&gt;
&lt;br /&gt;
 For example the focusFirst workaround function:&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;
 function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
&lt;br /&gt;
    var i=0;&lt;br /&gt;
&lt;br /&gt;
    while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        i++;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
    return;&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 the &amp;quot;Event&amp;quot; Parameter is mandatory for functions added to an Event.&lt;br /&gt;
&lt;br /&gt;
 After defining the function which should be loaded, add this into the head tag of startpage.pstpl (or in template.js) :&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(ie)&lt;br /&gt;
&lt;br /&gt;
 {window.attachEvent(&amp;quot;onload&amp;quot;, functionName);}&lt;br /&gt;
&lt;br /&gt;
 else&lt;br /&gt;
&lt;br /&gt;
 {document.addEventListener(&amp;quot;load&amp;quot;, functionName, true);}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 var ie is set in startpage.pstpl to true (Internet Explorer) or false (other Browser than IE) with conditional comments. IE needs his own attachEvent.&lt;br /&gt;
&lt;br /&gt;
 EventListeners are supported from gecko and webkit Browsers (Firefox, Iceweasel, Safari, Chrome etc.)&lt;br /&gt;
&lt;br /&gt;
 ==Global custom onload function in multi-language surveys==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 Global custom onload functions can dynamically react to mid-survey language changes in multi-language surveys. This can be accomplished by using the value of the &amp;quot;languagechanger&amp;quot; element to control behavior of the onload function. It would be useful if you wanted to insert a language specific element or alerts on every question page of the survey. There is a small demo of this [http://www.partnersinc.biz/surveys//index.php?sid=77713&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 In the demo we placed the following code at the very end of &#039;&#039;&#039;&#039;&#039;endpage.pstpl&#039;&#039;&#039;&#039;&#039;. The function will be called whenever a page loads and then checks to see if the language switcher exists (indicating that this is a question page and not the intro or thanks pages) and, if so, inserts an element with language specific text. The code could be easily modified to handle images or alerts.&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
 // Don&#039;t do anything unless the document is fully loaded&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
    // Only continue if the language switcher is present on this page&lt;br /&gt;
&lt;br /&gt;
    if ( $(&#039;select.languagechanger&#039;).length &amp;gt; 0 ) {&lt;br /&gt;
&lt;br /&gt;
        // Check the value of the language switcher element to find the current language&lt;br /&gt;
&lt;br /&gt;
        var langChange = $(&#039;select.languagechanger&#039;).val();&lt;br /&gt;
&lt;br /&gt;
        var langArray = langChange.split(&#039;lang=&#039;);&lt;br /&gt;
&lt;br /&gt;
        var lang = langArray[1];&lt;br /&gt;
&lt;br /&gt;
        // Create some language specific text for the element that we&#039;ll insert below&lt;br /&gt;
&lt;br /&gt;
        var newElementText = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        switch(lang) {&lt;br /&gt;
&lt;br /&gt;
            case &#039;en&#039; :&lt;br /&gt;
&lt;br /&gt;
                newElementText = &#039;This element was inserted with a global onload function.&#039;;&lt;br /&gt;
&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case &#039;fr&#039; :&lt;br /&gt;
&lt;br /&gt;
                newElementText = &amp;quot;Cet &amp;amp;eacute;l&amp;amp;eacute;ment ...&amp;lt;br /&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case &#039;de-informal&#039; :&lt;br /&gt;
&lt;br /&gt;
                newElementText = &#039;Dieses Element ...&amp;lt;br /&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            default :&lt;br /&gt;
&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Insert a div element and fill it with the text above&lt;br /&gt;
&lt;br /&gt;
        var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
&lt;br /&gt;
        el.setAttribute(&#039;id&#039;,&#039;newElement&#039;);&lt;br /&gt;
&lt;br /&gt;
        document.body.appendChild(el);&lt;br /&gt;
&lt;br /&gt;
        $( &#039;#newElement&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
            &#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;width&#039;:&#039;50%&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;padding&#039;:&#039;5px&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;color&#039;:&#039;red&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;margin-bottom&#039;:&#039;10px&#039;&lt;br /&gt;
&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#newElement&#039;).html(newElementText);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;.boilerplate&#039;).after($(&#039;#newElement&#039;]];&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the function&lt;br /&gt;
&lt;br /&gt;
Custom_On_Load();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Skipping the welcome page==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (second code snippet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 1:&#039;&#039;&#039; Include this Javascript in your welcome template, file welcome.pstpl:&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.onload = custom_on_load();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will reproduce the onclick event of the submit button and submit the form.&lt;br /&gt;
&lt;br /&gt;
To assure that the function is called only after the whole page got loaded,&lt;br /&gt;
&lt;br /&gt;
the window.onload event is used.&lt;br /&gt;
&lt;br /&gt;
Drawback of course is that users will see the page flashing up.&lt;br /&gt;
&lt;br /&gt;
Therefore, you may want to announce &amp;quot;... loading survey ...&amp;quot; as a description of your welcome page (in the admin interface when creating the survey), to pretend loading something big.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 2:&#039;&#039;&#039;&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.setTimeout( &#039;custom_on_load()&#039;,1);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Extend the use of Attribute1/Attribute2 to an unlimited number of attributes==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Officially taken into the core at 1.85 (Tested with: 1.70)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;: This workaround is obsolute. Handling of additional tokens has been implemented in version 1.85. More information is available in the [http://docs.limesurvey.org/tiki-index.php?page=Tokens&amp;amp;structure;=English+Instructions+for+LimeSurvey#User_defined_attribute_fields manual].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User &#039;&#039;Schalburg&#039;&#039; created a javascript solution (based on release 1.70) to use more than the two standard attributes (Thanks for that!). The workaround is posted in the[http://bugs.limesurvey.org/view.php?id=1770 bug and feature tracker]. You&#039;ll find a detailled description there.&lt;br /&gt;
&lt;br /&gt;
==Filter answers of a question with the answer of another==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.70 - 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to filter the answer of a question with another answer, you can use this workaround.&lt;br /&gt;
&lt;br /&gt;
First, use answer code like that: XX for the first question, and XXYYY for the second one.&lt;br /&gt;
&lt;br /&gt;
Answer of the second question filter if the 2 first letters are the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
We use 1000X1X1 and 1000X1X2 for the example, question had to be on separate page (question by question for example).The second question had to be a dropdown list (we can do similar workaround, but droplis is the best)&lt;br /&gt;
&lt;br /&gt;
Use the Custom_onload function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
var answerFilter=&#039;{INSERTANS:1000X1X1}&#039; ;&lt;br /&gt;
&lt;br /&gt;
var tblQuestionToFilter=document.getElementById(&#039;answer1000X1X2&#039;).options ;&lt;br /&gt;
&lt;br /&gt;
var maxAnswer = tblQuestionToFilter.length;&lt;br /&gt;
&lt;br /&gt;
var counter=1;&lt;br /&gt;
&lt;br /&gt;
while (counter&amp;lt;=maxAnswer) {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (![[(tblQuestionToFilter[counter].value).substr(0,answerFilter.length)==answerFilter)||&lt;br /&gt;
&lt;br /&gt;
 (tblQuestionToFilter[counter].value==&amp;quot;-oth-&amp;quot;]])&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  tblQuestionToFilter[counter]=null ;&lt;br /&gt;
&lt;br /&gt;
  maxAnswer--;&lt;br /&gt;
&lt;br /&gt;
  counter--;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
counter++;&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;
&lt;br /&gt;
==Use an answer to prefill another answer (default value)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround give you the ablility to use an answer to fill the default value for another answer. It&#039;s explai for free text question type but can be adapted for another question type.&lt;br /&gt;
&lt;br /&gt;
We use SGQA identifier. For the exemple , we use SGQA 1000X10X20 and 1000X10X21 to prefill 1000X11X30 and 1000X11X31. For working, the question had to be on different page.&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;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dynamic Sum==&lt;br /&gt;
&lt;br /&gt;
This script is used with a &amp;quot;Multiple Options&amp;quot; type question calculate a total price based on how which checkboxes are selected. The prices are listed as part of the answer. The answers are set up like this: &amp;quot;USB Mouse ($20)&amp;quot;. The script uses the number between the &amp;quot;($&amp;quot; and the &amp;quot;)&amp;quot; as the price for that item. You can adapt the script to if you need to change the currency or need to sum something other than money.&lt;br /&gt;
&lt;br /&gt;
This script works when used in a question-by-question format.  It does not work when there are more than one question on a page. I think it can be adapted to work, but I haven&#039;t done the coding yet.&lt;br /&gt;
&lt;br /&gt;
Put the following code into body of your question:&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;script language=Javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// General definitions&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match the labels containing information about an answer&lt;br /&gt;
&lt;br /&gt;
// In LimeSurvey, these labels start with &amp;quot;answer...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
var answerRegex = /^answer/;&lt;br /&gt;
&lt;br /&gt;
// Find all answer checkboxes in the document and set their&lt;br /&gt;
&lt;br /&gt;
// onchange events to updatePrice&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // Find all input elements&lt;br /&gt;
&lt;br /&gt;
   var inputList=document.getElementsByTagName(&amp;quot;input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Loop through each, looking for checkboxes&lt;br /&gt;
&lt;br /&gt;
   var i;&lt;br /&gt;
&lt;br /&gt;
   for( i=0; i&amp;lt; inputList.length;i++ )&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // If input item does not have an ID, skip&lt;br /&gt;
&lt;br /&gt;
       if (! (inputList[i].id)) {continue;}&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if ID doesn&#039;t start with &amp;quot;answer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       if (!answerRegex.test(inputList[i].id)) {continue;}&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if not a checkbox&lt;br /&gt;
&lt;br /&gt;
       if (inputList[i].type.toUpperCase()!=&#039;CHECKBOX&#039;)  {continue;}&lt;br /&gt;
&lt;br /&gt;
       // This is an answer checkbox!&lt;br /&gt;
&lt;br /&gt;
       // Setup onchange event&lt;br /&gt;
&lt;br /&gt;
       inputList[i].onclick = updatePrice;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Load initial sum&lt;br /&gt;
&lt;br /&gt;
   updatePrice();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updatePrice()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
var labels=document.getElementsByTagName(&amp;quot;LABEL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match a price inside parenthesis&lt;br /&gt;
&lt;br /&gt;
// For example: ($29) or ($29.54).&lt;br /&gt;
&lt;br /&gt;
// Set up&lt;br /&gt;
&lt;br /&gt;
priceRegex = /\(\$(\d*\.{0,1}\d+)\)/;&lt;br /&gt;
&lt;br /&gt;
// Loop through all the labels, looking for labels corresponding to&lt;br /&gt;
&lt;br /&gt;
// answers that have a price in them.&lt;br /&gt;
&lt;br /&gt;
var i;&lt;br /&gt;
&lt;br /&gt;
var total = 0;&lt;br /&gt;
&lt;br /&gt;
for( i=0; i&amp;lt;labels.length;i++ )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   var myArray;    // Define array used for regex matching&lt;br /&gt;
&lt;br /&gt;
   var inputID;    // Define field element&lt;br /&gt;
&lt;br /&gt;
   // Get the ID of the field corresponding to the label using the&lt;br /&gt;
&lt;br /&gt;
   // &amp;quot;htmlFor&amp;quot; attribute&lt;br /&gt;
&lt;br /&gt;
   // (FYI, there are some labels that will have to be screened out&lt;br /&gt;
&lt;br /&gt;
   // because they don&#039;t correspond to an answer)&lt;br /&gt;
&lt;br /&gt;
   // Does the label start with &amp;quot;answer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
   // If not: exit.&lt;br /&gt;
&lt;br /&gt;
   if (!answerRegex.test(labels[i].htmlFor)) {continue;}&lt;br /&gt;
&lt;br /&gt;
   // First make sure this element exists&lt;br /&gt;
&lt;br /&gt;
   // If it doesn&#039;t, go to the next element&lt;br /&gt;
&lt;br /&gt;
   // If it does, it will be defined in inputID&lt;br /&gt;
&lt;br /&gt;
   if (! (inputID = document.getElementById(labels[i].htmlFor)) ) {continue;}&lt;br /&gt;
&lt;br /&gt;
   // See if the corresponding answer is a checkbox that is checked.&lt;br /&gt;
&lt;br /&gt;
   // If not, go to next label&lt;br /&gt;
&lt;br /&gt;
   if (inputID.type.toUpperCase()!=&#039;CHECKBOX&#039;)  {continue;}&lt;br /&gt;
&lt;br /&gt;
   if (!inputID.checked) {continue;}&lt;br /&gt;
&lt;br /&gt;
   // This is label for an answer.&lt;br /&gt;
&lt;br /&gt;
   // The innerHTML will give us the text of the label&lt;br /&gt;
&lt;br /&gt;
   // The price information will be in the form ($XX.XX)&lt;br /&gt;
&lt;br /&gt;
   // which in contained in the label text.&lt;br /&gt;
&lt;br /&gt;
   // Find a match for a decimal number inside the pattern &amp;quot;($&amp;quot; and &amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   if [[myArray = priceRegex.exec(labels[i].innerHTML]] != null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // Keep a running tally&lt;br /&gt;
&lt;br /&gt;
       total += parseFloat(myArray[1]);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // Update total price on form&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;totalPrice&amp;quot;).value = &amp;quot;$&amp;quot; + formatCurrency(total);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function formatCurrency(num) {&lt;br /&gt;
&lt;br /&gt;
  num = isNaN(num) || num &amp;lt;u&amp;gt; &#039;&#039; || num &amp;lt;/u&amp;gt; null ? 0.00 : num;&lt;br /&gt;
&lt;br /&gt;
  return parseFloat(num).toFixed(2);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the following code in the help section (or wherever you want the sum to appear):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Total Cost for selected accessories: &amp;lt;input type=&amp;quot;readonly&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;totalPrice&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Focus on the first Input field==&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: Limesurvey 1.80 / IE6/7, Firefox 3, Safari, Opera, chrome&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Again an onload Function is needed for this tasks. I have done it the DOM way with compatibility to IE6/7.&lt;br /&gt;
&lt;br /&gt;
Put the following code into the startpage.pstpl of your template, right before the &amp;lt;/head&amp;gt; closing tag:&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;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       var i=0;&lt;br /&gt;
&lt;br /&gt;
       while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           i++;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
       return;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(ie)&lt;br /&gt;
&lt;br /&gt;
   {window.attachEvent(&amp;quot;onload&amp;quot;, focusFirst);}&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {document.addEventListener(&amp;quot;load&amp;quot;, focusFirst, true);}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; I am using this with version 1.80. As changes happened to the templates in the last release, you might need to add the following before the code, if your template is older than 1.80 stable and does not include this:&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;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   var ie = false;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will need this for the var ie to be set. Without this var, the function will not work with ie.&lt;br /&gt;
&lt;br /&gt;
==Answer questions by keypress==&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: IE7, Firefox 3&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This workaround allow to answer the question on key 0-9 (0 is for the 10 answer).&lt;br /&gt;
&lt;br /&gt;
Follow issues are supported at the moment:&lt;br /&gt;
*Yes-No Questions&lt;br /&gt;
*List Questions (radio)&lt;br /&gt;
*other radio questions&lt;br /&gt;
&lt;br /&gt;
In lists the answer limit is ten.&lt;br /&gt;
&lt;br /&gt;
You supply the template &amp;quot;endpage&amp;quot; of your template with the following script.&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;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   jQuery(document).bind(&#039;keypress&#039;, function(e){&lt;br /&gt;
&lt;br /&gt;
       if (48 &amp;lt;= e.which &amp;amp;&amp;amp; e.which &amp;lt;= 57) {&lt;br /&gt;
&lt;br /&gt;
           jQuery(&#039;input:radio&#039;).each(function() {&lt;br /&gt;
&lt;br /&gt;
               var v = jQuery(this).val();&lt;br /&gt;
&lt;br /&gt;
               var c = (e.which &amp;lt;u&amp;gt; 48) ? 10 : e.which - 48;&lt;br /&gt;
&lt;br /&gt;
               if(v &amp;lt;/u&amp;gt; &#039;Y&#039; || v &amp;lt;u&amp;gt; &#039;N&#039;) {&lt;br /&gt;
&lt;br /&gt;
                   v = (v &amp;lt;/u&amp;gt; &#039;Y&#039;) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               if(v == c) {&lt;br /&gt;
&lt;br /&gt;
                   jQuery(this).click();&lt;br /&gt;
&lt;br /&gt;
                   jQuery(&#039;#limesurvey input:submit&#039;).click();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&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;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Math notation in LimeSurvey==&lt;br /&gt;
#download the js file from [http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html AsciiMath script]&lt;br /&gt;
#copy it in the /scripts/ folder in your installation&lt;br /&gt;
#modify the startpage.psptl of the template you want to use adding the reference to the script (if you use an older version make sure that you copy the template folder first!) for 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ASCIIMathML.js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the notation where you need it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you use internet explorer or safari you will need to download the plugin as well, but firefox does the lot for you.&lt;br /&gt;
&lt;br /&gt;
Finally, if you are confident with the limesurvey structure you could add the editor which support math notation and change the reference to the editor you want to use in the configuration file. here is the [http://www.imathas.com/editordemo/demo.html link for a TinyMCE with math support].&lt;br /&gt;
&lt;br /&gt;
==Reverse array_filter==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used to filter the answers of an array question to be displayed based on the answers of a multi option question that were &#039;&#039;&#039;NOT&#039;&#039;&#039; selected. A possible application would be to have a multi-option question asking which products were purchased, followed by 2 array questions - one asking to rate the purchased products and another asking why the remaining products were not purchased. Another would be to ask about sessions attended at a conference as in [http://www.limesurvey.org/en/support/forums/5-can-i-do-this-with-limesurvey/27970-reverse-of-arrayfilter.html this forum thread] and pictured below. There is a live [http://www.partnersinc.biz/surveys//index.php?sid=43358&amp;amp;newtest;=Y&amp;amp;lang;=en demo here]&lt;br /&gt;
&lt;br /&gt;
[[File:sessions_645x344.gif]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll use the above example to explain the process as follows:&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsAttended&#039;&#039; multi-options question&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsNotAttended&#039;&#039; multi-options question with identical answers as &#039;&#039;SessionsAttended&#039;&#039; and hide it with styles or conditions&lt;br /&gt;
#In group 2 - Create a &#039;&#039;RateSessionsAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsAttended&#039;&#039;&lt;br /&gt;
#In group 2 - Create a &#039;&#039;ReasonNotAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsNotAttended&#039;&#039;&lt;br /&gt;
#In group 1 - Place JavaScript/jQeury listeners on each of the checkboxes in &#039;&#039;SessionsAttended&#039;&#039; that would toggle the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
&lt;br /&gt;
The JavaScript/jQuery code used would be:&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;
       // The toggle function&lt;br /&gt;
&lt;br /&gt;
   function toggle(q1, q2) {&lt;br /&gt;
&lt;br /&gt;
       if ($(q1).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Initialize the SessionNotAttended checkboxes to &amp;quot;checked&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   // The jQuery listeners on the SessionAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   // that toggle the SessionNotAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X331&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X332&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X333&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X334&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The code is in an onload function defined in the first question of group 1 - see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workarounds here]&lt;br /&gt;
*Both &#039;&#039;SessionsAttended&#039;&#039; and &#039;&#039;SessionsNotAttended&#039;&#039; must be in the same group for the toggling to work&lt;br /&gt;
*This case only uses 4 checkboxes but could be expanded as required&lt;br /&gt;
*In this case the survey ID is 11111, the group ID is 22, &#039;&#039;SessionsAttended&#039;&#039; ID is 33 and SessionsNotAttended ID is 44 - these would need to be modified for your survey&lt;br /&gt;
*The toggle function looks for the state of a checkbox in &#039;&#039;SessionsAttended&#039;&#039; and sets the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
*The &amp;quot;Initialize&amp;quot; section sets the state of &#039;&#039;SessionsNotAttended&#039;&#039; checkboxes whenever we navigate to the group&lt;br /&gt;
*The &amp;quot;Listener&amp;quot; section uses jQuery listeners to detect any change in the &#039;&#039;SessionsAttended&#039;&#039; checkboxes and then toggle the corresponding &#039;&#039;SessionsNotAttended&#039;&#039; checkbox&lt;br /&gt;
&lt;br /&gt;
Some general notes about the questions:&lt;br /&gt;
*CSS can be used to hide &#039;&#039;SessionsNotAttended&#039;&#039; (div#question44 {display: none;}) if you don&#039;t want to use conditions (because maybe you&#039;ve got [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Survey_Behavior $deletenonvalues set to 1])&lt;br /&gt;
*&#039;&#039;RateSessionsAttended&#039;&#039; and &#039;&#039;ReasonNotAttended&#039;&#039; are another group to avoid things popping in and out of existence as &#039;&#039;SessionsAttended&#039;&#039; is answered&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure;=English+Instructions+for+LimeSurvey Conditions] are used to ensure that &#039;&#039;RateSessionsAttended&#039;&#039; only appears if some sessions are selected and &#039;&#039;ReasonNotAttended&#039;&#039; only appears if no sessions are selected&lt;br /&gt;
&lt;br /&gt;
==Auto-tabbing between text input fields==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a workaround to facilitate auto-tabbing between text input questions in a single group using a [http://plugins.jquery.com/project/autotab jQuery plugin by Mathachew] and the Maximum characters attribute of questions.&lt;br /&gt;
&lt;br /&gt;
The behaviour will be: When the maximum number of characters has been entered into an input field, the focus (cursor) will be automatically moved to the next input field. When the backspace key is used to remove all characters from a field, the focus will be moved to the previous field. It&#039;s very useful in surveys having many text input questions to avoid having to manually tab or click between fields.&lt;br /&gt;
&lt;br /&gt;
You can view a small demo survey [http://www.partnersinc.biz/surveys//index.php?sid=11327&amp;amp;newtest;=Y&amp;amp;lang;=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Visit [http://plugins.jquery.com/node/4046 http://plugins.jquery.com/node/4046], download the plugin script and save it as &#039;&#039;jquery.autotab-1.1b.js&#039;&#039; in the template folder.&lt;br /&gt;
#Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autotab-1.1b.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
#Create the text based questions that auto-tabbing is to be applied to. (All must be in the same group if you&#039;re using group by group presentation)&lt;br /&gt;
#Define a Maximum characters attribute for all questions that the autotab is applied to. (See [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#maximum_chars documentation here])&lt;br /&gt;
#In the first question of the group that contains the auto-tabbed questions, add the following code. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]) Note: I prefer to use a boilerplate question for this and hide it with CSS - this prevents the JavaScript from appearing in error alerts etc.&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answerSSSSSXGGXAA&#039;).focus(); //initially focus on the first input&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answerSSSSSXGGXAA&#039;).autotab({ target: &#039;answerSSSSSXGGXBB&#039; });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answerSSSSSXGGXBB&#039;).autotab({ previous: &#039;answerSSSSSXGGXAA&#039;, target: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answerSSSSSXGGXCC&#039;).autotab({ previous: &#039;answerSSSSSXGGXBB&#039;, target: &#039;answerSSSSSXGGXDD&#039; });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answerSSSSSXGGXDD&#039;).autotab({ previous: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example has 4 fields to be auto-tabbed between - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
*SSSSS -&amp;gt; Survey ID&lt;br /&gt;
*GG -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Last question&lt;br /&gt;
&lt;br /&gt;
[[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;target&#039;&#039; parameter defines where the next input is and the &#039;&#039;previous&#039;&#039; parameter defines (you guessed it) the previous input.&lt;br /&gt;
&lt;br /&gt;
This plugin also has limited capability of formatting the input text - see comments in the plugin script.&lt;br /&gt;
&lt;br /&gt;
==Custom response listeners==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Listeners can be used to perform functions when a change in an input is detected. There are many uses such as the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds#Reverse_array_filter Reverse array_filter] but a simple one would be to warn a respondent if they enter a value that may be too high.&lt;br /&gt;
&lt;br /&gt;
We can use the [http://docs.jquery.com/Events/change jQuery change( ) event] to fire a function whenever there is a change to the input. The function will look for an input value higher than 10 and, if found, will warn the respondent.&lt;br /&gt;
&lt;br /&gt;
Place the following code in your [http://docs.limesurvey.org/tiki-index.php?page=Workarounds#Custom_onload_function Custom onload function]:&lt;br /&gt;
&lt;br /&gt;
Onload 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;
$(&#039;#answer11111X22X33&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
   if ( $(&#039;#answer11111X22X33&#039;).val() &amp;gt; 10 ) {&lt;br /&gt;
&lt;br /&gt;
       alert (&amp;quot;That&#039;s an awful lot. Are you sure?&amp;quot;);&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;
&lt;br /&gt;
Where:&lt;br /&gt;
*11111 is the survey ID&lt;br /&gt;
*22 is the group ID&lt;br /&gt;
*33 is the question ID&lt;br /&gt;
&lt;br /&gt;
==Text input masks==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number [[###) ###-####) or a Canadian postal code (A1A 1A1) The [http://plugins.jquery.com/project/meioMask|jQuery meioMask plugin by fabiomcosta] can be used to do this.&lt;br /&gt;
&lt;br /&gt;
 The plugin has several pre-defined masks and supports custom masks. It also allows for pasting of input, allows default values and can auto-focus the next form element when the current input is completely filled. See [http://www.meiocodigo.com/projects/meiomask/|http://www.meiocodigo.com/projects/meiomask/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
 You can view a small demo survey of masks in use [http://www.partnersinc.biz/surveys//index.php?sid=36146&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 Implementation for this demo was as follows:&lt;br /&gt;
&lt;br /&gt;
 #Visit [http://www.meiocodigo.com/projects/meiomask/|http://www.meiocodigo.com/projects/meiomask/], download the latest plugin script and save it as &#039;&#039;jquery.meiomask.js&#039;&#039; in the template folder.&lt;br /&gt;
&lt;br /&gt;
 #Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.meiomask.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
&lt;br /&gt;
 #Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects|documentation here])&lt;br /&gt;
&lt;br /&gt;
 #Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function|workaround here])&lt;br /&gt;
&lt;br /&gt;
 #Create the text input questions that the masks are to be applied to&lt;br /&gt;
&lt;br /&gt;
 #In the first question of the group that contains the masked inputs, add the following code. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._|How to use script here]) Note: I prefer to use a boilerplate question for this and hide it with CSS - this prevents the JavaScript from appearing in error alerts etc.&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
    // Define custom masks&lt;br /&gt;
&lt;br /&gt;
    $.mask.masks = $.extend($.mask.masks,{&lt;br /&gt;
&lt;br /&gt;
        customMask1:{ mask: &#039;a9a 9a9&#039; }, // Canadian postal code&lt;br /&gt;
&lt;br /&gt;
        // Maximum input of 9,999.99, reverse input, default value of 0.00&lt;br /&gt;
&lt;br /&gt;
        customMask2:{mask: &#039;99.999,9&#039;, type : &#039;reverse&#039;, defaultValue : &#039;000&#039;}&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Set the &#039;alt&#039; attributes of the inputs&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#answer111111X22XAA&#039;).attr(&#039;alt&#039;, &#039;phone-us&#039;); // a pre-defined mask&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#answer111111X22XBB&#039;).attr(&#039;alt&#039;, &#039;customMask1&#039;); // a custom mask&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#answer111111X22XCC&#039;).attr(&#039;alt&#039;, &#039;customMask2&#039;); // a custom mask&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#answer111111X22XDD&#039;).attr(&#039;alt&#039;, &#039;cc&#039;); // a pre-defined mask for credit card&lt;br /&gt;
&lt;br /&gt;
    // Tell the plugin to apply masks to these inputs&lt;br /&gt;
&lt;br /&gt;
    $(&#039;input:answer111111X22XAA&#039;).setMask();&lt;br /&gt;
&lt;br /&gt;
    $(&#039;input:answer111111X22XBB&#039;).setMask();&lt;br /&gt;
&lt;br /&gt;
    $(&#039;input:answer111111X22XCC&#039;).setMask();&lt;br /&gt;
&lt;br /&gt;
    $(&#039;input:answer111111X22XDD&#039;).setMask();&lt;br /&gt;
&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 The first section defines two custom masks to be used - one for Canadian postal code with a format of A#A #A# and a second for a maximum amount of 9999.99 with reverse input (useful for cost inputs) and a default value of 0.00.&lt;br /&gt;
&lt;br /&gt;
 The next section sets the &amp;quot;alt&amp;quot; attributes for the text inputs. This will tell meioMask which mask we will be applying to each input. By default meioMask looks at the alt attribute to find which mask to apply however this can be changed using the [http://www.meiocodigo.com/projects/meiomask/#mm_options|mask options].&lt;br /&gt;
&lt;br /&gt;
 In the final section we apply the masks to the inputs.&lt;br /&gt;
&lt;br /&gt;
 This example has 4 inputs with masks on them - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
&lt;br /&gt;
 *11111 -&amp;gt; Survey ID&lt;br /&gt;
&lt;br /&gt;
 *22 -&amp;gt; Group ID&lt;br /&gt;
&lt;br /&gt;
 *AA -&amp;gt; First question&lt;br /&gt;
&lt;br /&gt;
 *BB -&amp;gt; Second question&lt;br /&gt;
&lt;br /&gt;
 *CC -&amp;gt; Third question&lt;br /&gt;
&lt;br /&gt;
 *DD -&amp;gt; Fourth question&lt;br /&gt;
&lt;br /&gt;
 [[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
 Oops, found a &#039;&#039;possible bug in IE6:&#039;&#039; You may need to paste the contents of jquery.meiomask.js into the very beginning of your custom onload function (before the document.ready function).&lt;br /&gt;
&lt;br /&gt;
 ==Select a random response to a &amp;quot;Multiple options&amp;quot; question for later use==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 This workaround allows you to randomly select one of the checked boxes in a &amp;quot;Multiple options&amp;quot; question and store it&#039;s label for later use in the survey. A possible use would be to have a question asking what products were purchased and then randomly selecting one of the products to ask further questions about.&lt;br /&gt;
&lt;br /&gt;
 There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=81252&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 Basically what we&#039;ve done here is to put listeners on all of the checkboxes. If a change of state is detected in any of them the &amp;quot;randomResponse&amp;quot; function is called which loops through all of the checkboxes and if it finds a checked state, that box&#039;s label is added to an array. Then a random item is pulled from the array and used to populate the hidden question. This hidden question can then be drawn upon later in the survey using [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers|INSERTANS] or [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure;=English+Instructions+for+LimeSurvey|Conditions].&lt;br /&gt;
&lt;br /&gt;
 Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
 #Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects|documentation here])&lt;br /&gt;
&lt;br /&gt;
 #Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function|workaround here])&lt;br /&gt;
&lt;br /&gt;
 #Create a &amp;quot;Multiple options&amp;quot; question that we&#039;re going to randomly pick a checked box from&lt;br /&gt;
&lt;br /&gt;
 #Create a text input question to store the label of the checked box in (we&#039;re going to hide this with JavaScript)&lt;br /&gt;
&lt;br /&gt;
 #In the first question of the group that contains the &amp;quot;Multiple options&amp;quot; question, add the following code. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._|How to use script here]) Note: I prefer to use a boilerplate question for this and hide it with CSS - this prevents the JavaScript from appearing in error alerts etc.&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
    //// Identify the hidden question input&lt;br /&gt;
&lt;br /&gt;
    //// EDIT HERE (1) - replace with your hidden question input ID&lt;br /&gt;
&lt;br /&gt;
    var hiddenInput = &#039;#answer11111X22X44&#039;;&lt;br /&gt;
&lt;br /&gt;
    //// Make the &amp;quot;hidden&amp;quot; question disappear&lt;br /&gt;
&lt;br /&gt;
    //// EDIT HERE (2) - replace with your hidden question ID&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#question44&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
    //// Identify the checkboxes to be randomized&lt;br /&gt;
&lt;br /&gt;
    //// EDIT HERE (3) - add or remove as required,&lt;br /&gt;
&lt;br /&gt;
    //// replace with your checkbox IDs&lt;br /&gt;
&lt;br /&gt;
    var CB1 = &#039;#answer11111X22X33A&#039;;&lt;br /&gt;
&lt;br /&gt;
    var CB2 = &#039;#answer11111X22X33B&#039;;&lt;br /&gt;
&lt;br /&gt;
    var CB3 = &#039;#answer11111X22X33C&#039;;&lt;br /&gt;
&lt;br /&gt;
    var CB4 = &#039;#answer11111X22X33D&#039;;&lt;br /&gt;
&lt;br /&gt;
    var CB5 = &#039;#answer11111X22X33E&#039;;&lt;br /&gt;
&lt;br /&gt;
    var CB6 = &#039;#answer11111X22X33F&#039;;&lt;br /&gt;
&lt;br /&gt;
    //// Create an array of all checkboxes to be randomized&lt;br /&gt;
&lt;br /&gt;
    //// EDIT HERE (4) - add or remove CBs as required&lt;br /&gt;
&lt;br /&gt;
    checkBoxes = new Array( CB1, CB2, CB3, CB4, CB5, CB6 );&lt;br /&gt;
&lt;br /&gt;
    var checkBoxesLength = checkBoxes.length;&lt;br /&gt;
&lt;br /&gt;
    //// The randomizing function - no editing required&lt;br /&gt;
&lt;br /&gt;
    function randomResponse () {&lt;br /&gt;
&lt;br /&gt;
        var boxLabels = new Array();&lt;br /&gt;
&lt;br /&gt;
        // loop through all of the checkboxes and if they are checked,&lt;br /&gt;
&lt;br /&gt;
        // add their label to the boxLabels array&lt;br /&gt;
&lt;br /&gt;
        for( var i=0; i&amp;lt;checkBoxesLength; i++ ) {&lt;br /&gt;
&lt;br /&gt;
            if ( $(checkBoxes[i]).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
&lt;br /&gt;
                var cbid = checkBoxes[i].replace(&#039;#&#039;,&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
                boxLabels.push( $( &#039;label[for=&#039; + cbid + &#039;]&#039; ).html() );&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // find a random index of the responses array&lt;br /&gt;
&lt;br /&gt;
        var randomNum = Math.floor(Math.random() * boxLabels.length);&lt;br /&gt;
&lt;br /&gt;
        // populate the hidden question input with the&lt;br /&gt;
&lt;br /&gt;
        // random input value&lt;br /&gt;
&lt;br /&gt;
        $(hiddenInput).val( boxLabels[randomNum] );&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //// The listeners that will fire the randomize function if a&lt;br /&gt;
&lt;br /&gt;
    //// change occurs in the checkboxes&lt;br /&gt;
&lt;br /&gt;
    //// EDIT HERE (5) - add or remove CBs as required&lt;br /&gt;
&lt;br /&gt;
    $(CB1).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    $(CB2).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    $(CB3).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    $(CB4).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    $(CB5).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    $(CB6).change(function() {&lt;br /&gt;
&lt;br /&gt;
        randomResponse ();&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;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
 *EDIT HERE (1) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 44 -&amp;gt; hidden question ID.&lt;br /&gt;
&lt;br /&gt;
 *EDIT HERE (2) - 44 -&amp;gt; hidden question ID.&lt;br /&gt;
&lt;br /&gt;
 *EDIT HERE (3) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 33 -&amp;gt; multiple option question ID, A/B/C/D/E/F -&amp;gt; multiple option answer codes. Also add or remove CBs for more or less checkboxes.&lt;br /&gt;
&lt;br /&gt;
 *EDIT HERE (4) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
&lt;br /&gt;
 *EDIT HERE (5) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
&lt;br /&gt;
 For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey|SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
 ==Display secondary options in a &amp;quot;Multiple options&amp;quot; question==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 This workaround allows you to display secondary options in a &amp;quot;Multiple options&amp;quot; question if a primary option is checked as in the images below.&lt;br /&gt;
&lt;br /&gt;
 Primary option not selected:&lt;br /&gt;
&lt;br /&gt;
 [[File:secondary_options_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
 Primary option selected:&lt;br /&gt;
&lt;br /&gt;
 [[File:secondary_options_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
 There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=11491&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 We&#039;ve put a listener on the primary answer (&amp;quot;Option 1&amp;quot; in the demo) that shows or hides the secondary answers depending on the state of the primary.&lt;br /&gt;
&lt;br /&gt;
 Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
 #Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects|documentation here])&lt;br /&gt;
&lt;br /&gt;
 #Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function|workaround here])&lt;br /&gt;
&lt;br /&gt;
 #Create a &amp;quot;Multiple options&amp;quot; question including both the primary and secondary answers (in the order that you would like them displayed if all shown)&lt;br /&gt;
&lt;br /&gt;
 #Add the following JavaScript to the onload function for that group (page). (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._|How to use script here])&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
        /****&lt;br /&gt;
&lt;br /&gt;
        The following code puts a listener on an answer in a multiple options&lt;br /&gt;
&lt;br /&gt;
        question (the primary answer) and if that answer is checked, a secondary&lt;br /&gt;
&lt;br /&gt;
        level of answers is displayed.&lt;br /&gt;
&lt;br /&gt;
        ****/&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;strike&amp;gt;- 1 &amp;lt;/strike&amp;gt;- Indent the secondary answers a bit&lt;br /&gt;
&lt;br /&gt;
        $( &#039;#questionQQ li:eq(1)&#039; ).css({&#039;margin-left&#039;:&#039;2.5em&#039;});&lt;br /&gt;
&lt;br /&gt;
        $( &#039;#questionQQ li:eq(2)&#039; ).css({&#039;margin-left&#039;:&#039;2.5em&#039;});&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;strike&amp;gt;- 2 &amp;lt;/strike&amp;gt;- When the page loads, see if the primary answer is checked and if not,&lt;br /&gt;
&lt;br /&gt;
                //hide and un-check all secondary answers&lt;br /&gt;
&lt;br /&gt;
        if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
            $( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
            $( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
            $( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
            $( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;strike&amp;gt;- 3 &amp;lt;/strike&amp;gt;- Now put a listener on the primary answer to show or hide secondary answers&lt;br /&gt;
&lt;br /&gt;
        // We need to use .click instead of .change cause IE won&#039;t cooperate&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#answerSSSSSXGGXQQAA&#039;).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
            // Have a look at the primary answer and hide/show the secondary answers accordingly&lt;br /&gt;
&lt;br /&gt;
            if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            else {&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#questionQQ li:eq(1)&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
                $( &#039;#questionQQ li:eq(2)&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // The original functions of the click event&lt;br /&gt;
&lt;br /&gt;
            cancelBubbleThis(event);&lt;br /&gt;
&lt;br /&gt;
            checkconditions(this.value, this.name, this.type);&lt;br /&gt;
&lt;br /&gt;
          }&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;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&#039;&#039;The following edits are required to implement this in your survey:&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Section 1:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 *This section indents the secondary answers to give the look of a list in a list when they&#039;re shown&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; are the index positions of your secondary options. Modify or add as necessary for the number and placement of secondary options in your question. Note that the index starts at 0 so &#039;&#039;&#039;eq(1)&#039;&#039;&#039; actually affects the second option in the full list and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; affects the third.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Section 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 *This section checks the state of the primary question when the page is loaded and if necessary hides the secondary questions. We need this in case users navigate away from and then back to the page.&lt;br /&gt;
&lt;br /&gt;
 *Modify &#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; as above.&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;SSSSS&#039;&#039;&#039; is your survey ID.&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;GG&#039;&#039;&#039; is your group ID.&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID.&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;AA&#039;&#039;&#039; is your primary answer code.&lt;br /&gt;
&lt;br /&gt;
 *&#039;&#039;&#039;BB&#039;&#039;&#039; and &#039;&#039;&#039;CC&#039;&#039;&#039; are your secondary answer codes (add as necessary).&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Section 3:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 *This is the section that &amp;quot;listens&amp;quot; to the primary answer and reacts accordingly.&lt;br /&gt;
&lt;br /&gt;
 *Edit as in section 2.&lt;br /&gt;
&lt;br /&gt;
 For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey|SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
 This code could be tidied up and shortened a bit but I left it this way to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
 == Generate random number to control survey behaviour==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 This workaround allows you to generate a random number and then populate a hidden question with that number. You can then use this question to control the display of subsequent questions with [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure;=English+Instructions+for+LimeSurvey|Conditions]. It&#039;s useful if you have several sets of questions that you would like to randomly present to participants - see this  [http://www.limesurvey.org/en/support/forums/5-can-i-do-this-with-limesurvey/29579-experiment-with-random-questions.html|forum post].&lt;br /&gt;
&lt;br /&gt;
 There is a small demo [http://www.partnersinc.biz/surveys//index.php?sid=12659&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 In the demo, in the first group, we generate a random number between 1 and 4 and populate a hidden question with it. Then in the second group we have 4 questions, each showing conditional on the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
 Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
 #Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects|documentation here])&lt;br /&gt;
&lt;br /&gt;
 #Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function|workaround here])&lt;br /&gt;
&lt;br /&gt;
 #In the first group add a &amp;quot;Short free text&amp;quot; question (We&#039;re going to hide this with JavaScript)&lt;br /&gt;
&lt;br /&gt;
 #In the source of that question add the following onload function. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._|How to use script here])&lt;br /&gt;
&lt;br /&gt;
 #In the following groups add the questions that are conditional on the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
        // Find a random number between 1 and 4&lt;br /&gt;
&lt;br /&gt;
        var randNumber = Math.floor(Math.random()*4 + 1);&lt;br /&gt;
&lt;br /&gt;
        // Populate and hide the hidden question&lt;br /&gt;
&lt;br /&gt;
        $(&#039;input#answerSSSSSXGGXQQ&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#questionQQ&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
        /***********************************************************/&lt;br /&gt;
&lt;br /&gt;
        // This just tells the user which number has been selected&lt;br /&gt;
&lt;br /&gt;
        // You can remove this from your onload function&lt;br /&gt;
&lt;br /&gt;
        $(&#039;input#setNumber&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;input#setNumber&#039;).css({&lt;br /&gt;
&lt;br /&gt;
            &#039;margin-left&#039;:&#039;0.5em&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;width&#039;:&#039;1.5em&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
&lt;br /&gt;
            &#039;font-weight&#039;:&#039;bold&#039;&lt;br /&gt;
&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(&#039;input#setNumber&#039;).attr(&#039;disabled&#039;, true);&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;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Where &#039;&#039;&#039;SSSSS&#039;&#039;&#039; is the survey ID, &#039;&#039;&#039;GG&#039;&#039;&#039; is the group ID and &#039;&#039;&#039;QQ&#039;&#039;&#039; is the hidden question ID.&lt;br /&gt;
&lt;br /&gt;
 Increase or decrease the maximum value of the random number by modifying the first section. For example to get a number between 1 and 10 you would use this:&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;
 var randNumber = Math.floor(Math.random()*10 + 1);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 The third section of code just populates a placeholder element that I use to tell the participant what&#039;s going on. You can remove it from your code.&lt;br /&gt;
&lt;br /&gt;
 == Minimum number of required answers in an array==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 This workaround allows you to specify a &#039;&#039;&#039;minimum number&#039;&#039;&#039; of answers required in an array question. It is an alternative to the &amp;quot;Mandatory&amp;quot; parameter which specifies that &#039;&#039;&#039;all&#039;&#039;&#039; answers are required. It could also be easily modified to specify a maximum number of answers.&lt;br /&gt;
&lt;br /&gt;
 We accomplish this by placing an onload function in the source of the array question. This function hides the Next/Submit button and displays a warning element until it detects a minimum number of responses. It then hides the warning and shows the Next/Submit button.&lt;br /&gt;
&lt;br /&gt;
 There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=97166&amp;amp;newtest;=Y&amp;amp;lang;=en|here].&lt;br /&gt;
&lt;br /&gt;
 Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
 #Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects|documentation here])&lt;br /&gt;
&lt;br /&gt;
 #Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function|workaround here])&lt;br /&gt;
&lt;br /&gt;
 #In the source of the array question add the following onload function. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._|How to use script here])&lt;br /&gt;
&lt;br /&gt;
 #Modify the &#039;&#039;SETTINGS&#039;&#039; section of the code as required.&lt;br /&gt;
&lt;br /&gt;
 Onload 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;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
        // Wait until the document is fully loaded&lt;br /&gt;
&lt;br /&gt;
        $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
            /********************** SETTINGS **********************/&lt;br /&gt;
&lt;br /&gt;
            // The text to appear in the warning element&lt;br /&gt;
&lt;br /&gt;
            var warningText = &#039;Please answer at least 4 to continue&#039;;&lt;br /&gt;
&lt;br /&gt;
            // The question ID&lt;br /&gt;
&lt;br /&gt;
            var questionId = 137;&lt;br /&gt;
&lt;br /&gt;
            // The minimum number of answers required&lt;br /&gt;
&lt;br /&gt;
            var minNumber = 4;&lt;br /&gt;
&lt;br /&gt;
            /******************************************************/&lt;br /&gt;
&lt;br /&gt;
            // Create the warning element and place it after the submit button&lt;br /&gt;
&lt;br /&gt;
            var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
&lt;br /&gt;
            el.setAttribute(&#039;id&#039;,&#039;warning&#039;);&lt;br /&gt;
&lt;br /&gt;
            document.body.appendChild(el);&lt;br /&gt;
&lt;br /&gt;
            $( &#039;#warning&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
                &#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
&lt;br /&gt;
                &#039;width&#039;:&#039;200px&#039;,&lt;br /&gt;
&lt;br /&gt;
                &#039;padding&#039;:&#039;3px&#039;,&lt;br /&gt;
&lt;br /&gt;
                &#039;color&#039;:&#039;red&#039;&lt;br /&gt;
&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $(&#039;#warning&#039;).html(warningText);&lt;br /&gt;
&lt;br /&gt;
            $(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).after($(&#039;#warning&#039;]];&lt;br /&gt;
&lt;br /&gt;
           // Detect the initial number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
&lt;br /&gt;
           var inputInitCount = 0;&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
&lt;br /&gt;
                   inputInitCount++;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           if (inputInitCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
&lt;br /&gt;
               $(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#warning&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           else {&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#warning&#039;).show();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Listener to detect number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + questionId + &#039; input&#039;).click(function() {&lt;br /&gt;
&lt;br /&gt;
               var inputCount = 0;&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                   if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
&lt;br /&gt;
                       inputCount++;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
               if (inputCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#warning&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#warning&#039;).show();&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               // The original functions of the click event&lt;br /&gt;
&lt;br /&gt;
               checkconditions(this.value, this.name, this.type);&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;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Variable Length Array (Multi Flexible Text) question==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows a respondent to add or remove rows of an Array (Multi Flexible Text) question. It&#039;s useful to avoid the page being cluttered with unnecessary array rows.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of the array question. This function hides all of the array rows except the first and inserts two elements that when clicked show or hide rows accordingly.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=53132&amp;amp;newtest;=Y&amp;amp;lang;=en here].&lt;br /&gt;
&lt;br /&gt;
It must be noted that you can not make this question Mandatory as the respondent will have no way to complete hidden fields. If you want the displayed fields to be mandatory you will need to validate them in another function or modify this function to only allow the addition of rows if all fields in the last row are completed and then disable those fields - that, however, is a little over the top for this example.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
#Create one or more Array (Multi Flexible Text) questions&lt;br /&gt;
#In the source of the first array question add the following onload function. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here])&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end with the question ID.&lt;br /&gt;
#If you want to apply it to more arrays on the same page simply add more calls with the appropriate question IDs. (eg. varLengthArray(1); varLengthArray(2);...)&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
// A function to add or remove rows of an Array (Multi Flexible)(Text) question&lt;br /&gt;
&lt;br /&gt;
function varLengthArray(qID) {&lt;br /&gt;
&lt;br /&gt;
   // The HTML content of the Add/Remove elements - modify as you wish&lt;br /&gt;
&lt;br /&gt;
   var addContent = &#039;[+]&#039;;&lt;br /&gt;
&lt;br /&gt;
   var removeContent = &#039;[-]&#039;;&lt;br /&gt;
&lt;br /&gt;
   // Just some initialization stuff&lt;br /&gt;
&lt;br /&gt;
   var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody tr&#039;;&lt;br /&gt;
&lt;br /&gt;
   var rowCount = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
   // Initially hide all except first row&lt;br /&gt;
&lt;br /&gt;
   $( arrayRow ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
       if ( i &amp;gt; 0 ) {&lt;br /&gt;
&lt;br /&gt;
           // We also need to give the hidden rows a name cause IE doesn&#039;t&lt;br /&gt;
&lt;br /&gt;
           // recognize jQuery :visible selector consistently&lt;br /&gt;
&lt;br /&gt;
           $( this ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
           rowCount = i;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Create the Add and Remove elements &amp;amp; insert them&lt;br /&gt;
&lt;br /&gt;
   var el1 = document.createElement(&#039;div&#039;);&lt;br /&gt;
&lt;br /&gt;
   el1.setAttribute(&#039;id&#039;,&#039;addButton&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el1);&lt;br /&gt;
&lt;br /&gt;
   var el2 = document.createElement(&#039;div&#039;);&lt;br /&gt;
&lt;br /&gt;
   el2.setAttribute(&#039;id&#039;,&#039;removeButton&#039;);&lt;br /&gt;
&lt;br /&gt;
   document.body.appendChild(el2);&lt;br /&gt;
&lt;br /&gt;
   // Move them to after the array&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#addButton&#039; ).appendTo($( &#039;#question&#039; + qID + &#039; td.answer&#039; ));&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#removeButton&#039; ).appendTo($( &#039;#question&#039; + qID + &#039; td.answer&#039; ));&lt;br /&gt;
&lt;br /&gt;
   // Insert their HTML&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#addButton&#039; ).html( addContent );&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#removeButton&#039; ).html( removeContent );&lt;br /&gt;
&lt;br /&gt;
   // Style the elements - you can modify here if you wish&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#addButton&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
       &#039;margin&#039;:&#039;-10px 0 0 10px&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;float&#039;:&#039;left&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#removeButton&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
       &#039;margin&#039;:&#039;-10px 0 0 10px&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
&lt;br /&gt;
       &#039;float&#039;:&#039;left&#039;&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Initially hide the Remove element&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#removeButton&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
   // Call the functions below when clicked&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#addButton&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
       addRow();&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $( &#039;div#removeButton&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
       removeRow();&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Function to add a row, also shows the Remove element and hides the&lt;br /&gt;
&lt;br /&gt;
   //Add element if all rows are shown&lt;br /&gt;
&lt;br /&gt;
   function addRow() {&lt;br /&gt;
&lt;br /&gt;
       $( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
&lt;br /&gt;
       $( &#039;div#removeButton&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
       if ( $( arrayRow + &#039;:eq(&#039; + rowCount + &#039;)&#039; ).attr(&#039;name&#039;) == &#039;visible&#039; )  {&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div#addButton&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Function to remove a row, also clears the contents of the removed row,&lt;br /&gt;
&lt;br /&gt;
   // shows the Add element if the last row is hidden and hides the Remove&lt;br /&gt;
&lt;br /&gt;
   // element if only the first row is shown&lt;br /&gt;
&lt;br /&gt;
   function removeRow() {&lt;br /&gt;
&lt;br /&gt;
       $( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last input[type=&amp;quot;text&amp;quot;]&#039; ).val(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
       $( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last&#039; ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
       $( &#039;div#addButton&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
       if ( $( arrayRow + &#039;:eq(1)&#039; ).attr(&#039;name&#039;) == &#039;hidden&#039; )  {&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div#removeButton&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the function with a question ID&lt;br /&gt;
&lt;br /&gt;
varLengthArray(QQ);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last as in the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:random_336x179gif.gif]]&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest;=Y&amp;amp;lang;=en here].&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Survey_Behavior $shownoanswer option] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#random_order random_order question attribute] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // Function to allow randomization of all answers&lt;br /&gt;
&lt;br /&gt;
   //except the last one in Multiple options and List/radio questions&lt;br /&gt;
&lt;br /&gt;
   function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
       // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
       var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
       $( &#039;div#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
           ansCount = (i + 1);&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
       // Place the last answer created at the end of the list&lt;br /&gt;
&lt;br /&gt;
       $( &#039;input#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).&lt;br /&gt;
&lt;br /&gt;
       //CAUTION: manually inserted line break.&lt;br /&gt;
&lt;br /&gt;
       //Append the line below at the end of the above one&lt;br /&gt;
&lt;br /&gt;
       parent().appendTo($( &#039;#question&#039; + qID + &#039; td.answer ul&#039; ));&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
   partRand(SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Partially Randomized Answers - List (dropdown) questions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the one above, allows the answers of List (dropdown) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest;=Y&amp;amp;lang;=en here].&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here])&lt;br /&gt;
#Create one or more List (dropdown) questions with sequential response codes. Set the [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#random_order random_order question attribute] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // Function to allow randomization of all answers&lt;br /&gt;
&lt;br /&gt;
   //except the last one in List/dropdown questions&lt;br /&gt;
&lt;br /&gt;
   function partRandDD(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
       // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
       var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
       $( &#039;div#question&#039; + qID + &#039; select option&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
           ansCount = i;&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
       // Place the last answer created at the end of the list&lt;br /&gt;
&lt;br /&gt;
$( &#039;option[value=&amp;quot;&#039; + ansCount + &#039;&amp;quot;]&#039; ).appendTo($( &#039;div#question&#039; + qID + &#039; select&#039; ));&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
   partRandDD(89344, 72, 244);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Making one (or more) rows of an array mandatory==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define one or more rows of an array question as mandatory (instead of all of them which the &amp;quot;Mandatory&amp;quot; question setting does). It is [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest;=Y&amp;amp;lang;=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
We use a custom onload function to interrupt the submit function and check if the inputs in the mandatory row(s) are populated. If not, an alert is popped up, the offending inputs are turned pink and the submit is aborted. Otherwise the submit goes ahead.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here]).&lt;br /&gt;
#Set up the template to use custom onload functions (see the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#Custom_onload_function workaround here]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following onload function (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]).&lt;br /&gt;
#Modify the alertText as required.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; with the question ID.&lt;br /&gt;
#Modify &amp;quot;tr:eq(0)&amp;quot; for whatever row you want mandatory. The row indexes start at 0, so &amp;quot;tr:eq(0)&amp;quot; would be row 1, &amp;quot;tr:eq(1)&amp;quot; would be row 2, &amp;quot;tr:eq(2)&amp;quot; would be row 3, etc. This example is for a single mandatory row - see below for multiple rows.&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // Interrupt the submit function&lt;br /&gt;
&lt;br /&gt;
   $(&#039;form#limesurvey&#039;).submit(function(){&lt;br /&gt;
&lt;br /&gt;
       // The alert to be displayed - modify as required&lt;br /&gt;
&lt;br /&gt;
       var alertText = &#039;You must complete all fields for Option 1.&#039;;&lt;br /&gt;
&lt;br /&gt;
       var empty = 0;&lt;br /&gt;
&lt;br /&gt;
       // Loop through all inputs of the mandatory row&lt;br /&gt;
&lt;br /&gt;
       // Modify &amp;quot;tr:eq(0)&amp;quot; for the row to be mandatory (indexes start at 0)&lt;br /&gt;
&lt;br /&gt;
       // - eg, tr:eq(0) = row 1 mandatory, tr:eq(1) = row 2 mandatory,...&lt;br /&gt;
&lt;br /&gt;
$( &#039;div#questionQQ table.question tbody tr:eq(0) input[type=&amp;quot;text&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
           if ( $( this ).val() == &#039;&#039; ) {&lt;br /&gt;
&lt;br /&gt;
               $( this ).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
&lt;br /&gt;
               empty = 1;&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           else {&lt;br /&gt;
&lt;br /&gt;
               $( this ).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
       if ( empty == 1 ) {&lt;br /&gt;
&lt;br /&gt;
           alert ( alertText );&lt;br /&gt;
&lt;br /&gt;
           return false;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           return true;&lt;br /&gt;
&lt;br /&gt;
       }&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;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you would like multiple mandatory rows, simply repeat the loop with the other row number(s) as below. This example would make rows 1 and 2 mandatory:&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;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
&amp;lt;&amp;lt;strike&amp;gt;-&amp;lt;/strike&amp;gt;---&lt;br /&gt;
&lt;br /&gt;
// Loop through all inputs of the mandatory row&lt;br /&gt;
&lt;br /&gt;
// Modify &amp;quot;tr:eq(0)&amp;quot; for the row to be mandatory (indexes start at 0)&lt;br /&gt;
&lt;br /&gt;
// - eg, tr:eq(0) = row 1 mandatory, tr:eq(1) = row 2 mandatory,...&lt;br /&gt;
&lt;br /&gt;
$( &#039;div#questionQQ table.question tbody tr:eq(0) input[type=&amp;quot;text&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
   if ( $( this ).val() == &#039;&#039; ) {&lt;br /&gt;
&lt;br /&gt;
       $( this ).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
&lt;br /&gt;
       empty = 1;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       $( this ).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
$( &#039;div#questionQQ table.question tbody tr:eq(1) input[type=&amp;quot;text&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
   if ( $( this ).val() == &#039;&#039; ) {&lt;br /&gt;
&lt;br /&gt;
       $( this ).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
&lt;br /&gt;
       empty = 1;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       $( this ).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Randomly displaying one of a few YouTube videos, and recording which was displayed==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland has created and documented a method to randomly display one of a number of youtube videos in a single question, and save which one was displayed.&lt;br /&gt;
&lt;br /&gt;
http://www.aptigence.com.au/home/archives/23-Random-display-of-videos-in-a-question-2-YouTube.html&lt;br /&gt;
&lt;br /&gt;
=Survey Behavior=&lt;br /&gt;
&lt;br /&gt;
==Respond multiple times using the same computer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this workaround it will be possible to respond multiple times to the same survey. Normally there will be a message saying that the computer already received the answers. To prevent this you have to add the following code to the URL that leads to the survey &#039;&#039;&amp;quot;&amp;amp;newtest;=Y&amp;quot;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Example of the &amp;quot;new&amp;quot; url:&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;
http://www.yourdomain.org/limesurvey/index.php?sid=12345&amp;amp;newtest;=Y&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Allow Multiple Survey Invitations to the same Email Address to be completed in the Same Browser Session==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; When Multiple Surveys Invitations are activated during the same browser session, the second and subsequent survey activation results in a system message stating that the survey has already been completed. A user would have to close the browser and reopen in order to complete the next survey inviation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Workaround:&#039;&#039;&#039; Edit the Survey Invitation Email (also the reminder) Template. Append &amp;quot;&amp;amp;newtest;=Y&amp;quot; to the {SURVEYURL} line so it looks like this {SURVEYURL}&amp;amp;newtest;=Y&lt;br /&gt;
&lt;br /&gt;
Save the edited templates.&lt;br /&gt;
&lt;br /&gt;
Note: The save of this template edit does not seem to work when using HTML invitations, only text based invitations.&lt;br /&gt;
&lt;br /&gt;
==Add a data field to manually add data==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to add some additional data after a user has finished a survey you can use the dataentry screen of the admin panel. You have to set up the survey as follows:&lt;br /&gt;
# Create a question that can store the needed data at the end of the survey.&lt;br /&gt;
# Use [http://docs.limesurvey.org/tiki-index.php?page=Setting+Conditions conditions] on the previous question so that whatever is answered at the previous question the following question &#039;&#039;&#039;doesn&#039;t appear&#039;&#039;&#039;.&lt;br /&gt;
# To enter several questions repeat steps 1-2. Don&#039;t forget to adapt the conditions.&lt;br /&gt;
# Go to the admin panel, chose the survey from the list and go to &#039;&#039;Dataentry screen for survey&#039;&#039;.&lt;br /&gt;
# Enter the additional data&lt;br /&gt;
&lt;br /&gt;
==Totally random survey order==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to use random order globally for all questions in your survey, you can do it like this, depending on what type of question routine you use.&lt;br /&gt;
# If you use Group by Group add &amp;quot;shuffle($_SESSION&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;grouplist&#039;]);&amp;quot; at the end of UpdateSessionGroupList($language) function in index.php&lt;br /&gt;
# If you use Question by Question or All-in-one put &amp;quot;shuffle($_SESSION&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;fieldarray&#039;])&amp;quot; at the end of buildsurveysession() function in index.php&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; This modifications affect all surveys in application, you may want to use an if statement with surveyid to make this work with specific surveys e.g.&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 ($surveyid==12345)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  do_some_shuffling()&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Saving survey is not possible because this workaround doesn&#039;t save random order for specyfic tokens.&lt;br /&gt;
*Solution doesn&#039;t care about language changes so if you have on in your survey this will not work.&lt;br /&gt;
*Using conditions is not possible because conditions rely on a fixed and pre-determined order of questions.&lt;br /&gt;
&lt;br /&gt;
==Selective group randomization==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.82&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Select which surveys you want to have their groups randomized, and not a global setting. This workaround puts a extra tab under group ordering which allows you to enable / disable group randomization for the selected survey.&lt;br /&gt;
&lt;br /&gt;
A working code and database modification is described in the PDF file [http://bugs.limesurvey.org/file_download.php?file_id=1937&amp;amp;type;=bug selective_random_groups] which is downloadable from the Bugtracker at [http://bugs.limesurvey.org/view.php?id=3106].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; There may be situations where this might not work, for example when adding conditions or assessments to surveys.&lt;br /&gt;
&lt;br /&gt;
==Randomize the order of &#039;&#039;sequences of groups&#039;&#039; in a survey==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.86&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can randomize the order of subsequences of groups in a survey. E.g., you may have a survey comprising the below group structure&lt;br /&gt;
*demographics&lt;br /&gt;
*itemgroup1&lt;br /&gt;
*itemgroup2&lt;br /&gt;
*itemgroup3&lt;br /&gt;
*interlude&lt;br /&gt;
*itemgroup4&lt;br /&gt;
*itemgroup5&lt;br /&gt;
*itemgroup6&lt;br /&gt;
*closingcomments&lt;br /&gt;
&lt;br /&gt;
and want to separately randomize the presentation order of itemgroup1...3 and itemgroup4...6 while maintaining the position of the other three groups. A working code modification is described in the PDF file [http://bugs.limesurvey.org/file_download.php?file_id=1228&amp;amp;type;=bug randomize_groups] which is downloadable from the Bugtracker at [http://bugs.limesurvey.org/view.php?id=557].&lt;br /&gt;
* &#039;&#039;&#039;Note:&#039;&#039;&#039; The code will randomize the order of subsequent groups in isolation, not across different sequences. Hence in the above example, you might get &#039;&#039;itemgroup1, 3, 2&#039;&#039; but never &#039;&#039;itemgroup1, 4, 2&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Note:&#039;&#039;&#039; The survey presentation format must be &#039;&#039;Group by Group&#039;&#039; not &#039;&#039;Question by Question&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Note:&#039;&#039;&#039; If you wish to select only a limited number of groups from a larger set, replace&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$scratcharr = array_merge($scratcharr, $randarr);&amp;lt;/syntaxhighlight&amp;gt;with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$scratcharr = array_merge($scratcharr, array_slice($randarr,0,x));&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where x is the number of elements/groups that you wish to include. In the example above &#039;&#039;&#039;$scratcharr = array_merge($scratcharr, array_slice($randarr,0,2));&#039;&#039;&#039; would select two out of the possible three groups in each group set.&lt;br /&gt;
* &#039;&#039;&#039;Warning:&#039;&#039;&#039; The code is compatible with conditions operating on items within a group but most possibly produces erroneous behavior with conditions between groups&lt;br /&gt;
* &#039;&#039;&#039;Warning:&#039;&#039;&#039; In a multi-language survey, the groups get randomized each time the language is changed. A simple workaround is to remove the language changer from the question pages of the survey leaving it on the welcome page only. (Though not totally foolproof this does lower the risk of unnecessary language changes.)&lt;br /&gt;
&lt;br /&gt;
==Selective Question Randomization==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.82&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this workaround you are able to select which groups within a survey should have their questions randomized and not kept in order. This workaround also adds a tab in the question ordering page. The extra tab allows you to enable / disable question randomization for the selected group.&lt;br /&gt;
&lt;br /&gt;
A working code and database modification is described in the PDF file [http://bugs.limesurvey.org/file_download.php?file_id=1939&amp;amp;type;=bug selective_random_questions] which is downloadable from the Bugtracker at [http://bugs.limesurvey.org/view.php?id=3107].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This might not work when adding conditions or assessments to the survey.&lt;br /&gt;
&lt;br /&gt;
== Randomize the order of questions within individual groups - JavaScript solution==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to randomize the order of questions in individual groups. It uses JavaScript/jQuery to apply this randomization to only those groups that you wish and requires no modification of the core files when updating the installation.&lt;br /&gt;
&lt;br /&gt;
The script uses a cookie to &amp;quot;remember&amp;quot; the shuffled order of the questions for the duration of the session so if a respondent navigates away from the group and returns, they will see the same question order. However if the survey is submitted or the session expires the questions will be re-shuffled.&lt;br /&gt;
&lt;br /&gt;
A couple of cautions about the script are:&lt;br /&gt;
#If the survey is saved, the questions will be re-shuffled when it is accessed again (as with the PHP solution).&lt;br /&gt;
#The question shuffling may play havoc with conditions within a group (as with the PHP solution).&lt;br /&gt;
#The script has been tested with all templates shipped with 1.85+ but if you have a custom template with &amp;quot;question&amp;quot; in the ID of division(s) (ie &amp;lt;div id=&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;question&amp;lt;/span&amp;gt;Holder&amp;quot;&amp;gt;) it may fail - the script looks for all divs with IDs starting with &amp;quot;question&amp;quot; and adds them to an array to be shuffled.&lt;br /&gt;
&lt;br /&gt;
There is a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=84767&amp;amp;newtest;=Y&amp;amp;lang;=en here].&lt;br /&gt;
&lt;br /&gt;
Put simply, the script:&lt;br /&gt;
#Checks cookies to see if the questions have already been shuffled for this group and session.&lt;br /&gt;
#If so - displays the questions in that order.&lt;br /&gt;
#If not - creates an array of all of the questions in the group, shuffles the array, sets a cookie with the shuffled array contents, displays the questions in the shuffled order.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript (see [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here])..&lt;br /&gt;
#Create your group and questions.&lt;br /&gt;
#In the source of the group description add the following onload function (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]).&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       function shuffleQuestions() {&lt;br /&gt;
&lt;br /&gt;
           // Create an array to hold question IDs&lt;br /&gt;
&lt;br /&gt;
           var qArray = new Array();&lt;br /&gt;
&lt;br /&gt;
           // Find the group ID of the page&lt;br /&gt;
&lt;br /&gt;
           var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
&lt;br /&gt;
           var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
&lt;br /&gt;
           var sID = tmp[0];&lt;br /&gt;
&lt;br /&gt;
           var gID = tmp[1];&lt;br /&gt;
&lt;br /&gt;
           // A function to get the value of a cookie by name&lt;br /&gt;
&lt;br /&gt;
           function getCookie ( cookieName ) {&lt;br /&gt;
&lt;br /&gt;
               var results = document.cookie.match ( &#039;(&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;|;) ?&#039; + cookieName + &#039;=([&amp;lt;/div&amp;gt;;]*)(;|$)&#039; );&lt;br /&gt;
&lt;br /&gt;
               if ( results ) {&lt;br /&gt;
&lt;br /&gt;
                   return ( unescape ( results[2] ) );&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return null;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Get the session name&lt;br /&gt;
&lt;br /&gt;
           var sessionName = getCookie ( &#039;PHPSESSID&#039; );&lt;br /&gt;
&lt;br /&gt;
           // Check to see if the question order has already been shuffled in this session&lt;br /&gt;
&lt;br /&gt;
           var cookieArray = getCookie ( &#039;sArray&#039; + gID + &#039;_&#039; + sessionName );&lt;br /&gt;
&lt;br /&gt;
           // If already shuffled, use that question order&lt;br /&gt;
&lt;br /&gt;
           if ( cookieArray ) {&lt;br /&gt;
&lt;br /&gt;
               //qArray = $.trim(cookieArray);&lt;br /&gt;
&lt;br /&gt;
               qArray = cookieArray.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // If not, go ahead and shuffle&lt;br /&gt;
&lt;br /&gt;
           else {&lt;br /&gt;
&lt;br /&gt;
               // Load the IDs of all questions on the page into the array&lt;br /&gt;
&lt;br /&gt;
               $( &#039;div[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;question&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                   qArray.push($( this ).attr(&#039;id&#039;));&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
               // Shuffle the questions array&lt;br /&gt;
&lt;br /&gt;
               function shuffle(o){&lt;br /&gt;
&lt;br /&gt;
                   for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);&lt;br /&gt;
&lt;br /&gt;
                   return o;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               shuffle(qArray);&lt;br /&gt;
&lt;br /&gt;
               // Set a cookie with the value of the shuffled array&lt;br /&gt;
&lt;br /&gt;
               var today = new Date();&lt;br /&gt;
&lt;br /&gt;
               today.setTime( today.getTime() );&lt;br /&gt;
&lt;br /&gt;
               var expires = 2 * 1000 * 60 * 60 * 24; // Expire the cookie in 2 days&lt;br /&gt;
&lt;br /&gt;
               var expiresDate = new Date( today.getTime() + (expires) );&lt;br /&gt;
&lt;br /&gt;
               document.cookie = &#039;sArray&#039; + gID + &#039;_&#039; + sessionName + &#039;=&#039; + qArray + &#039;;expires=&#039; + expiresDate.toGMTString();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Wrap the questions in a div&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div[id&amp;lt;/div&amp;gt;=&amp;quot;question&amp;quot;]&#039; ).wrapAll( document.createElement(&#039;div&#039;) );&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;question&amp;quot;]:eq(0)&#039; ).parent().attr(&#039;id&#039;, &#039;qWrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div#qWrapper&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;padding&#039;:0,&lt;br /&gt;
&lt;br /&gt;
               &#039;margin&#039;:0&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the questions into the wrapper in the shuffled order&lt;br /&gt;
&lt;br /&gt;
           $.each(qArray, function(i, val){&lt;br /&gt;
&lt;br /&gt;
               $( &#039;div#&#039; + val + &#039;&#039; ).appendTo( $( &#039;#qWrapper&#039; ) );&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       shuffleQuestions();&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Randomise the order of questions &#039;&#039;within&#039;&#039; groups==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can randomize the order questions of within groups (i.e. without interleaving questions from different groups) like this:&lt;br /&gt;
&lt;br /&gt;
1 Call a custom function from the last line of buildsurveysession() before the return statement in index.php:&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;
$_SESSION&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;fieldarray&#039;] = withinGroupsShuffle();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Add these custom functions at the end of the same file:&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;
$currentGid;&lt;br /&gt;
&lt;br /&gt;
function withinGroupsShuffle() {&lt;br /&gt;
&lt;br /&gt;
   global $currentGid;&lt;br /&gt;
&lt;br /&gt;
   $groupArray = array();&lt;br /&gt;
&lt;br /&gt;
   $shuffledArray = array();&lt;br /&gt;
&lt;br /&gt;
   foreach ($_SESSION[&#039;grouplist&#039;] as $group)    {&lt;br /&gt;
&lt;br /&gt;
       $currentGid = $group[0];&lt;br /&gt;
&lt;br /&gt;
       $groupArray = array_filter($_SESSION[&#039;fieldarray&#039;], &amp;quot;questionInGroup&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
       shuffle($groupArray);&lt;br /&gt;
&lt;br /&gt;
       $tmp = $shuffledArray;&lt;br /&gt;
&lt;br /&gt;
       $shuffledArray = array_merge($tmp, $groupArray);&lt;br /&gt;
&lt;br /&gt;
       $groupArray = array();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return $shuffledArray;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function questionInGroup($question) {&lt;br /&gt;
&lt;br /&gt;
   global $currentGid;&lt;br /&gt;
&lt;br /&gt;
   return ($question[5] == $currentGid) ? 1 : 0;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;I&#039;m new to PHP, so please make changes if you can make the code shorter or more elegant&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This could be combined with the method mentioned above for shuffling the order of groups:&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;
shuffle($_SESSION&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;grouplist&#039;]);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know how this code affects or is affected by conditions or tokens! This code has the same limitations as the global randomisation above: it applies to all groups in all surveys. It would be nice to add a group-level parameter like randomise_questions = [0|1], but I can&#039;t find a mechanism for doing that.&lt;br /&gt;
&lt;br /&gt;
== Random question sets==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, in conjunction with the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds#Randomize_the_order_of_questions_within_individual_groups_JavaScript_solution randomizing questions script], allows you to display a random set of questions in a group.&lt;br /&gt;
&lt;br /&gt;
There is a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=84767&amp;amp;newtest;=Y&amp;amp;lang;=en here] (page 2).&lt;br /&gt;
&lt;br /&gt;
JavaScript is used to first shuffle the question order and then hide the number of questions that you stipulate, effectively giving respondents a random question set. So if, as in the demo, you have 5 questions in your group and choose to hide 2, the respondents will be presented with a random 3 questions.&lt;br /&gt;
&lt;br /&gt;
A brief explanation of the script is:&lt;br /&gt;
*The questions are shuffled (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds#Randomize_the_order_of_questions_within_individual_groups_JavaScript_solution randomizing questions]) and their IDs placed in an array.&lt;br /&gt;
*The number of questions to be shown is calculated and their IDs are moved to a new array.&lt;br /&gt;
*All questions in the first array are hidden - this effectively hides the first &#039;&#039;&#039;&#039;&#039;n&#039;&#039;&#039;&#039;&#039; questions on the page so you&#039;ll get a random set of questions displayed.&lt;br /&gt;
*An asterisk is prepended to the remaining questions (remove this if your questions are not mandatory).&lt;br /&gt;
*When the next/submit button is clicked, all remaining questions are checked for an answer. If any are unanswered, their text is turned red, an alert is popped up and the next/submit is aborted (remove this if your questions are not mandatory).&lt;br /&gt;
&lt;br /&gt;
A cookie is used to &amp;quot;remember&amp;quot; the shuffled order of the questions for the duration of the session so if a respondent navigates away from the group and returns, they will see the same question set. However if the survey is submitted or the session expires, the questions will be re-shuffled and a new set will be displayed. Therefor this workaround should not be used with surveys that can be saved.&lt;br /&gt;
&lt;br /&gt;
A couple of cautions about the script are:&lt;br /&gt;
#If the survey is saved, the questions will be re-shuffled when it is accessed again and a new question set will be displayed.&lt;br /&gt;
#The question shuffling may play havoc with conditions within a group.&lt;br /&gt;
#The script has been tested with all templates shipped with 1.85+ but if you have a custom template with &amp;quot;question&amp;quot; in the ID of division(s) (ie &amp;lt;div id=&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;question&amp;lt;/span&amp;gt;Holder&amp;quot;&amp;gt;) it may fail - the script looks for all divs with IDs starting with &amp;quot;question&amp;quot; and adds them to an array to be shuffled.&lt;br /&gt;
#The script may need to be modified to display the &amp;quot;Mandatory&amp;quot; asterisk in templates other than the default - see below.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript (see [http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects documentation here]).&lt;br /&gt;
#Create your group with all questions non-mandatory (we&#039;ll make them mandatory later with JavaScript).&lt;br /&gt;
#In the source of the group description add the following onload function (see [http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure;=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ How to use script here]).&lt;br /&gt;
#Modify the function call at the end of the script for the number of questions to be hidden and the mandatory error text.&lt;br /&gt;
&lt;br /&gt;
Onload 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;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       function shuffleQuestions() {&lt;br /&gt;
&lt;br /&gt;
           // Create an array to hold question IDs&lt;br /&gt;
&lt;br /&gt;
           var qArray = new Array();&lt;br /&gt;
&lt;br /&gt;
           // Find the group ID of the page&lt;br /&gt;
&lt;br /&gt;
           var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
&lt;br /&gt;
           var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
&lt;br /&gt;
           var sID = tmp[0];&lt;br /&gt;
&lt;br /&gt;
           var gID = tmp[1];&lt;br /&gt;
&lt;br /&gt;
           // A function to get the value of a cookie by name&lt;br /&gt;
&lt;br /&gt;
           function getCookie ( cookieName ) {&lt;br /&gt;
&lt;br /&gt;
               var results = document.cookie.match ( &#039;(&amp;lt;/div&amp;gt;|;) ?&#039; + cookieName + &#039;=([&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;;]*)(;|$)&#039; );&lt;br /&gt;
&lt;br /&gt;
               if ( results ) {&lt;br /&gt;
&lt;br /&gt;
                   return ( unescape ( results[2] ) );&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return null;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Get the session name&lt;br /&gt;
&lt;br /&gt;
           var sessionName = getCookie ( &#039;PHPSESSID&#039; );&lt;br /&gt;
&lt;br /&gt;
           // Check to see if the question order has already been shuffled in this session&lt;br /&gt;
&lt;br /&gt;
           var cookieArray = getCookie ( &#039;sArray&#039; + gID + &#039;_&#039; + sessionName );&lt;br /&gt;
&lt;br /&gt;
           // If already shuffled, use that question order&lt;br /&gt;
&lt;br /&gt;
           if ( cookieArray ) {&lt;br /&gt;
&lt;br /&gt;
               //qArray = $.trim(cookieArray);&lt;br /&gt;
&lt;br /&gt;
               qArray = cookieArray.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // If not, go ahead and shuffle&lt;br /&gt;
&lt;br /&gt;
           else {&lt;br /&gt;
&lt;br /&gt;
               // Load the IDs of all questions on the page into the array&lt;br /&gt;
&lt;br /&gt;
               $( &#039;div[id&amp;lt;/div&amp;gt;=&amp;quot;question&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                   qArray.push($( this ).attr(&#039;id&#039;));&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
               // Shuffle the questions array&lt;br /&gt;
&lt;br /&gt;
               function shuffle(o){&lt;br /&gt;
&lt;br /&gt;
                   for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);&lt;br /&gt;
&lt;br /&gt;
                   return o;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               shuffle(qArray);&lt;br /&gt;
&lt;br /&gt;
               // Set a cookie with the value of the shuffled array&lt;br /&gt;
&lt;br /&gt;
               var today = new Date();&lt;br /&gt;
&lt;br /&gt;
               today.setTime( today.getTime() );&lt;br /&gt;
&lt;br /&gt;
               var expires = 2 * 1000 * 60 * 60 * 24; // Expire the cookie in 2 days&lt;br /&gt;
&lt;br /&gt;
               var expiresDate = new Date( today.getTime() + (expires) );&lt;br /&gt;
&lt;br /&gt;
               document.cookie = &#039;sArray&#039; + gID + &#039;_&#039; + sessionName + &#039;=&#039; + qArray + &#039;;expires=&#039; + expiresDate.toGMTString();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Wrap the questions in a div&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;question&amp;quot;]&#039; ).wrapAll( document.createElement(&#039;div&#039;) );&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div[id&amp;lt;/div&amp;gt;=&amp;quot;question&amp;quot;]:eq(0)&#039; ).parent().attr(&#039;id&#039;, &#039;qWrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div#qWrapper&#039; ).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;padding&#039;:0,&lt;br /&gt;
&lt;br /&gt;
               &#039;margin&#039;:0&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the questions into the wrapper in the shuffled order&lt;br /&gt;
&lt;br /&gt;
           $.each(qArray, function(i, val){&lt;br /&gt;
&lt;br /&gt;
               $( &#039;div#&#039; + val + &#039;&#039; ).appendTo( $( &#039;#qWrapper&#039; ) );&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       shuffleQuestions();&lt;br /&gt;
&lt;br /&gt;
       function hideQuestions(numberToHide, mandatoryMsg) {&lt;br /&gt;
&lt;br /&gt;
           // Create an array of the IDs of all questions on the page&lt;br /&gt;
&lt;br /&gt;
           var questions = new Array();&lt;br /&gt;
&lt;br /&gt;
           $( &#039;div[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;question&amp;quot;]&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               questions.push($( this ).attr(&#039;id&#039;));&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Remove the &amp;quot;shown&amp;quot; questions and place them in a new array&lt;br /&gt;
&lt;br /&gt;
           var questionsLength = questions.length;&lt;br /&gt;
&lt;br /&gt;
           var shownQuestions = questions.splice(numberToHide,questionsLength-numberToHide);&lt;br /&gt;
&lt;br /&gt;
           // Hide the remaining questions&lt;br /&gt;
&lt;br /&gt;
           $.each(questions, function(i, val){&lt;br /&gt;
&lt;br /&gt;
               $( &#039;div#&#039; + val + &#039;&#039; ).hide();&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Add an asterisk to the &amp;quot;shown&amp;quot; questions&lt;br /&gt;
&lt;br /&gt;
           // NOTE: Comment this section out if questions are not mandatory&lt;br /&gt;
&lt;br /&gt;
           $( &#039;td.questiontext&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
           // Interrupt the submit function and validate mandatory questions&lt;br /&gt;
&lt;br /&gt;
           // NOTE: Comment this section out if questions are not mandatory&lt;br /&gt;
&lt;br /&gt;
           $(&#039;form#limesurvey&#039;).submit(function(){&lt;br /&gt;
&lt;br /&gt;
               // Loop through all &amp;quot;shown&amp;quot; questions and check for answer&lt;br /&gt;
&lt;br /&gt;
               var answered = 0;&lt;br /&gt;
&lt;br /&gt;
               $.each(shownQuestions, function(i, val){&lt;br /&gt;
&lt;br /&gt;
                   if ( $( &#039;div#&#039; + val + &#039; input.radio:checked&#039; ).length == 0 ) {&lt;br /&gt;
&lt;br /&gt;
                       $( &#039;div#&#039; + val + &#039;&#039; ).css(&#039;color&#039;, &#039;red&#039;);&lt;br /&gt;
&lt;br /&gt;
                       answered = 1;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
                   else {&lt;br /&gt;
&lt;br /&gt;
                       $( &#039;div#&#039; + val + &#039;&#039; ).css(&#039;color&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
               if ( answered == 1 ) {&lt;br /&gt;
&lt;br /&gt;
                   alert ( mandatoryMsg );&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       // Call the hide function&lt;br /&gt;
&lt;br /&gt;
       // Edit here for number of question to hide and mandatory message&lt;br /&gt;
&lt;br /&gt;
       hideQuestions(2, &#039;Please complete all questions&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To add the asterisk to non default templates, replace &#039;&#039;$( &#039;td.questiontext&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&#039;&#039; with:&lt;br /&gt;
&lt;br /&gt;
- basic - &#039;&#039;$( &#039;td.be&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- bluengrey - Not possible to insert asterisk in correct location&lt;br /&gt;
&lt;br /&gt;
- business_grey - &#039;&#039;$( &#039;div.questiontext&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- clear_logo - &#039;&#039;$( &#039;td.be&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- default - &#039;&#039;$( &#039;td.questiontext&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- eirenicon - Not possible to insert asterisk in correct location&lt;br /&gt;
&lt;br /&gt;
- limespired - &#039;&#039;$( &#039;div.survey-question-text&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- mint_idea - &#039;&#039;$( &#039;div.survey-question-text&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- sherpa - &#039;&#039;$( &#039;div.survey-question-text&#039; ).prepend( &#039;&amp;lt;span class=&amp;quot;asterisk&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;&#039;);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- vallendar - Not possible to insert asterisk in correct location&lt;br /&gt;
&lt;br /&gt;
==Randomization - &#039;&#039;Assign People Randomly&#039;&#039; To Surveys==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a very easy way to assign people randomly to surveys, I think experts do it in other ways, but it works for me.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;LINK.PHP:&#039;&#039;&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;
 $db = @file(&amp;quot;link.txt&amp;quot;); // path to .txt file&lt;br /&gt;
&lt;br /&gt;
 $anz = @count($db);&lt;br /&gt;
&lt;br /&gt;
 srand[[SGQA identifier]], and the answer, as a parameter of your survey URL. This feature will only work where the survey is commenced immediately upon entering the URL (so it won&#039;t work if you use CAPTCHA&#039;s to restrict access, or the registration page).&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need to ensure that the answer you pass is the correct format for the question you are attempting to prefill - for example - multiple option questions should contain a &amp;quot;Y&amp;quot; to check a box. List type questions need the correct answer code. To be certain which codes to pass, complete a survey manually with the prefilled answer(s) you want, and then export the results as question codes and answer codes(not full text). This will give you both the correct SGQA identifier (the name of the column), and the correct format for the answer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;http://www.myownd.../index.php?sid=1234&amp;amp;1234X43X123=Y&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the user gets to that question, the &amp;quot;Y&amp;quot; will be prefilled as the answer to question 123 in group 43 in survey 1234.&lt;br /&gt;
&lt;br /&gt;
==Prefilling survey answers using the survey URL and hiding the Answer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.80RC3+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Having used the previous workaround to prefill an answer in your survey by passing a [[SGQA identifier]] throught the URL, you may also want to hide the question that is being prefilled so that the user cannot modify it (or even know it is there).&lt;br /&gt;
&lt;br /&gt;
There are currently two options for you:&lt;br /&gt;
*The javascript approach which does not require patching the limesurvey source&lt;br /&gt;
*Applying the patch attached to http://bugs.limesurvey.org/view.php?id=3555 and setting the &#039;&#039;hidden&#039;&#039; question attribute.&lt;br /&gt;
&lt;br /&gt;
===The javascript approach===&lt;br /&gt;
&lt;br /&gt;
To do this, utilise the id name of each answers div area. Each question is presented in a div with an idea comprising the word &amp;quot;question&amp;quot; immediately followed with the questions unique id code. So from the above example, with SGQA 1234X43X123, the question id we are prefilling is id 123. That means the div id for displaying the whole question is &amp;quot;question123&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To hide this question, enter the following javascript in the question source.&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;script type=&#039;text/javascript&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround will make most sense if you are displaying your surveys in groups. If you are displaying question by question, then the user will get a blank page with just a &amp;quot;Next&amp;quot; and &amp;quot;Prev&amp;quot; button, and they may get confused.&lt;br /&gt;
&lt;br /&gt;
==Prefilling a date question with the current date==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.80RC3&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Workaround created by user &amp;quot;[http://docs.limesurvey.org/tiki-index.php?page=UserPage%20Mazi Mazi]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Using the [http://docs.limesurvey.org/tiki-index.php?page=Workarounds#Prefilling_survey_answers_using_the_survey_URL workaround mentioned above] you can prefill the current date for a date question. Instead of using the common link to a survey which looks like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;http://www.yourdomain.org/limesurvey/index.php?sid=53298&amp;amp;newtest;=Y&amp;amp;lang;=de&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you create an additional script, let&#039;s call it date.php. This script contains 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;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
   $date = date(&amp;quot;Y-m-d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   header(&amp;quot;Location: http://www.yourdomain.org/limesurvey/index.php?sid=53298&amp;amp;newtest;=Y&amp;amp;lang;=de&amp;amp;53298X15X102=$date&amp;quot;);&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;
The script determines the current date and calls the survey with a certain URL. The current date is attached as the answer for a certain date question using [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier SGQA identifier]. Don&#039;t forget to &#039;&#039;&#039;adjust the SID and SGQA identifier&#039;&#039;&#039; according to your survey/group/question ID!&lt;br /&gt;
&lt;br /&gt;
Upload the new &#039;&#039;date.php&#039;&#039; file into your limesurvey directory. You can then call the survey using this link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;http://www.yourdomain.org/limesurvey/date.php&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Things to watch out for:&lt;br /&gt;
* Date questions always use the internal date data format of the database which has to be YYYY-MM-DD!&lt;br /&gt;
* You have to adjust the SID at the URl.&lt;br /&gt;
* Also adjust the SGQA identifier (SIDXGIDXQID) according to your survey.&lt;br /&gt;
* This solution doesn&#039;t work if you use tokens at your survey.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;New:&#039;&#039; I created a PHP script which is easy to adapt by just entering the matching IDs. (&#039;&#039;[http://docs.limesurvey.org/tiki-index.php?page=UserPage%20Mazi Mazi]&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Media:prefill_date.php|Download this file]]&lt;br /&gt;
&lt;br /&gt;
==Offer option to change answers later==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When having a closed access survey using a token table it is possible to offer the opportunity to change answers later. Normally after having submitted the answers a token is marked as &amp;quot;used&amp;quot;. To prevent this do as follows:&lt;br /&gt;
* set your survey to question-by-question mode (or group-by-group mode)&lt;br /&gt;
* set the survey to Non anonymous + Allow persistence for token answers&lt;br /&gt;
* activate survey and create your token table&lt;br /&gt;
* add at least one question of type boilerplate (which contains just some text). This is necessaray to give some instructions to the user like &amp;quot;&#039;&#039;Your answers have been recorded to the DB, if you&#039;re sure you won&#039;t modify them, you can submit your response. If unsure, please quit your browser now and get back later with the private URL you&#039;ve received&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
By not submitting the survey the user is still able to change the answers later.&lt;br /&gt;
&lt;br /&gt;
==Use general password for accessing a survey==&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use tokens but a general password to access a survey you can set your survey to &amp;quot;allow public access&amp;quot;. Don&#039;t create a token table but use the following workaround:&lt;br /&gt;
# Create a short text question first&lt;br /&gt;
# Create the other questions&lt;br /&gt;
# Use conditions on all the other questions. You can use regular expressions to validate the string entered at the short text question. Just validate a certain password. If the password is correct the following questions are shown.&lt;br /&gt;
# Create a boilerplate question which just says &amp;quot;invalid password&amp;quot; which is shown if the user entered a wrong password.&lt;br /&gt;
&lt;br /&gt;
==Create token on the fly and Edit completed survey==&lt;br /&gt;
&lt;br /&gt;
When having a close token survey you can create a token on the fly by giving as parameters sid and token.&lt;br /&gt;
&lt;br /&gt;
In addition if someone has already completed a survey he can review his answers and correct them.&lt;br /&gt;
&lt;br /&gt;
[http://bugs.limesurvey.org/view.php?id=2982 Just put this script attached at the bugtracker ticket into limesurveys root directory]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Prerequisites&#039;&#039;&#039;:&lt;br /&gt;
# Anonymous answers? No (This survey is NOT anonymous.)&lt;br /&gt;
# Enable Token-based answers persistence? Yes&lt;br /&gt;
# Switch to closed-acces mode&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;http://www.yoururl.com/limesurvey180/newtoken.php?sid=98761&amp;amp;token;=12345&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where Survey id = 98761 your survey&#039;s id and token=12345 a token (any token actually)&lt;br /&gt;
# The first time the token will be created and you you will redirect to anwser the surrvey&lt;br /&gt;
# If you wont complete the survey and call the script with the same parameters you will be redirect to the same case in order to finish the survey&lt;br /&gt;
# If you finish the survey and call the script with the same parameters you will see restart the survey with your previews answers prefiled so you can change them&lt;br /&gt;
# Back to 3&lt;br /&gt;
&lt;br /&gt;
this is valid for all survey in the installation but you can make a filter so it wont be valid for every survey.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Relative posts&#039;&#039;&#039;&lt;br /&gt;
*LimeSurvey Bug &amp;amp; Feature Tracker&lt;br /&gt;
&lt;br /&gt;
[http://bugs.limesurvey.org/view.php?id=2982]&lt;br /&gt;
*the code&lt;br /&gt;
&lt;br /&gt;
http://bugs.limesurvey.org/file_download.php?file_id=1826&amp;amp;type;=bug&lt;br /&gt;
&lt;br /&gt;
by user &amp;quot;janokary&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==multiple &#039;completed&#039; with only one token==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.71&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Whit a closed survey, each token work only one time. Sometime we need the possibility to complete a particular survey several time with the same token.&lt;br /&gt;
&lt;br /&gt;
Here is an example for the survey id &#039;71314&#039;.  Don&#039;t forget to adapt your own sid.&lt;br /&gt;
&lt;br /&gt;
Edit &#039;&#039;index.php &#039;&#039; to in the function submittokens() replace lines ~ 1312 :&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 (bIsTokenCompletedDatestamped($thissurvey))&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
   $utquery .= &amp;quot;SET completed=&#039;$today&#039;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
   $utquery .= &amp;quot;SET completed=&#039;Y&#039;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;with lines :&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 (bIsTokenCompletedDatestamped($thissurvey))&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
   //multiple token only for survey 71314&lt;br /&gt;
&lt;br /&gt;
   if ($surveyid == &#039;71314&#039;) {&lt;br /&gt;
&lt;br /&gt;
   $utquery .= &amp;quot;SET completed=&#039;N&#039;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   }else {&lt;br /&gt;
&lt;br /&gt;
   $utquery .= &amp;quot;SET completed=&#039;$today&#039;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
   //$utquery .= &amp;quot;SET completed=&#039;Y&#039;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We never update the database with the completed date and time for this survey.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039; : a limitation of this code is that you never recieve a confirmation mail for the compledted.&lt;br /&gt;
&lt;br /&gt;
==Loop question(s)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There is no real loop option within Limesurvey 1.x. Too loop a question an initial question to determine the number of loops is needed. Looping is then done using a condition wokraround:&lt;br /&gt;
&lt;br /&gt;
1. Create a single choice question asking &amp;quot;How many X do you want to rate&amp;quot;, possible answers 1, 2, 3, 4, 5.&lt;br /&gt;
&lt;br /&gt;
2. Create up to 5 following questions asking &amp;quot;Please rate item 1/2/3/...&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
3. Check manual -&amp;gt; conditions and read it carefully.&lt;br /&gt;
&lt;br /&gt;
4. Set conditions like&lt;br /&gt;
&lt;br /&gt;
a) &amp;quot;Only show Q3 (Rate item 2) IF Q1 (How many...) was answered 2&lt;br /&gt;
&lt;br /&gt;
OR Q1 (How many...) was answered 3&lt;br /&gt;
&lt;br /&gt;
OR Q1 (How many...) was answered 4&lt;br /&gt;
&lt;br /&gt;
OR Q1 (How many...) was answered 5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
b) &amp;quot;Only show Q4 (Rate item 3) IF Q1 (How many...) was answered 3&lt;br /&gt;
&lt;br /&gt;
OR Q1 (How many...) was answered 4&lt;br /&gt;
&lt;br /&gt;
OR Q1 (How many...) was answered 5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
c) Q5... see above&lt;br /&gt;
&lt;br /&gt;
d) Q6...&lt;br /&gt;
&lt;br /&gt;
Of course Q2 is always shown, the following question will be added by conditions depending on what the user answered at Q1.&lt;br /&gt;
&lt;br /&gt;
=Improve Statistics=&lt;br /&gt;
&lt;br /&gt;
==Display menu of all public survey statistics==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: version 1.85&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some of you may want to give your survey respondents a URL that will display a menu of all surveys that have public statistics to be displayed. This is a hack module that generates a menu only and then calls the real userstatistics module to display those statistics for your user.&lt;br /&gt;
&lt;br /&gt;
It is a small file and is basically the same code Jason wrote to build the survey menu with some minor edits. You can rename the module to anything you like for your particular survey system and place it in your root directory.  Then give the URL to this module to your users to produce a menu of the available surveys you have public statistics enabled on.&lt;br /&gt;
&lt;br /&gt;
You can [http://www.limesurvey.org/support/forums/5-can-i-do-this-with-limesurvey/30067-display-menu-of-all-public-survey-statistics.html?lang=en#30067 download the file in the forum]&lt;br /&gt;
&lt;br /&gt;
=Everything Else=&lt;br /&gt;
&lt;br /&gt;
==How to import survey responses from v1.00 into v1.5x (and later)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LS &amp;gt;= 1.50&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In LimeSurvey v1.50 it&amp;amp;acute;s possible to import a survey, which is generated (and exported) with v1.00 into v1.5x. The Problem is, on that way only the survey structure gets imported, but no respones to that survey.&lt;br /&gt;
&lt;br /&gt;
If you also need to import the responses, follow the next steps:&lt;br /&gt;
#Export your survey in v1.00&lt;br /&gt;
#Do a VV-Export in v1.00 (to save your responses)&lt;br /&gt;
#Import your survey from v1.00 into v1.5x via &amp;quot;Create or Import a New Survey&amp;quot; in the main Admin Panel&lt;br /&gt;
#Activate your imported survey&lt;br /&gt;
#Fill out your survey once, so that at least one response is in your database.&lt;br /&gt;
#Do a VV-Export in v1.5x&lt;br /&gt;
#Open both VV-Exports (v1.5x and v1.00); if you use Microsoft Excel do it via &amp;quot;Open New File&amp;quot; and &amp;quot;Import from Text-File&amp;quot; or &amp;quot;Import from external source - textfile&amp;quot; and choose &amp;quot;seperated&amp;quot; and &amp;quot;Unicode (UTF-8)&amp;quot;; choose&lt;br /&gt;
#Compare the file structure and you&amp;amp;acute;ll see that there are two columns added (submitdate and startlanguage) and that all question codes changed.&lt;br /&gt;
#Copy all rows (except row 1 and 2, that means you start with the third row) from your VV-Export  v1.00 into your VV-Export v1.5x (also put it at the third row)&lt;br /&gt;
#Add the columns &amp;quot;submitdate&amp;quot; and &amp;quot;startlanguage&amp;quot; in your VV-Export v1.5x-File, right between &amp;quot;id&amp;quot; and &amp;quot;token&amp;quot;&lt;br /&gt;
#Save your file (in Microsoft Excel use Textfile - Tabstopp seperated). It&amp;amp;acute;s necessary that your file after saving has the same format as before - Notice: it&amp;amp;acute;s not a normal .csv-File.&lt;br /&gt;
#Import your file via VV-Import&lt;br /&gt;
&lt;br /&gt;
==If you closed your survey accidentally==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: All versions&#039;&#039;&lt;br /&gt;
# Activate your survey again&lt;br /&gt;
# Go to the &amp;quot;Browse responses for this survey&amp;quot; menu&lt;br /&gt;
# Click at the &amp;quot;Import answers from a deactivated survey table&amp;quot; button&lt;br /&gt;
# Choose your source table&lt;br /&gt;
# Click at the &amp;quot;Import responses&amp;quot; button&lt;br /&gt;
&lt;br /&gt;
==Translate surveys without admin access==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User &amp;quot;CasN&amp;quot; has written a nice extension that allows you to translate surveys without having access to the admin panel. He has added his files in the bug and feature tracker ([http://bugs.limesurvey.org/view.php?id=1735 01735: Remote translating feature]) where you can download them. You&#039;ll also find a short How-To there.&lt;br /&gt;
&lt;br /&gt;
This is how it works:&lt;br /&gt;
&lt;br /&gt;
Copy the scripts in the root of your survey directory and call starttrans.php like this starttrans.php?survey=12345&lt;br /&gt;
&lt;br /&gt;
It will check the languages connected to the survey and also verify the labelsets used.&lt;br /&gt;
&lt;br /&gt;
You will then get a screen with for each language the required links for translating, aswell for the labels as the survey itself. From the survey, the question and tip fields are presented for translation.&lt;br /&gt;
&lt;br /&gt;
Thanks CasN for sharing your solution with the community!&lt;br /&gt;
&lt;br /&gt;
== Create Question Pools==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workarounds was created by [http://www.limesurvey.org/component/option,com_comprofiler/task,userProfile/user,7511/lang,de/ user &amp;quot;akky&amp;quot;] and [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/id,18171/catid,11/limit,10/limitstart,10/lang,de/ posted in the forum]:&lt;br /&gt;
&lt;br /&gt;
This is a simple solution to create question pools for Limesurvey. It will require access to the backend database. I&#039;m not going to explain how to do this, as &#039;&#039;&#039;&#039;&#039;if you don&#039;t understand it, then you shouldn&#039;t really do it&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically 3 tables exist that we care about:&lt;br /&gt;
*lime_surveys - id field = sid&lt;br /&gt;
*lime_groups - id field = gid&lt;br /&gt;
*lime_questions id field = qid&lt;br /&gt;
&lt;br /&gt;
In order to show the questions correctly the id field from the &#039;&#039;lime_groups &#039;&#039;table exists in the &#039;&#039;lime_questions &#039;&#039;table. This then is used to create the parent/child relationship.&lt;br /&gt;
&lt;br /&gt;
However, if you want to create a pool of questions all you need to do is to amend the gid field in the &#039;&#039;lime_questions&#039;&#039; table to a value that doesn&#039;t exist in the &#039;&#039;lime_groups &#039;&#039;table. I would use 0 or a something silly like 10000. Try this with one question and you will notice it doesnt appear in the question list.&lt;br /&gt;
&lt;br /&gt;
It&#039;s a crude workaround, but allows you to create as many questions as you want, without having them visible.&lt;br /&gt;
&lt;br /&gt;
This could also be applied for groups as well just by using the sid field in the &#039;&#039;lime_groups &#039;&#039;table.&lt;br /&gt;
&lt;br /&gt;
==Re-open a submitted answer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.71+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As an administrator you can re-open a submitted answer.&lt;br /&gt;
# Reset tokens invitation to not sent&lt;br /&gt;
# Reset answers to not completed&lt;br /&gt;
## &#039;&#039;&#039;release &amp;lt;= 1.72&#039;&#039;&#039;: In LS &amp;lt;= 1.72 you don&#039;t have the option to &amp;quot;Reset answers to not completed&amp;quot; that version 1.8 offers, so this would require the following workaround:&lt;br /&gt;
### export of tokens&lt;br /&gt;
### vvexport of answers&lt;br /&gt;
### deactivate/activate survey in order to erase answers&lt;br /&gt;
### import answers from VVimport but Add the &#039;import as not finalized answers&#039; option&lt;br /&gt;
### import tokens&lt;br /&gt;
## &#039;&#039;&#039;release &amp;gt;= 1.8&#039;&#039;&#039;:&lt;br /&gt;
### from the answer summary page, a new option can be used to reset all answers to a not submitted state&lt;br /&gt;
### from the tokens summary page, you can reset all tokens to &#039;not sent&#039; state&lt;br /&gt;
&lt;br /&gt;
Note that this &#039;&#039;&#039;&#039;&#039;will work only on non anonymous surveys with &amp;quot;Allow Persistence&amp;quot; option set&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Bypassing email check at registration==&lt;br /&gt;
&lt;br /&gt;
When you allow public registration to your survey Limesurvey developers have opted to put in place a certain level of protection from bots and spammers by placing a captcha and by forcing the users to go and check their emails to find the link associated with their tokens.&lt;br /&gt;
&lt;br /&gt;
Sometimes, however, this is a nuisance that actually force people to wait for the email when they would rather just take the survey and get on with things. Ideally it would be great if a token-based survey present the participant a short-text box (like a security question) asking at random one of the field in the registration form when the token is passed via URL (i will put this as feature request for the next edition!).&lt;br /&gt;
&lt;br /&gt;
In the meantime, there is a very easy workaround. The solution is to edit the register.php and add the following code around line 156 (where the code is rewriting the page with the message that the email has been sent):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a href=&#039;$publicurl/index.php?sid=$surveyid&amp;amp;token;=$newtoken&amp;amp;lang;=$baselang&#039;&amp;gt;Whatever you want to say&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I placed right on line 156 between the two line breaks. The code is simply creating a link to the survey embedding the token in the URL.&lt;br /&gt;
&lt;br /&gt;
NOTE that this is literally bypassing the safety currently in place, but the advantage is streamlining the steps for taking the survey with registration.&lt;br /&gt;
&lt;br /&gt;
==Used email and public registration==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with v1.8&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When you have a closed survey with public registration, currently LimeSurvey is not allowing a user to re-use the same email. This is a problem if the user has deleted the registration email without taking the survey. In the above workaround a user was allowed to take a survey by presenting a link straight after the registration; ideally they should be prompted with an additional security question and/or captcha (see bugtracker). In the meantime, this owrkaround allows you to from a link from the corresponding email and present it to the user.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Make sure you back up your register.php first!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Here the querystring has been modified to pull out the token as well as the email address and the error message has been changed to display the link to the survey for the existing token. &#039;&#039;&#039;Please also note that this forced change will not be reflected in the different languages!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Around line 75 find the corresponding 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;
//Check if this email already exists in token database&lt;br /&gt;
&lt;br /&gt;
$query = &amp;quot;SELECT email,token FROM {$dbprefix}tokens_$surveyid\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
. &amp;quot;WHERE email = &amp;quot;.db_quoteall(sanitize_email(returnglobal(&#039;register_email&#039;)));&lt;br /&gt;
&lt;br /&gt;
$result = $connect-&amp;gt;Execute($query) or safe_die ($query.&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;.$connect-&amp;gt;ErrorMsg());   //Checked&lt;br /&gt;
&lt;br /&gt;
if [[$result-&amp;gt;RecordCount(]] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   //transform in array of values&lt;br /&gt;
&lt;br /&gt;
   $row=$result-&amp;gt;FetchRow();&lt;br /&gt;
&lt;br /&gt;
   $register_errormsg=$clang-&amp;gt;gT(&amp;quot;The email you used has already been registered.&amp;quot;).&amp;quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;&amp;lt;a style=&#039;color:red;font-weight: bold;&#039; href=&#039;$publicurl/index.php?sid=$surveyid&amp;amp;token;=&amp;quot;.$row[&#039;token&#039;].&amp;quot;&amp;amp;lang;=$baselang&#039;&amp;gt;Click this link to take the survey now&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   include &amp;quot;index.php&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   exit;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HTTP-Refferer is not shown after a Redirect==&lt;br /&gt;
&lt;br /&gt;
There are different ways to redirect a page, just as HTTP-Redirect 301, meta http-equiv=&amp;quot;Refresh&amp;quot;, meta http-equiv=&amp;quot;Referrer&amp;quot;, link rel=&amp;amp;rdquo;canonical&amp;amp;rdquo; or JavaScript window.location. But all of them don&#039;t work correct in all Browsers when it comes up to the HTTP-Referer. The only working solution I found is with a bit strange JavaScript. You see the solution at [http://www.visionen.ch/umfrage/redirect.pdf]&lt;br /&gt;
&lt;br /&gt;
==Export graphic results to pdf==&lt;br /&gt;
&lt;br /&gt;
Note: Limesurvey can export statistics with graphs to pdf from version 1.86.&lt;br /&gt;
&lt;br /&gt;
Limesurvey is not yet able to export statistics to pdf. The following workaround is a solution to print your statistics (including graphs) to a pdf file with one page per question. You first will need to install a pdf printer (I use pdfcreator). Then you will need to modify Limesurvey as follows :&lt;br /&gt;
* open the common.php file&lt;br /&gt;
* after the line number 3615 (LS 1.80 build 6506) or 3641 (LS 1.80+ build 6601) or 3736 (LS 1.82+ build 6825) add the following line :&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;
$strAdminHeader.=&amp;quot;\t\t&amp;lt;link rel=\&amp;quot;stylesheet\&amp;quot; type=\&amp;quot;text/css\&amp;quot; href=\&amp;quot;styles/print.css\&amp;quot; media=\&amp;quot;print\&amp;quot; /&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* create a new file named print.css in the admin/styles folder and write the following code in it :&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;
@page {&lt;br /&gt;
&lt;br /&gt;
size: 21.0cm 29.7cm;&lt;br /&gt;
&lt;br /&gt;
margin: 1cm;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.statisticstable {&lt;br /&gt;
&lt;br /&gt;
page-break-after:always;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* visualize your stats with graphs from the admin panel then from your browser go to the file/print menu and select your pdf printer&lt;br /&gt;
* it prints your stats to a pdf file with one page per question&lt;/div&gt;</summary>
		<author><name>Rakete</name></author>
	</entry>
</feed>