Actions

Workarounds: Further solutions provided by LimeSurvey users

From LimeSurvey Manual

Revision as of 17:28, 3 October 2011 by Gskramer (talk | contribs)

Here you can find workarounds/solutions provided by Limesurvey users which do not deal with these workaround sections:

If you are looking for general troubleshooting please check our general FAQ and installation FAQ. If you can't find a solution for your problem please open a new thread at our forum or ask at our live chat.

Please keep in mind that the workarounds published here are no official Limesurvey extensions but solutions that other users created for themselves.
Therefore we can't give support for any solution on this page.
Please contact the users that, thankfully, shared their solutions with the community if you have any questions.

How to import survey responses from v1.00 into v1.5x (and later)

Tested with: LS >= 1.50

In LimeSurvey v1.50 it´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.

If you also need to import the responses, follow the next steps:

  1. Export your survey in v1.00
  2. Do a VV-Export in v1.00 (to save your responses)
  3. Import your survey from v1.00 into v1.5x via "Create or Import a New Survey" in the main Admin Panel
  4. Activate your imported survey
  5. Fill out your survey once, so that at least one response is in your database.
  6. Do a VV-Export in v1.5x
  7. Open both VV-Exports (v1.5x and v1.00); if you use Microsoft Excel do it via "Open New File" and "Import from Text-File" or "Import from external source - textfile" and choose "seperated" and "Unicode (UTF-8)"; choose
  8. Compare the file structure and you´ll see that there are two columns added (submitdate and startlanguage) and that all question codes changed.
  9. 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)
  10. Add the columns "submitdate" and "startlanguage" in your VV-Export v1.5x-File, right between "id" and "token"
  11. Save your file (in Microsoft Excel use Textfile - Tabstopp seperated). It´s necessary that your file after saving has the same format as before - Notice: it´s not a normal .csv-File.
  12. Import your file via VV-Import

Translate surveys without admin access

Tested with:

User "CasN" 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 (01735: Remote translating feature) where you can download them. You'll also find a short How-To there.

This is how it works:

Copy the scripts in the root of your survey directory and call starttrans.php like this starttrans.php?survey=12345

It will check the languages connected to the survey and also verify the labelsets used.

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.

Thanks CasN for sharing your solution with the community!

Create Question Pools

Tested with:

This workarounds was created by user "akky" and posted in the forum:

This is a simple solution to create question pools for Limesurvey. It will require access to the backend database. I'm not going to explain how to do this, as if you don't understand it, then you shouldn't really do it.

Basically 3 tables exist that we care about:

  • lime_surveys - id field = sid
  • lime_groups - id field = gid
  • lime_questions id field = qid

In order to show the questions correctly the id field from the lime_groups table exists in the lime_questions table. This then is used to create the parent/child relationship.

However, if you want to create a pool of questions all you need to do is to amend the gid field in the lime_questions table to a value that doesn't exist in the lime_groups 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.

It's a crude workaround, but allows you to create as many questions as you want, without having them visible.

This could also be applied for groups as well just by using the sid field in the lime_groups table.

Re-open a submitted answer

Tested with: 1.71+

As an administrator you can re-open a submitted answer.

  1. Reset tokens invitation to not sent
  2. Reset answers to not completed
    1. release <= 1.72: In LS <= 1.72 you don't have the option to "Reset answers to not completed" that version 1.8 offers, so this would require the following workaround:
      1. export of tokens
      2. vvexport of answers
      3. deactivate/activate survey in order to erase answers
      4. import answers from VVimport but Add the 'import as not finalized answers' option
      5. import tokens
    2. release >= 1.8:
      1. from the answer summary page, a new option can be used to reset all answers to a not submitted state
      2. from the tokens summary page, you can reset all tokens to 'not sent' state

Note that this will work only on non anonymous surveys with "Allow Persistence" option set.

Bypassing email check at registration

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.

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!).

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):

<a href='$publicurl/index.php?sid=$surveyid&token;=$newtoken⟨=$baselang'>Whatever you want to say</a>

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.

NOTE that this is literally bypassing the safety currently in place, but the advantage is streamlining the steps for taking the survey with registration.

Alternate Bypassing Email Check at Registration

For version 1.87, please add the following code on line 180 above the //PRINT COMPLETED PAGE in register.php.  This will take the user directly to the welcome page without any pauses in between and bypasses the user having to go to the email validation to start the survey.

header("Location: $publicurl/index.php?sid=$surveyid&token;=$newtoken");

- Zad Imam 04/20/2010

Used email and public registration

Tested with v1.8

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.

Make sure you back up your register.php first!

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. Please also note that this forced change will not be reflected in the different languages!

Around line 75 find the corresponding code:

//Check if this email already exists in token database

$query = "SELECT email,token FROM {$dbprefix}tokens_$surveyid\n"

. "WHERE email = ".db_quoteall(sanitize_email[['register_email']]);

$result = $connect->Execute($query) or safe_die ($query."<br />".$connect->ErrorMsg());   //Checked

if [[$result->RecordCount(]] > 0)

{

   //transform in array of values

   $row=$result->FetchRow();

   $register_errormsg=$clang->gT("The email you used has already been registered.")."<br><br>".

   "<a style='color:red;font-weight: bold;' href='$publicurl/index.php?sid=$surveyid&token;

       = ".$row['token']."&lang;=$baselang'>Click this link to take the survey now</a><br><br>";

   include "index.php";

   exit;

}

HTTP-Refferer is not shown after a Redirect

There are different ways to redirect a page, just as HTTP-Redirect 301, meta http-equiv="Refresh", meta http-equiv="Referrer", link rel=”canonical” or JavaScript window.location. But all of them don'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 [1]

Display of survey results from a single URL

For anyone interested - I've created a small hack/add-on to Version 1.86 (7697) that enables the display of survey results from a single URL.

( I didn't like the fact that the 'View Statistics' URL requires a user to first set Filter settings and then to click on 'View stats' )

INSTALLATION: unzip files in your 'admin' directory.

https://www.limesurvey.org/images/fbfiles/files/LimeSurvey_show_results_v1p1.zip

--

I'd recommend not overwriting your copy of admin/admin.php (in case it's changed since I edited it) The only change to this file is the addition of the following code from lines 291 to 295:

elseif ($action == 'results')

   {

     if($surrows['browse_response'] || $_SESSION['USER_RIGHT_SUPERADMIN'] == 1){

        include('show_results.php');

     } else { include('access_denied.php');}

   }

You're better off adding this code yourself. It simply adds an additional conditional redirect to the new show_results.php page if action=results is passed as a URL variable.

IN USE:

URL uses additional parameters to define new functionality:

http:/yoursite/limesurvey/admin/admin.php?action=results&comments=full&graphs&auto=1&sid=71533

'results' (instead of the usual 'statistics') turns on this add-on.

'comments=full' displays comments inline (ie on results page)

'=full' can be dropped so that questions type P (Multiple Options With Comments) will display a 'browse' button (if comments exist) instead of inline comments.

'graphs' forces the display of the graphs

- omitting this variable shows results without graphs.

'auto=1' forces auto-submission of the statistics form - allowing for a single click display.

- omitting this parameter directs you to the normal 'set Filter settings' page before then displaying the new results page.

'sid=71533 obviously your 'sid' needs to be a valid (activated) survey Id.

EXAMPLES:

http:/yoursite/limesurvey/admin/admin.php?action=results&comments&auto=1&sid=71533

Shows 'Browse' buttons instead of inline text for additional comments to P type questions and doesn't display graphs. (see http://screencast.com/t/YTZiYTY2M)

http:/yoursite/limesurvey/admin/admin.php?action=results&comments=full&graphs&auto=1&sid=71533

Shows inline text for additional comments to P type questions and display graphs. (see http://screencast.com/t/NmYyYmY5O)

NOTES:

show_results.php was tested on a survey using questions of type

  • P - Multiple Options With Comments
  • T - Long Free Text

I've added improvements that allow you to actually show the 'Long Free Text' - rather than having to use the 'Browse' button. I'm also hiding graphs for this question type (even if show graphs is enabled) because I personally think that the display of a piechart showing that the question has been answered (or not) is not what you actually need to see on a results page.

Secondly - I found that the additional 'Comments' for question type P - Multiple Options With Comments weren't actually showing up (you had to click the browse button next to 'export' at the top of the page). As previously explained, the 'comments' parameter in the URL allows you to either view these inline (on the page) or adds a new 'browse' button for each question with comments added. (see http://screencast.com/t/YTZiYTY2M)

Page should work fine with all other question types but obviously use at your peril!

--

scripts/statistics-auto.js add a few lines of code in the jQuery $(document).ready method.

Provide a preview-all-questions page for any survey

Sometimes people would like to be able to preview all questions in a survey before actually taking the survey - it gives them a chance to prepare their information in advance. While the Limesurvey admin tool lets you create a printable version of a survey, this is not really appropriate for end users, as it contains placeholders for token values, etc. So, for our installation I created a separate PHP script, which you can install on your server and provide for users. Further notes are in the body of the script:

<?php

/******

PreviewLimeSurvey.php

Displays an HTML page with a preview of all questions in the specified survey; multiple-choice and array questions are displayed with all possible responses listed out. Mandatory questions are displayed with "(* REQUIRED)" after the question text.

Usage: Pass the 5-digit survey ID, e.g.: http://{some_path}/PreviewLimeSurvey.php?sid=nnnnn

Preparation:

   - In the calls to mysql_connect() and mysql_select_db(), substitute the parameters for your own Limesurvey server and database

   - In the HTML part, modify styles and page title as desired

   - This code presumes your Limesurvey database tables use standard nomenclature: lime_questions, lime_answers, etc. If that is NOT the case, you will need to modify table names in the queries.

CAVEATS:

   - This does not handle ALL Limesurvey question types. The default behavior is to print just the text of each question. It then adds additional info for specific types that include lists of options, array tables, etc., but you may need to modify the code to handle all the types that you use.

   - It does NOT print boilerplate questions (type 'X'), because in our setup these would be irrelevant when someone just wants to preview the survey questions. You can change this by commenting out the clause "if ($row['type'] != 'X')"
*/

// Put the page parameters in globals

$mySID = $_GET['sid'];

// Preview questions and possible responses for the specified survey ID

function preview_survey($sid) {

   $dbh = mysql_connect('myHost', 'myLimesurveyDatabaseUsername', 'myLimesurveyDatabasePassword');

   mysql_select_db('myLimesurveyDatabaseName', $dbh);

   // Start by getting survey name from db, to display in title

   $result = mysql_query("SELECT surveyls_title FROM lime_surveys_languagesettings WHERE surveyls_survey_id={$sid}");

   $row = mysql_fetch_assoc($result);

   $output = "<h2>Survey Preview: {$row['surveyls_title']}</h2>";    // Initialize markup with heading showing survey name

   $output .= '<div style="margin:15px 0 15px 1em;width:30em;">Below are questions that will appear on your survey.</div>';

   $result = mysql_query("SELECT lq.qid, lq.sid, lq.gid, lq.lid, lq.type, lq.title, lq.question, lq.mandatory, lg.group_order FROM lime_questions AS lq, lime_groups AS lg WHERE lq.sid='{$sid}' AND lg.sid=lq.sid AND lq.gid=lg.gid ORDER BY lg.group_order ASC, question_order ASC");

   while ($row = mysql_fetch_assoc($result))

       {

       // For all questions *except* Boilerplate (type X), print out the main question text

       if ($row['type'] != 'X') {

           if ($row['mandatory'] == 'Y')

               $isMandatory = ' <span style="color:red;">(* REQUIRED)</span>';

           else

               $isMandatory = '';

           // Grab the question text and put in a <div>, first filtering it thru stripFinalBrk(); this strips out the final break tag that appears

           // in many of the questions, which can mess up our formatting (break tags INSIDE the question text are left alone)

           $output .= '<div class="qText">' . stripFinalBrk($row['question']) . $isMandatory . '</div>';

           // Get array of possible options: This will be empty for some question types

           $qOpts = mysql_query("SELECT answer FROM lime_answers WHERE qid={$row['qid']} ORDER BY code ASC");

           $numOpts = mysql_num_rows($qOpts);

           }

       switch ($row['type']) {        // Process output based on question type

           case 'Q':    // Multiple short text

           case 'P':

           case 'K':

           case 'L':

               $output .= '<ul style="margin:0;">';    // Begin tag for bulleted list of options

               // Populate an array of options listed for this question

               while ($rowOpts = mysql_fetch_assoc($qOpts))

                   $output .= '<li>' . $rowOpts['answer'] . '</li>';

               $output .= '</ul>';

               break;

           case ';':        // Mandatory multi-choice flex labels (tabular display)

               $output .= '<div style="margin-left:2em;"><table border="1" cellpadding="4"><tr>';

               // Get labels for columns and create top table row for output

               $output .= "<th> </th>";    // 1st column where row labels will go

               $qColumns = mysql_query("SELECT title FROM lime_labels WHERE lid={$row['lid']} ORDER BY sortorder ASC");

               $numColumns = mysql_num_rows($qColumns);

               while ($colOpts = mysql_fetch_assoc($qColumns)) {

                   $output .= "<th>{$colOpts['title']}</th>";

                   }

               $output .= "</tr>";

               //  Create one row per option. The row labels will be the $qOpts we already got. Use these for 1st column, fill others with blanks

               while ($rowOpts = mysql_fetch_assoc($qOpts)) {

                   $output .= "<tr><td>{$rowOpts['answer']}</td>";

                   for ($i=0; $i < $numColumns; $i++) {    // Fill in blank columns under the column heads output above

                       $output .= "<td> </td>";

                       }    // end $i

                   $output .= "</tr>";

                   }    // end while ($rowOpts)

               $output .= "</table></div>";

               break;

           case 'Z';    // Flexible drop-down/radio-button - user selections come from lime_labels; here, show all possible options

               $output .= '<ul style="margin:0;">';    // Begin tag for bulleted list of options

               $qLabels = mysql_query("SELECT title FROM lime_labels WHERE lid={$row['lid']}");

               while ($rowOpts = mysql_fetch_assoc($qLabels)) {

                   $output .= '<li>' . $rowOpts['title'] . '</li>';

                   }

               $output .= '</ul>';

               break;

           default:    // For any type not specified above, no further output after displaying the question text

               break;

           }    // END: switch ($row['type'])

       }    // End main loop thru survey questions (while ($row....)

   return ($output);

}

/******

   stripFinalBrk(): Test if string ends with a <br /> tag, and if so remove it; returns modified string.
*/

function stripFinalBrk($myString) {

   $yerString = strrev($myString);    // Reverse input string for testing

   // Check if *reversed* string begins with a <br /> tag (backwards) - if so, strip out starting characters and return the rest

   if (substr($yerString,0,6) == '>/ rb<')

       $yerString = substr($yerString,6);

   return(strrev($yerString));    // Reverse back for result

   }

?>



<html>

<head>

   <title>Limesurvey Preview Page</title>

   <style>

       body {

           font-family: Helvetica, Verdana, sans-serif;

           padding:1em 0 2em 1em;

           font-size:0.9em;

           }

       td, th {

           font-size:0.8em;

           }

       li {

           font-size:0.9em;

           }

       h2 {

           color:#00A;

           }

       div.qText {

           margin:1em 0 0.5em 0;

           padding:0.5em 0 0.2em 0;

           border-top: solid 1px #00a;

           /* border-bottom: solid 1px #00a; */

           }

   </style>

</head>

<body>

   <?php echo(preview_survey($mySID)); ?>

   <hr style="margin-top:15px;" />

</body>