array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Assessments"),'description'=>$clang->gT("Permission to create/view/update/delete assessments rules for a survey"),'img'=>'assessments'), // Checked
'quotas'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Quotas"),'description'=>$clang->gT("Permission to create/view/update/delete quota rules for a survey"),'img'=>'quota'), // Checked
'responses'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Responses"),'description'=>$clang->gT("Permission to create(data entry)/view/update/delete/import/export responses"),'img'=>'browse'),
'statistics'=>array('create'=>false,'read'=>true,'update'=>false,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Statistics"),'description'=>$clang->gT("Permission to view statistics"),'img'=>'statistics'), //Checked
'survey'=>array('create'=>false,'read'=>true,'update'=>false,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey deletion"),'description'=>$clang->gT("Permission to delete a survey"),'img'=>'delete'), //Checked
'surveyactivation'=>array('create'=>false,'read'=>false,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey activation"),'description'=>$clang->gT("Permission to activate/deactivate a survey"),'img'=>'activate_deactivate'), //Checked
'surveycontent'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Survey content"),'description'=>$clang->gT("Permission to create/view/update/delete/import/export the questions, groups, answers & conditions of a survey"),'img'=>'add'),
'surveylocale'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey locale settings"),'description'=>$clang->gT("Permission to view/update the survey locale settings"),'img'=>'edit'),
'surveysecurity'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey security"),'description'=>$clang->gT("Permission to modify survey security settings"),'img'=>'survey_security'),
'surveysettings'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey settings"),'description'=>$clang->gT("Permission to view/update the survey settings including token table creation"),'img'=>'survey_settings'),
'tokens'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Tokens"),'description'=>$clang->gT("Permission to create/update/delete/import/export token entries"),'img'=>'tokens'),
'translations'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Quick translation"),'description'=>$clang->gT("Permission to view & update the translations using the quick-translation feature"),'img'=>'translate')
);
uasort($aPermissions,"aComparePermission");
return $aPermissions;
}
/**
* Simple function to sort the permissions by title
*
* @param mixed $aPermissionA Permission A to compare
* @param mixed $aPermissionB Permission B to compare
*/
function aComparePermission($aPermissionA,$aPermissionB)
{
if($aPermissionA['title'] >$aPermissionB['title']) {
return 1;
}
else {
return -1;
}
}
/**
* getqtypelist() Returns list of question types available in LimeSurvey. Edit this if you are adding a new
* question type
*
* @global string $publicurl
* @global string $sourcefrom
*
* @param string $SelectedCode Value of the Question Type (defaults to "T")
* @param string $ReturnType Type of output from this function (defaults to selector)
*
* @return depending on $ReturnType param, returns a straight "array" of question types, or an list
*
* Explanation of questiontype array:
*
* description : Question description
* subquestions : 0= Does not support subquestions x=Number of subquestion scales
* answerscales : 0= Does not need answers x=Number of answer scales (usually 1, but e.g. for dual scale question set to 2)
* assessable : 0=Does not support assessment values when editing answerd 1=Support assessment values
*/
function getqtypelist($SelectedCode = "T", $ReturnType = "selector")
{
global $publicurl;
global $sourcefrom, $clang;
if (!isset($clang))
{
$clang = new limesurvey_lang("en");
}
$group['Arrays'] = $clang->gT('Arrays');
$group['MaskQuestions'] = $clang->gT("Mask questions");
$group['SinChoiceQues'] = $clang->gT("Single choice questions");
$group['MulChoiceQues'] = $clang->gT("Multiple choice questions");
$group['TextQuestions'] = $clang->gT("Text questions");
$qtypes = array(
"1"=>array('description'=>$clang->gT("Array dual scale"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'assessable'=>1,
'hasdefaultvalues'=>0,
'answerscales'=>2),
"5"=>array('description'=>$clang->gT("5 Point Choice"),
'group'=>$group['SinChoiceQues'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"A"=>array('description'=>$clang->gT("Array (5 Point Choice)"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>0),
"B"=>array('description'=>$clang->gT("Array (10 Point Choice)"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>0),
"C"=>array('description'=>$clang->gT("Array (Yes/No/Uncertain)"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>0),
"D"=>array('description'=>$clang->gT("Date"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"E"=>array('description'=>$clang->gT("Array (Increase/Same/Decrease)"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>0),
"F"=>array('description'=>$clang->gT("Array"),
'group'=>$group['Arrays'],
'subquestions'=>1,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>1),
"G"=>array('description'=>$clang->gT("Gender"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"H"=>array('description'=>$clang->gT("Array by column"),
'group'=>$group['Arrays'],
'hasdefaultvalues'=>0,
'subquestions'=>1,
'assessable'=>1,
'answerscales'=>1),
"I"=>array('description'=>$clang->gT("Language Switch"),
'group'=>$group['MaskQuestions'],
'hasdefaultvalues'=>0,
'subquestions'=>0,
'assessable'=>0,
'answerscales'=>0),
"K"=>array('description'=>$clang->gT("Multiple Numerical Input"),
'group'=>$group['MaskQuestions'],
'hasdefaultvalues'=>1,
'subquestions'=>1,
'assessable'=>1,
'answerscales'=>0),
"L"=>array('description'=>$clang->gT("List (Radio)"),
'group'=>$group['SinChoiceQues'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>1,
'answerscales'=>1),
"M"=>array('description'=>$clang->gT("Multiple choice"),
'group'=>$group['MulChoiceQues'],
'subquestions'=>1,
'hasdefaultvalues'=>1,
'assessable'=>1,
'answerscales'=>0),
"N"=>array('description'=>$clang->gT("Numerical Input"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"O"=>array('description'=>$clang->gT("List with comment"),
'group'=>$group['SinChoiceQues'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>1,
'answerscales'=>1),
"P"=>array('description'=>$clang->gT("Multiple choice with comments"),
'group'=>$group['MulChoiceQues'],
'subquestions'=>1,
'hasdefaultvalues'=>1,
'assessable'=>1,
'answerscales'=>0),
"Q"=>array('description'=>$clang->gT("Multiple Short Text"),
'group'=>$group['TextQuestions'],
'subquestions'=>1,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"R"=>array('description'=>$clang->gT("Ranking"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>1),
"S"=>array('description'=>$clang->gT("Short Free Text"),
'group'=>$group['TextQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"T"=>array('description'=>$clang->gT("Long Free Text"),
'group'=>$group['TextQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"U"=>array('description'=>$clang->gT("Huge Free Text"),
'group'=>$group['TextQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>0,
'answerscales'=>0),
"X"=>array('description'=>$clang->gT("Text display"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"Y"=>array('description'=>$clang->gT("Yes/No"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"!"=>array('description'=>$clang->gT("List (Dropdown)"),
'group'=>$group['SinChoiceQues'],
'subquestions'=>0,
'hasdefaultvalues'=>1,
'assessable'=>1,
'answerscales'=>1),
":"=>array('description'=>$clang->gT("Array (Numbers)"),
'group'=>$group['Arrays'],
'subquestions'=>2,
'hasdefaultvalues'=>0,
'assessable'=>1,
'answerscales'=>0),
";"=>array('description'=>$clang->gT("Array (Texts)"),
'group'=>$group['Arrays'],
'subquestions'=>2,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"|"=>array('description'=>$clang->gT("File upload"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
"*"=>array('description'=>$clang->gT("Equation"),
'group'=>$group['MaskQuestions'],
'subquestions'=>0,
'hasdefaultvalues'=>0,
'assessable'=>0,
'answerscales'=>0),
);
asort($qtypes);
if ($ReturnType == "array") {return $qtypes;}
if ($ReturnType == "group"){
foreach($qtypes as $qkey=>$qtype){
$newqType[$qtype['group']][$qkey] = $qtype;
}
$qtypeselecter = "";
foreach($newqType as $group=>$members)
{
$qtypeselecter .= '";
}
if ($expiredsurveys!='')
{
$surveyselecter .= "";
}
if ($inactivesurveys!='')
{
$surveyselecter .= "";
}
if (!isset($svexist))
{
$surveyselecter = "\n".$surveyselecter;
} else
{
if ($returnwithouturl===false)
{
$surveyselecter = "\n".$surveyselecter;
} else
{
$surveyselecter = "\n".$surveyselecter;
}
}
return $surveyselecter;
}
/**
* getQuestions() queries the database for an list of all questions matching the current survey and group id
*
* @global string $surveyid
* @global string $gid
* @global string $selectedqid
*
* @return This string is returned containing formatted list of questions in the current survey and group
*/
function getQuestions($surveyid,$gid,$selectedqid)
{
global $scriptname, $clang;
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$qquery = 'SELECT * FROM '.db_table_name('questions')." WHERE sid=$surveyid AND gid=$gid AND language='{$s_lang}' and parent_qid=0 order by question_order";
$qresult = db_execute_assoc($qquery); //checked
$qrows = $qresult->GetRows();
if (!isset($questionselecter)) {$questionselecter="";}
foreach ($qrows as $qrow)
{
$qrow['title'] = strip_tags($qrow['title']);
$questionselecter .= "\n".$questionselecter;
}
return $questionselecter;
}
/**
* getGidPrevious() returns the Gid of the group prior to the current active group
*
* @param string $surveyid
* @param string $gid
*
* @return The Gid of the previous group
*/
function getGidPrevious($surveyid, $gid)
{
global $scriptname, $clang;
if (!$surveyid) {$surveyid=returnglobal('sid');}
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$gquery = "SELECT gid FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' ORDER BY group_order";
$qresult = db_execute_assoc($gquery); //checked
$qrows = $qresult->GetRows();
$i = 0;
$iPrev = -1;
foreach ($qrows as $qrow)
{
if ($gid == $qrow['gid']) {$iPrev = $i - 1;}
$i += 1;
}
if ($iPrev >= 0) {$GidPrev = $qrows[$iPrev]['gid'];}
else {$GidPrev = "";}
return $GidPrev;
}
/**
* getQidPrevious() returns the Qid of the question prior to the current active question
*
* @param string $surveyid
* @param string $gid
* @param string $qid
*
* @return This Qid of the previous question
*/
function getQidPrevious($surveyid, $gid, $qid)
{
global $scriptname, $clang;
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$qquery = 'SELECT * FROM '.db_table_name('questions')." WHERE sid=$surveyid AND gid=$gid AND language='{$s_lang}' and parent_qid=0 order by question_order";
$qresult = db_execute_assoc($qquery); //checked
$qrows = $qresult->GetRows();
$i = 0;
$iPrev = -1;
foreach ($qrows as $qrow)
{
if ($qid == $qrow['qid']) {$iPrev = $i - 1;}
$i += 1;
}
if ($iPrev >= 0) {$QidPrev = $qrows[$iPrev]['qid'];}
else {$QidPrev = "";}
return $QidPrev;
}
/**
* getGidNext() returns the Gid of the group next to the current active group
*
* @param string $surveyid
* @param string $gid
*
* @return The Gid of the next group
*/
function getGidNext($surveyid, $gid)
{
global $scriptname, $clang;
if (!$surveyid) {$surveyid=returnglobal('sid');}
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$gquery = "SELECT gid FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' ORDER BY group_order";
$qresult = db_execute_assoc($gquery); //checked
$qrows = $qresult->GetRows();
$GidNext="";
$i = 0;
$iNext = 1;
foreach ($qrows as $qrow)
{
if ($gid == $qrow['gid']) {$iNext = $i + 1;}
$i += 1;
}
if ($iNext < count($qrows)) {$GidNext = $qrows[$iNext]['gid'];}
else {$GidNext = "";}
return $GidNext;
}
/**
* getQidNext() returns the Qid of the question prior to the current active question
*
* @param string $surveyid
* @param string $gid
* @param string $qid
*
* @return This Qid of the previous question
*/
function getQidNext($surveyid, $gid, $qid)
{
global $scriptname, $clang;
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$qquery = 'SELECT qid FROM '.db_table_name('questions')." WHERE sid=$surveyid AND gid=$gid AND language='{$s_lang}' and parent_qid=0 order by question_order";
$qresult = db_execute_assoc($qquery); //checked
$qrows = $qresult->GetRows();
$i = 0;
$iNext = 1;
foreach ($qrows as $qrow)
{
if ($qid == $qrow['qid']) {$iNext = $i + 1;}
$i += 1;
}
if ($iNext < count($qrows)) {$QidNext = $qrows[$iNext]['qid'];}
else {$QidNext = "";}
return $QidNext;
}
/**
* This function calculates how much space is actually used by all files uploaded
* using the File Upload question type
*
* @returns integer Actual space used in MB
*/
function fCalculateTotalFileUploadUsage(){
global $uploaddir;
$sQuery="select sid from ".db_table_name('surveys');
$oResult = db_execute_assoc($sQuery); //checked
$aRows = $oResult->GetRows();
$iTotalSize=0.0;
foreach ($aRows as $aRow)
{
$sFilesPath=$uploaddir.'/surveys/'.$aRow['sid'].'/files';
if (file_exists($sFilesPath))
{
$iTotalSize+=(float)iGetDirectorySize($sFilesPath);
}
}
return (float)$iTotalSize/1024/1024;
}
function iGetDirectorySize($directory) {
$size = 0;
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file){
$size+=$file->getSize();
}
return $size;
}
/**
* Gets number of groups inside a particular survey
*
* @param string $surveyid
* @param mixed $lang
*/
function getGroupSum($surveyid, $lang)
{
global $surveyid,$dbprefix ;
$sumquery3 = "SELECT * FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='".$lang."'"; //Getting a count of questions for this survey
$sumresult3 = db_execute_assoc($sumquery3); //Checked
$groupscount = $sumresult3->RecordCount();
return $groupscount ;
}
/**
* Gets number of questions inside a particular group
*
* @param string $surveyid
* @param mixed $groupid
*/
function getQuestionSum($surveyid, $groupid)
{
global $surveyid,$dbprefix ;
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$sumquery3 = "SELECT * FROM ".db_table_name('questions')." WHERE gid=$groupid and sid=$surveyid AND language='{$s_lang}'"; //Getting a count of questions for this survey
$sumresult3 = db_execute_assoc($sumquery3); //Checked
$questionscount = $sumresult3->RecordCount();
return $questionscount ;
}
/**
* getMaxgrouporder($surveyid) queries the database for the maximum sortorder of a group and returns the next higher one.
*
* @param mixed $surveyid
* @global string $surveyid
*/
function getMaxgrouporder($surveyid)
{
global $surveyid, $connect ;
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$max_sql = "SELECT max( group_order ) AS max FROM ".db_table_name('groups')." WHERE sid =$surveyid AND language='{$s_lang}'" ;
$current_max = $connect->GetOne($max_sql) ;
if(is_null($current_max))
{
return "0" ;
}
else return ++$current_max ;
}
/**
* getGroupOrder($surveyid,$gid) queries the database for the sortorder of a group.
*
* @param mixed $surveyid
* @param mixed $gid
* @return mixed
*/
function getGroupOrder($surveyid,$gid)
{
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$grporder_sql = "SELECT group_order FROM ".db_table_name('groups')." WHERE sid =$surveyid AND language='{$s_lang}' AND gid=$gid" ;
$grporder_result =db_execute_assoc($grporder_sql); //Checked
$grporder_row = $grporder_result->FetchRow() ;
$group_order = $grporder_row['group_order'];
if($group_order=="")
{
return "0" ;
}
else return $group_order ;
}
/**
* getMaxquestionorder($gid) queries the database for the maximum sortorder of a question.
*
* @global string $surveyid
*/
function getMaxquestionorder($gid)
{
global $surveyid ;
$gid=sanitize_int($gid);
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$max_sql = "SELECT max( question_order ) AS max FROM ".db_table_name('questions')." WHERE gid='$gid' AND language='$s_lang'";
$max_result =db_execute_assoc($max_sql) ; //Checked
$maxrow = $max_result->FetchRow() ;
$current_max = $maxrow['max'];
if($current_max=="")
{
return "0" ;
}
else return $current_max ;
}
/**
* question_class() returns a class name for a given question type to allow custom styling for each question type.
*
* @param string $input containing unique character representing each question type.
* @return string containing the class name for a given question type.
*/
function question_class($input)
{
switch($input)
{ // I think this is a bad solution to adding classes to question
// DIVs but I can't think of a better solution. (eric_t_cruiser)
case 'X': return 'boilerplate'; // BOILERPLATE QUESTION
case '5': return 'choice-5-pt-radio'; // 5 POINT CHOICE radio-buttons
case 'D': return 'date'; // DATE
// case 'Z': return 'list-radio-flexible'; // LIST Flexible radio-button
case 'L': return 'list-radio'; // LIST radio-button
// case 'W': return 'list-dropdown-flexible'; // LIST drop-down (flexible label)
case '!': return 'list-dropdown'; // List - dropdown
case 'O': return 'list-with-comment'; // LIST radio-button + textarea
case 'R': return 'ranking'; // RANKING STYLE
case 'M': return 'multiple-opt'; // Multiple choice checkbox
case 'I': return 'language'; // Language Question
case 'P': return 'multiple-opt-comments'; // Multiple choice with comments checkbox + text
case 'Q': return 'multiple-short-txt'; // TEXT
case 'K': return 'numeric-multi'; // MULTIPLE NUMERICAL QUESTION
case 'N': return 'numeric'; // NUMERICAL QUESTION TYPE
case 'S': return 'text-short'; // SHORT FREE TEXT
case 'T': return 'text-long'; // LONG FREE TEXT
case 'U': return 'text-huge'; // HUGE FREE TEXT
case 'Y': return 'yes-no'; // YES/NO radio-buttons
case 'G': return 'gender'; // GENDER drop-down list
case 'A': return 'array-5-pt'; // ARRAY (5 POINT CHOICE) radio-buttons
case 'B': return 'array-10-pt'; // ARRAY (10 POINT CHOICE) radio-buttons
case 'C': return 'array-yes-uncertain-no'; // ARRAY (YES/UNCERTAIN/NO) radio-buttons
case 'E': return 'array-increase-same-decrease'; // ARRAY (Increase/Same/Decrease) radio-buttons
case 'F': return 'array-flexible-row'; // ARRAY (Flexible) - Row Format
case 'H': return 'array-flexible-column'; // ARRAY (Flexible) - Column Format
// case '^': return 'slider'; // SLIDER CONTROL
case ':': return 'array-multi-flexi'; // ARRAY (Multi Flexi) 1 to 10
case ";": return 'array-multi-flexi-text';
case "1": return 'array-flexible-duel-scale'; // Array dual scale
case "*": return 'equation'; // Equation
default: return 'generic_question'; // Should have a default fallback
};
};
function setup_columns($columns, $answer_count)
{
/**
* setup_columns() defines all the html tags to be wrapped around
* various list type answers.
*
* @param integer $columns - the number of columns, usually supplied by $dcols
* @param integer $answer_count - the number of answers to a question, usually supplied by $anscount
* @return array with all the various opening and closing tags to generate a set of columns.
*
* It returns an array with the following items:
* $wrapper['whole-start'] = Opening wrapper for the whole list
* $wrapper['whole-end'] = closing wrapper for the whole list
* $wrapper['col-devide'] = normal column devider
* $wrapper['col-devide-last'] = the last column devider (to allow
* for different styling of the last
* column
* $wrapper['item-start'] = opening wrapper tag for individual
* option
* $wrapper['item-start-other'] = opening wrapper tag for other
* option
* $wrapper['item-end'] = closing wrapper tag for individual
* option
* $wrapper['maxrows'] = maximum number of rows in each
* column
* $wrapper['cols'] = Number of columns to be inserted
* (and checked against)
*
* It also expect the global parameter $column_style
* initialised at the end of config-defaults.php or from within config.php
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Columns are a problem.
* Really there is no perfect solution to columns at the moment.
*
* - Using Tables is problematic semanticly.
* - Using inline or float to create columns, causes the answers
* flows horizontally, not vertically which is not ideal visually.
* - Using CSS3 columns is also a problem because of browser support
* and also because if you have answeres split across two or more
* lines, and those answeres happen to fall at the bottom of a
* column, the answer might be split across columns as well as
* lines.
* - Using nested unordered list with the first level of
s
* floated is the same as using tables and so is bad semantically
* for the same reason tables are bad.
* - Breaking the unordered lists into consecutive floated unordered
* lists is not great semantically but probably not as bad as
* using tables.
*
* Because I haven't been able to decide which option is the least
* bad, I have handed over that responsibility to the admin who sets
* LimeSurvey up on their server.
*
* There are four options:
* 'css' using one of the various CSS only methods for
* rendering columns.
* (Check the CSS file for your chosen template to see
* how columns are defined.)
* 'ul' using multiple floated unordered lists. (DEFAULT)
* 'table' using conventional tables based layout.
* NULL blocks the use of columns
*
* 'ul' is the default because it's the best possible compromise
* between semantic markup and visual layout.
*/
global $column_style;
if ( !in_array($column_style,array('css','ul','table')) && !is_null($column_style) )
{
$column_style = 'ul';
};
/*
if(defined('PRINT_TEMPLATE')) // This forces tables based columns for printablesurvey
{
$colstyle = 'table';
};
*/
if($columns < 2)
{
$column_style = null;
$columns = 1;
}
if(($columns > $answer_count) && $answer_count>0)
{
$columns = $answer_count;
};
if ($answer_count>0 && $columns>0)
{
$columns = ceil($answer_count/ceil($answer_count/$columns)); // # of columns is # of answers divided by # of rows (all rounded up)
}
$class_first = '';
if($columns > 1 && !is_null($column_style))
{
if($column_style == 'ul')
{
$ul = '-ul';
}
else
{
$ul = '';
}
$class_first = ' class="cols-'.$columns . $ul.' first"';
$class = ' class="cols-'.$columns . $ul.'"';
$class_last_ul = ' class="cols-'.$columns . $ul.' last"';
$class_last_table = ' class="cols-'.$columns.' last"';
}
else
{
$class = '';
$class_last_ul = '';
$class_last_table = '';
};
$wrapper = array(
'whole-start' => "\n
\n";
};
return $wrapper;
};
function alternation($alternate = '' , $type = 'col')
{
/**
* alternation() Returns a class identifyer for alternating between
* two options. Used to style alternate elements differently. creates
* or alternates between the odd string and the even string used in
* as column and row classes for array type questions.
*
* @param string $alternate = '' (empty) (default) , 'array2' , 'array1' , 'odd' , 'even'
* @param string $type = 'col' (default) or 'row'
*
* @return string representing either the first alternation or the opposite alternation to the one supplied..
*/
/*
// The following allows type to be left blank for row in subsequent
// function calls.
// It has been left out because 'row' must be defined the first time
// alternation() is called. Since it is only ever written once for each
// while statement within a function, 'row' is always defined.
if(!empty($alternate) && $type != 'row')
{ if($alternate == ('array2' || 'array1'))
{
$type = 'row';
};
};
// It has been left in case it becomes useful but probably should be
// removed.
*/
if($type == 'row')
{
$odd = 'array2'; // should be row_odd
$even = 'array1'; // should be row_even
}
else
{
$odd = 'odd'; // should be col_odd
$even = 'even'; // should be col_even
};
if($alternate == $odd)
{
$alternate = $even;
}
else
{
$alternate = $odd;
};
return $alternate;
}
/**
* longest_string() returns the length of the longest string past to it.
* @peram string $new_string
* @peram integer $longest_length length of the (previously) longest string passed to it.
* @return integer representing the length of the longest string passed (updated if $new_string was longer than $longest_length)
*
* usage should look like this: $longest_length = longest_string( $new_string , $longest_length );
*
*/
function longest_string( $new_string , $longest_length )
{
if($longest_length < strlen(trim(strip_tags($new_string))))
{
$longest_length = strlen(trim(strip_tags($new_string)));
};
return $longest_length;
};
/**
* getNotificationlist() returns different options for notifications
*
* @param string $notificationcode - the currently selected one
*
* @return This string is returned containing formatted list of notification methods for current survey
*/
function getNotificationlist($notificationcode)
{
global $clang;
$ntypes = array(
"0"=>$clang->gT("No email notification"),
"1"=>$clang->gT("Basic email notification"),
"2"=>$clang->gT("Detailed email notification with result codes")
);
if (!isset($ntypeselector)) {$ntypeselector="";}
foreach($ntypes as $ntcode=>$ntdescription)
{
$ntypeselector .= " formatted list of groups to current survey
*/
function getgrouplist($gid)
{
global $surveyid, $dbprefix, $scriptname, $connect, $clang;
$groupselecter="";
$gid=sanitize_int($gid);
$surveyid=sanitize_int($surveyid);
if (!$surveyid) {$surveyid=returnglobal('sid');}
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$gidquery = "SELECT gid, group_name FROM ".db_table_name('groups')." WHERE sid='{$surveyid}' AND language='{$s_lang}' ORDER BY group_order";
$gidresult = db_execute_num($gidquery) or safe_die("Couldn't get group list in common.php $gidquery ".$connect->ErrorMsg()); //Checked
while($gv = $gidresult->FetchRow())
{
$groupselecter .= "\n".$groupselecter;}
else {$groupselecter .= "\n";}
}
return $groupselecter;
}
function getgrouplist2($gid)
{
global $surveyid, $dbprefix, $connect, $clang;
$groupselecter = "";
if (!$surveyid) {$surveyid=returnglobal('sid');}
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$gidquery = "SELECT gid, group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' ORDER BY group_order";
$gidresult = db_execute_num($gidquery) or safe_die("Plain old did not work!"); //Checked
while ($gv = $gidresult->FetchRow())
{
$groupselecter .= "\n".$groupselecter;}
else {$groupselecter .= "\n";}
}
return $groupselecter;
}
function getgrouplist3($gid)
{
global $surveyid, $dbprefix;
if (!$surveyid) {$surveyid=returnglobal('sid');}
$groupselecter = "";
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
$gidquery = "SELECT gid, group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' ORDER BY group_order";
$gidresult = db_execute_num($gidquery) or safe_die("Plain old did not work!"); //Checked
while ($gv = $gidresult->FetchRow())
{
$groupselecter .= "\n".$groupselecter;}
else {$groupselecter .= "\n";}
}
return $groupselecter;
}
function getuserlist($outputformat='fullinfoarray')
{
global $dbprefix, $connect, $databasetype;
global $usercontrolSameGroupPolicy;
if (isset($_SESSION['loginID']))
{
$myuid=sanitize_int($_SESSION['loginID']);
}
if ($_SESSION['USER_RIGHT_SUPERADMIN'] != 1 && isset($usercontrolSameGroupPolicy) &&
$usercontrolSameGroupPolicy == true)
{
if (isset($myuid))
{
// List users from same group as me + all my childs
// a subselect is used here because MSSQL does not like to group by text
// also Postgres does like this one better
$uquery = " SELECT * FROM ".db_table_name('users')." where uid in
(SELECT u.uid FROM ".db_table_name('users')." AS u,
".db_table_name('user_in_groups')." AS ga ,".db_table_name('user_in_groups')." AS gb
WHERE u.uid=$myuid
OR (ga.ugid=gb.ugid AND ( (gb.uid=$myuid AND u.uid=ga.uid) OR (u.parent_id=$myuid) ) )
GROUP BY u.uid)";
}
else
{
return Array(); // Or die maybe
}
}
else
{
$uquery = "SELECT * FROM ".db_table_name('users')." ORDER BY uid";
}
$uresult = db_execute_assoc($uquery); //Checked
if ($uresult->RecordCount()==0)
//user is not in a group and usercontrolSameGroupPolicy is activated - at least show his own userinfo
{
$uquery = "SELECT u.* FROM ".db_table_name('users')." AS u WHERE u.uid=".$myuid;
$uresult = db_execute_assoc($uquery);//Checked
}
$userlist = array();
$userlist[0] = "Reserved for logged in user";
while ($srow = $uresult->FetchRow())
{
if ($outputformat != 'onlyuidarray')
{
if ($srow['uid'] != $_SESSION['loginID'])
{
$userlist[] = array("user"=>$srow['users_name'], "uid"=>$srow['uid'], "email"=>$srow['email'], "password"=>$srow['password'], "full_name"=>$srow['full_name'], "parent_id"=>$srow['parent_id'], "create_survey"=>$srow['create_survey'], "configurator"=>$srow['configurator'], "create_user"=>$srow['create_user'], "delete_user"=>$srow['delete_user'], "superadmin"=>$srow['superadmin'], "manage_template"=>$srow['manage_template'], "manage_label"=>$srow['manage_label']); //added by Dennis modified by Moses
}
else
{
$userlist[0] = array("user"=>$srow['users_name'], "uid"=>$srow['uid'], "email"=>$srow['email'], "password"=>$srow['password'], "full_name"=>$srow['full_name'], "parent_id"=>$srow['parent_id'], "create_survey"=>$srow['create_survey'], "configurator"=>$srow['configurator'], "create_user"=>$srow['create_user'], "delete_user"=>$srow['delete_user'], "superadmin"=>$srow['superadmin'], "manage_template"=>$srow['manage_template'], "manage_label"=>$srow['manage_label']);
}
}
else
{
if ($srow['uid'] != $_SESSION['loginID'])
{
$userlist[] = $srow['uid'];
}
else
{
$userlist[0] = $srow['uid'];
}
}
}
return $userlist;
}
/**
* Gets all survey infos in one big array including the language specific settings
*
* @param string $surveyid The survey ID
* @param string $languagecode The language code - if not given the base language of the particular survey is used
* @return array Returns array with survey info or false, if survey does not exist
*/
function getSurveyInfo($surveyid, $languagecode='')
{
global $dbprefix, $siteadminname, $siteadminemail, $connect, $languagechanger;
$surveyid=sanitize_int($surveyid);
$languagecode=sanitize_languagecode($languagecode);
$thissurvey=false;
// if no language code is set then get the base language one
if (!isset($languagecode) || $languagecode=='')
{
$languagecode=GetBaseLanguageFromSurveyID($surveyid);;
}
$query="SELECT * FROM ".db_table_name('surveys').",".db_table_name('surveys_languagesettings')." WHERE sid=$surveyid and surveyls_survey_id=$surveyid and surveyls_language='$languagecode'";
$result=db_execute_assoc($query) or safe_die ("Couldn't access survey settings $query ".$connect->ErrorMsg()); //Checked
while ($row=$result->FetchRow())
{
$thissurvey=$row;
// now create some stupid array translations - needed for backward compatibility
// Newly added surveysettings don't have to be added specifically - these will be available by field name automatically
$thissurvey['name']=$thissurvey['surveyls_title'];
$thissurvey['description']=$thissurvey['surveyls_description'];
$thissurvey['welcome']=$thissurvey['surveyls_welcometext'];
$thissurvey['templatedir']=$thissurvey['template'];
$thissurvey['adminname']=$thissurvey['admin'];
$thissurvey['tablename']=$dbprefix.'survey_'.$thissurvey['sid'];
$thissurvey['urldescrip']=$thissurvey['surveyls_urldescription'];
$thissurvey['url']=$thissurvey['surveyls_url'];
$thissurvey['expiry']=$thissurvey['expires'];
$thissurvey['email_invite_subj']=$thissurvey['surveyls_email_invite_subj'];
$thissurvey['email_invite']=$thissurvey['surveyls_email_invite'];
$thissurvey['email_remind_subj']=$thissurvey['surveyls_email_remind_subj'];
$thissurvey['email_remind']=$thissurvey['surveyls_email_remind'];
$thissurvey['email_confirm_subj']=$thissurvey['surveyls_email_confirm_subj'];
$thissurvey['email_confirm']=$thissurvey['surveyls_email_confirm'];
$thissurvey['email_register_subj']=$thissurvey['surveyls_email_register_subj'];
$thissurvey['email_register']=$thissurvey['surveyls_email_register'];
if (!isset($thissurvey['adminname'])) {$thissurvey['adminname']=$siteadminname;}
if (!isset($thissurvey['adminemail'])) {$thissurvey['adminemail']=$siteadminemail;}
if (!isset($thissurvey['urldescrip']) ||
$thissurvey['urldescrip'] == '' ) {$thissurvey['urldescrip']=$thissurvey['surveyls_url'];}
$thissurvey['passthrulabel']=isset($_SESSION['passthrulabel']) ? $_SESSION['passthrulabel'] : "";
$thissurvey['passthruvalue']=isset($_SESSION['passthruvalue']) ? $_SESSION['passthruvalue'] : "";
}
if (!(isset($languagechanger) && strlen($languagechanger) > 0) && function_exists('makelanguagechanger')) {
$languagechanger = makelanguagechanger();
}
return $thissurvey;
}
function getlabelsets($languages=null)
// Returns a list with label sets
// if the $languages paramter is provided then only labelset containing all of the languages in the paramter are provided
{
global $dbprefix, $connect, $surveyid;
if ($languages){
$languages=sanitize_languagecodeS($languages);
$languagesarray=explode(' ',trim($languages));
}
$query = "SELECT ".db_table_name('labelsets').".lid as lid, label_name FROM ".db_table_name('labelsets');
if ($languages){
$query .=" where ";
foreach ($languagesarray as $item)
{
$query .=" ((languages like '% $item %') or (languages='$item') or (languages like '% $item') or (languages like '$item %')) and ";
}
$query .=" 1=1 ";
}
$query .=" order by label_name";
$result = db_execute_assoc($query) or safe_die ("Couldn't get list of label sets $query ".$connect->ErrorMsg()); //Checked
$labelsets=array();
while ($row=$result->FetchRow())
{
$labelsets[] = array($row['lid'], $row['label_name']);
}
return $labelsets;
}
/**
* Compares two elements from an array (passed by the usort function)
* and returns -1, 0 or 1 depending on the result of the comparison of
* the sort order of the group_order and question_order field
*
* @param mixed $a
* @param mixed $b
* @return int
*/
function GroupOrderThenQuestionOrder($a, $b)
{
if (isset($a['group_order']) && isset($b['group_order']))
{
$GroupResult = strnatcasecmp($a['group_order'], $b['group_order']);
}
else
{
$GroupResult = "";
}
if ($GroupResult == 0)
{
$TitleResult = strnatcasecmp($a["question_order"], $b["question_order"]);
return $TitleResult;
}
return $GroupResult;
}
function StandardSort($a, $b)
{
return strnatcasecmp($a, $b);
}
function fixsortorderAnswers($qid) //Function rewrites the sortorder for a group of answers
{
global $dbprefix, $connect, $surveyid;
$qid=sanitize_int($qid);
$baselang = GetBaseLanguageFromSurveyID($surveyid);
$cdresult = db_execute_num("SELECT qid, code, sortorder FROM ".db_table_name('answers')." WHERE qid={$qid} and language='{$baselang}' ORDER BY sortorder"); //Checked
$position=0;
while ($cdrow=$cdresult->FetchRow())
{
$cd2query="UPDATE ".db_table_name('answers')." SET sortorder={$position} WHERE qid={$cdrow[0]} AND code='{$cdrow[1]}' AND sortorder={$cdrow[2]} ";
$cd2result=$connect->Execute($cd2query) or safe_die ("Couldn't update sortorder $cd2query ".$connect->ErrorMsg()); //Checked
$position++;
}
}
/**
* This function rewrites the sortorder for questions inside the named group
*
* @param integer $groupid the group id
* @param integer $surveyid the survey id
*/
function fixsortorderQuestions($groupid, $surveyid) //Function rewrites the sortorder for questions
{
global $connect;
$gid = sanitize_int($groupid);
$surveyid = sanitize_int($surveyid);
$baselang = GetBaseLanguageFromSurveyID($surveyid);
$cdresult = db_execute_assoc("SELECT qid FROM ".db_table_name('questions')." WHERE gid='{$gid}' and language='{$baselang}' ORDER BY question_order, title ASC"); //Checked
$position=0;
while ($cdrow=$cdresult->FetchRow())
{
$cd2query="UPDATE ".db_table_name('questions')." SET question_order='{$position}' WHERE qid='{$cdrow['qid']}' ";
$cd2result = $connect->Execute($cd2query) or safe_die ("Couldn't update question_order $cd2query ".$connect->ErrorMsg()); //Checked
$position++;
}
}
function shiftorderQuestions($sid,$gid,$shiftvalue) //Function shifts the sortorder for questions
{
global $dbprefix, $connect, $surveyid;
$sid=sanitize_int($sid);
$gid=sanitize_int($gid);
$shiftvalue=sanitize_int($shiftvalue);
$baselang = GetBaseLanguageFromSurveyID($surveyid);
$cdresult = db_execute_assoc("SELECT qid FROM ".db_table_name('questions')." WHERE gid='{$gid}' and language='{$baselang}' ORDER BY question_order, title ASC"); //Checked
$position=$shiftvalue;
while ($cdrow=$cdresult->FetchRow())
{
$cd2query="UPDATE ".db_table_name('questions')." SET question_order='{$position}' WHERE qid='{$cdrow['qid']}' ";
$cd2result = $connect->Execute($cd2query) or safe_die ("Couldn't update question_order $cd2query ".$connect->ErrorMsg()); //Checked
$position++;
}
}
function fixSortOrderGroups($surveyid) //Function rewrites the sortorder for groups
{
global $dbprefix, $connect;
$baselang = GetBaseLanguageFromSurveyID($surveyid);
$cdresult = db_execute_assoc("SELECT gid FROM ".db_table_name('groups')." WHERE sid='{$surveyid}' AND language='{$baselang}' ORDER BY group_order, group_name");
$position=0;
while ($cdrow=$cdresult->FetchRow())
{
$cd2query="UPDATE ".db_table_name('groups')." SET group_order='{$position}' WHERE gid='{$cdrow['gid']}' ";
$cd2result = $connect->Execute($cd2query) or safe_die ("Couldn't update group_order $cd2query ".$connect->ErrorMsg()); //Checked
$position++;
}
}
function fixmovedquestionConditions($qid,$oldgid,$newgid) //Function rewrites the cfieldname for a question after group change
{
global $dbprefix, $connect, $surveyid;
$qid=sanitize_int($qid);
$oldgid=sanitize_int($oldgid);
$newgid=sanitize_int($newgid);
$cresult = db_execute_assoc("SELECT cid, cfieldname FROM ".db_table_name('conditions')." WHERE cqid={$qid}"); //Checked
while ($crow=$cresult->FetchRow())
{
$mycid=$crow['cid'];
$mycfieldname=$crow['cfieldname'];
$cfnregs="";
if (preg_match('/'.$surveyid."X".$oldgid."X".$qid."(.*)/", $mycfieldname, $cfnregs) > 0)
{
$newcfn=$surveyid."X".$newgid."X".$qid.$cfnregs[1];
$c2query="UPDATE ".db_table_name('conditions')
." SET cfieldname='{$newcfn}' WHERE cid={$mycid}";
$c2result=$connect->Execute($c2query) //Checked
or safe_die ("Couldn't update conditions $c2query ".$connect->ErrorMsg());
}
}
}
/**
* This function returns GET/POST/REQUEST vars, for some vars like SID and others they are also sanitized
*
* @param mixed $stringname
*/
function returnglobal($stringname)
{
global $useWebserverAuth;
if ((isset($useWebserverAuth) && $useWebserverAuth === true) || $stringname=='sid') // don't read SID from a Cookie
{
if (isset($_GET[$stringname])) $urlParam = $_GET[$stringname];
if (isset($_POST[$stringname])) $urlParam = $_POST[$stringname];
}
elseif (isset($_REQUEST[$stringname]))
{
$urlParam = $_REQUEST[$stringname];
}
if (isset($urlParam))
{
if ($stringname == 'sid' || $stringname == "gid" || $stringname == "oldqid" ||
$stringname == "qid" || $stringname == "tid" ||
$stringname == "lid" || $stringname == "ugid"||
$stringname == "thisstep" || $stringname == "scenario" ||
$stringname == "cqid" || $stringname == "cid" ||
$stringname == "qaid" || $stringname == "scid" ||
$stringname == "loadsecurity")
{
return sanitize_int($urlParam);
}
elseif ($stringname =="lang" || $stringname =="adminlang")
{
return sanitize_languagecode($urlParam);
}
elseif ($stringname =="htmleditormode" ||
$stringname =="subaction" ||
$stringname =="questionselectormode" ||
$stringname =="templateeditormode"
)
{
return sanitize_paranoid_string($urlParam);
}
elseif ( $stringname =="cquestions")
{
return sanitize_cquestions($urlParam);
}
return $urlParam;
}
else
{
return NULL;
}
}
function sendcacheheaders()
{
global $embedded;
if ( $embedded ) return;
if (!headers_sent())
{
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); // this line lets IE7 run LimeSurvey in an iframe
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Content-Type: text/html; charset=utf-8');
}
}
function getsidgidqidaidtype($fieldcode)
{
// use simple parsing to get {sid}, {gid}
// and what may be {qid} or {qid}{aid} combination
list($fsid, $fgid, $fqid) = explode('X', $fieldcode);
$fsid=sanitize_int($fsid);
$fgid=sanitize_int($fgid);
if (!$fqid) {$fqid=0;}
$fqid=sanitize_int($fqid);
// try a true parsing of fieldcode (can separate qid from aid)
// but fails for type M and type P multiple choice
// questions because the SESSION fieldcode is combined
// and we want here to pass only the sidXgidXqid for type M and P
$fields=arraySearchByKey($fieldcode, createFieldMap($fsid), "fieldname", 1);
if (count($fields) != 0)
{
$aRef['sid']=$fields['sid'];
$aRef['gid']=$fields['gid'];
$aRef['qid']=$fields['qid'];
$aRef['aid']=$fields['aid'];
$aRef['type']=$fields['type'];
}
else
{
// either the fielcode doesn't match a question
// or it is a type M or P question
$aRef['sid']=$fsid;
$aRef['gid']=$fgid;
$aRef['qid']=sanitize_int($fqid);
$s_lang = GetBaseLanguageFromSurveyID($fsid);
$query = "SELECT type FROM ".db_table_name('questions')." WHERE qid=".$fqid." AND language='".$s_lang."'";
$result = db_execute_assoc($query) or safe_die ("Couldn't get question type - getsidgidqidaidtype() in common.php ".$connect->ErrorMsg()); //Checked
if ( $result->RecordCount() == 0 )
{ // question doesn't exist
return Array();
}
else
{ // certainly is type M or P
while($row=$result->FetchRow())
{
$aRef['type']=$row['type'];
}
}
}
//return array('sid'=>$fsid, "gid"=>$fgid, "qid"=>$fqid);
return $aRef;
}
/**
* put your comment there...
*
* @param mixed $fieldcode
* @param mixed $value
* @param mixed $format
* @param mixed $dateformatid
* @return string
*/
function getextendedanswer($fieldcode, $value, $format='', $dateformatphp='d.m.Y')
{
global $dbprefix, $surveyid, $connect, $clang, $action;
// use Survey base language if s_lang isn't set in _SESSION (when browsing answers)
$s_lang = GetBaseLanguageFromSurveyID($surveyid);
if (!isset($action) || (isset($action) && $action!='browse') )
{
if (isset($_SESSION['s_lang'])) $s_lang = $_SESSION['s_lang']; //This one does not work in admin mode when you browse a particular answer
}
//Fieldcode used to determine question, $value used to match against answer code
//Returns NULL if question type does not suit
if (substr_count($fieldcode, "X") > 1) //Only check if it looks like a real fieldcode
{
$fieldmap = createFieldMap($surveyid);
if (isset($fieldmap[$fieldcode]))
$fields = $fieldmap[$fieldcode];
else
return false;
//Find out the question type
$this_type = $fields['type'];
switch($this_type)
{
case 'D': if (trim($value)!='')
{
$datetimeobj = new Date_Time_Converter($value , "Y-m-d H:i:s");
$value=$datetimeobj->convert($dateformatphp);
}
break;
case "L":
case "!":
case "O":
case "^":
case "I":
case "R":
$query = "SELECT code, answer FROM ".db_table_name('answers')." WHERE qid={$fields['qid']} AND code='".$connect->escape($value)."' AND scale_id=0 AND language='".$s_lang."'";
$result = db_execute_assoc($query) or safe_die ("Couldn't get answer type L - getextendedanswer() in common.php $query ".$connect->ErrorMsg()); //Checked
while($row=$result->FetchRow())
{
$this_answer=$row['answer'];
} // while
if ($value == "-oth-")
{
$this_answer=$clang->gT("Other");
}
break;
case "M":
case "J":
case "P":
switch($value)
{
case "Y": $this_answer=$clang->gT("Yes"); break;
}
break;
case "Y":
switch($value)
{
case "Y": $this_answer=$clang->gT("Yes"); break;
case "N": $this_answer=$clang->gT("No"); break;
default: $this_answer=$clang->gT("No answer");
}
break;
case "G":
switch($value)
{
case "M": $this_answer=$clang->gT("Male"); break;
case "F": $this_answer=$clang->gT("Female"); break;
default: $this_answer=$clang->gT("No answer");
}
break;
case "C":
switch($value)
{
case "Y": $this_answer=$clang->gT("Yes"); break;
case "N": $this_answer=$clang->gT("No"); break;
case "U": $this_answer=$clang->gT("Uncertain"); break;
}
break;
case "E":
switch($value)
{
case "I": $this_answer=$clang->gT("Increase"); break;
case "D": $this_answer=$clang->gT("Decrease"); break;
case "S": $this_answer=$clang->gT("Same"); break;
}
break;
case "F":
case "H":
case "1":
$query = "SELECT answer FROM ".db_table_name('answers')." WHERE qid={$fields['qid']} AND code='".$connect->escape($value)."' AND language='".$s_lang."'";
if (isset($fields['scale_id']))
{
$query.=" AND scale_id={$fields['scale_id']}";
}
$result = db_execute_assoc($query) or safe_die ("Couldn't get answer type F/H - getextendedanswer() in common.php"); //Checked
while($row=$result->FetchRow())
{
$this_answer=$row['answer'];
} // while
if ($value == "-oth-")
{
$this_answer=$clang->gT("Other");
}
break;
case "|": //File upload
if (substr($fieldcode, -9) == 'filecount') {
$this_answer = $clang->gT("File count");
} else {
//Show the filename, size, title and comment -- no link!
$files = json_decode($value);
$value = '';
if (is_array($files)) {
foreach ($files as $file) {
$value .= $file->name .
' (' . $file->size . 'KB) ' .
strip_tags($file->title) .
' - ' . strip_tags($file->comment) . " ";
}
}
}
break;
default:
;
} // switch
}
if (isset($this_answer))
{
if ($format != 'INSERTANS')
{
return $this_answer." [$value]";
}
else
{
if (strip_tags($this_answer) == "")
{
switch ($this_type)
{// for questions with answers beeing
// answer code, it is safe to return the
// code instead of the blank stripped answer
case "A":
case "B":
case "C":
case "E":
case "F":
case "H":
case "1":
case "M":
case "P":
case "!":
case "5":
case "L":
case "O":
return $value;
break;
default:
return strip_tags($this_answer);
break;
}
}
else
{
return strip_tags($this_answer);
}
}
}
else
{
return $value;
}
}
/*function validate_email($email)
{
// Create the syntactical validation regular expression
// Validate the syntax
// see http://data.iana.org/TLD/tlds-alpha-by-domain.txt
$maxrootdomainlength = 6;
return ( ! preg_match("/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,".$maxrootdomainlength."}))$/ix", $email)) ? FALSE : TRUE;
}*/
function validate_email($email){
$no_ws_ctl = "[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]";
$alpha = "[\\x41-\\x5a\\x61-\\x7a]";
$digit = "[\\x30-\\x39]";
$cr = "\\x0d";
$lf = "\\x0a";
$crlf = "(?:$cr$lf)";
$obs_char = "[\\x00-\\x09\\x0b\\x0c\\x0e-\\x7f]";
$obs_text = "(?:$lf*$cr*(?:$obs_char$lf*$cr*)*)";
$text = "(?:[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f]|$obs_text)";
$text = "(?:$lf*$cr*$obs_char$lf*$cr*)";
$obs_qp = "(?:\\x5c[\\x00-\\x7f])";
$quoted_pair = "(?:\\x5c$text|$obs_qp)";
$wsp = "[\\x20\\x09]";
$obs_fws = "(?:$wsp+(?:$crlf$wsp+)*)";
$fws = "(?:(?:(?:$wsp*$crlf)?$wsp+)|$obs_fws)";
$ctext = "(?:$no_ws_ctl|[\\x21-\\x27\\x2A-\\x5b\\x5d-\\x7e])";
$ccontent = "(?:$ctext|$quoted_pair)";
$comment = "(?:\\x28(?:$fws?$ccontent)*$fws?\\x29)";
$cfws = "(?:(?:$fws?$comment)*(?:$fws?$comment|$fws))";
$outer_ccontent_dull = "(?:$fws?$ctext|$quoted_pair)";
$outer_ccontent_nest = "(?:$fws?$comment)";
$outer_comment = "(?:\\x28$outer_ccontent_dull*(?:$outer_ccontent_nest$outer_ccontent_dull*)+$fws?\\x29)";
$atext = "(?:$alpha|$digit|[\\x21\\x23-\\x27\\x2a\\x2b\\x2d\\x2f\\x3d\\x3f\\x5e\\x5f\\x60\\x7b-\\x7e])";
$atext_domain = "(?:$alpha|$digit|[\\x2b\\x2d\\x5f])";
$atom = "(?:$cfws?(?:$atext)+$cfws?)";
$atom_domain = "(?:$cfws?(?:$atext_domain)+$cfws?)";
$qtext = "(?:$no_ws_ctl|[\\x21\\x23-\\x5b\\x5d-\\x7e])";
$qcontent = "(?:$qtext|$quoted_pair)";
$quoted_string = "(?:$cfws?\\x22(?:$fws?$qcontent)*$fws?\\x22$cfws?)";
$quoted_string = "(?:$cfws?\\x22(?:$fws?$qcontent)+$fws?\\x22$cfws?)";
$word = "(?:$atom|$quoted_string)";
$obs_local_part = "(?:$word(?:\\x2e$word)*)";
$obs_domain = "(?:$atom_domain(?:\\x2e$atom_domain)*)";
$dot_atom_text = "(?:$atext+(?:\\x2e$atext+)*)";
$dot_atom_text_domain = "(?:$atext_domain+(?:\\x2e$atext_domain+)*)";
$dot_atom = "(?:$cfws?$dot_atom_text$cfws?)";
$dot_atom_domain = "(?:$cfws?$dot_atom_text_domain$cfws?)";
$dtext = "(?:$no_ws_ctl|[\\x21-\\x5a\\x5e-\\x7e])";
$dcontent = "(?:$dtext|$quoted_pair)";
$domain_literal = "(?:$cfws?\\x5b(?:$fws?$dcontent)*$fws?\\x5d$cfws?)";
$local_part = "(($dot_atom)|($quoted_string)|($obs_local_part))";
$domain = "(($dot_atom_domain)|($domain_literal)|($obs_domain))";
$addr_spec = "$local_part\\x40$domain";
if (strlen($email) > 256) return FALSE;
$email = strip_comments($outer_comment, $email, "(x)");
if (!preg_match("!^$addr_spec$!", $email, $m)){
return FALSE;
}
$bits = array(
'local' => isset($m[1]) ? $m[1] : '',
'local-atom' => isset($m[2]) ? $m[2] : '',
'local-quoted' => isset($m[3]) ? $m[3] : '',
'local-obs' => isset($m[4]) ? $m[4] : '',
'domain' => isset($m[5]) ? $m[5] : '',
'domain-atom' => isset($m[6]) ? $m[6] : '',
'domain-literal' => isset($m[7]) ? $m[7] : '',
'domain-obs' => isset($m[8]) ? $m[8] : '',
);
$bits['local'] = strip_comments($comment, $bits['local']);
$bits['domain'] = strip_comments($comment, $bits['domain']);
if (strlen($bits['local']) > 64) return FALSE;
if (strlen($bits['domain']) > 255) return FALSE;
if (strlen($bits['domain-literal'])){
$Snum = "(\d{1,3})";
$IPv4_address_literal = "$Snum\.$Snum\.$Snum\.$Snum";
$IPv6_hex = "(?:[0-9a-fA-F]{1,4})";
$IPv6_full = "IPv6\:$IPv6_hex(:?\:$IPv6_hex){7}";
$IPv6_comp_part = "(?:$IPv6_hex(?:\:$IPv6_hex){0,5})?";
$IPv6_comp = "IPv6\:($IPv6_comp_part\:\:$IPv6_comp_part)";
$IPv6v4_full = "IPv6\:$IPv6_hex(?:\:$IPv6_hex){5}\:$IPv4_address_literal";
$IPv6v4_comp_part = "$IPv6_hex(?:\:$IPv6_hex){0,3}";
$IPv6v4_comp = "IPv6\:((?:$IPv6v4_comp_part)?\:\:(?:$IPv6v4_comp_part\:)?)$IPv4_address_literal";
if (preg_match("!^\[$IPv4_address_literal\]$!", $bits['domain'], $m)){
if (intval($m[1]) > 255) return FALSE;
if (intval($m[2]) > 255) return FALSE;
if (intval($m[3]) > 255) return FALSE;
if (intval($m[4]) > 255) return FALSE;
}else{
while (1){
if (preg_match("!^\[$IPv6_full\]$!", $bits['domain'])){
break;
}
if (preg_match("!^\[$IPv6_comp\]$!", $bits['domain'], $m)){
list($a, $b) = explode('::', $m[1]);
$folded = (strlen($a) && strlen($b)) ? "$a:$b" : "$a$b";
$groups = explode(':', $folded);
if (count($groups) > 6) return FALSE;
break;
}
if (preg_match("!^\[$IPv6v4_full\]$!", $bits['domain'], $m)){
if (intval($m[1]) > 255) return FALSE;
if (intval($m[2]) > 255) return FALSE;
if (intval($m[3]) > 255) return FALSE;
if (intval($m[4]) > 255) return FALSE;
break;
}
if (preg_match("!^\[$IPv6v4_comp\]$!", $bits['domain'], $m)){
list($a, $b) = explode('::', $m[1]);
$b = substr($b, 0, -1); # remove the trailing colon before the IPv4 address
$folded = (strlen($a) && strlen($b)) ? "$a:$b" : "$a$b";
$groups = explode(':', $folded);
if (count($groups) > 4) return FALSE;
break;
}
return FALSE;
}
}
}else{
$labels = explode('.', $bits['domain']);
if (count($labels) == 1) return FALSE;
foreach ($labels as $label){
if (strlen($label) > 63) return FALSE;
if (substr($label, 0, 1) == '-') return FALSE;
if (substr($label, -1) == '-') return FALSE;
}
if (preg_match('!^[0-9]+$!', array_pop($labels))) return FALSE;
}
return TRUE;
}
##################################################################################
function strip_comments($comment, $email, $replace=''){
while (1){
$new = preg_replace("!$comment!", $replace, $email);
if (strlen($new) == strlen($email)){
return $email;
}
$email = $new;
}
}
function validate_templatedir($templatename)
{
global $usertemplaterootdir, $defaulttemplate;
if (isStandardTemplate($templatename))
{
return $templatename;
}
elseif (is_dir("$usertemplaterootdir/{$templatename}/"))
{
return $templatename;
}
elseif (isStandardTemplate($defaulttemplate))
{
return $defaulttemplate;
}
elseif (is_dir("$usertemplaterootdir/{$defaulttemplate}/"))
{
return $defaulttemplate;
}
else
{
return 'default';
}
}
/**
* This function generates an array containing the fieldcode, and matching data in the same order as the activate script
*
* @param string $surveyid The Survey ID
* @param mixed $style 'short' (default) or 'full' - full creates extra information like default values
* @param mixed $force_refresh - Forces to really refresh the array, not just take the session copy
* @param int $questionid Limit to a certain qid only (for question preview) - default is false
* @return array
*/
function createFieldMap($surveyid, $style='full', $force_refresh=false, $questionid=false, $sQuestionLanguage=null) {
global $dbprefix, $connect, $clang, $aDuplicateQIDs;
$surveyid=sanitize_int($surveyid);
//Get list of questions
if (is_null($sQuestionLanguage))
{
if (isset($_SESSION['s_lang'])&& in_array($_SESSION['s_lang'],GetAdditionalLanguagesFromSurveyID($surveyid)) ) {
$sQuestionLanguage = $_SESSION['s_lang'];
}
else {
$sQuestionLanguage = GetBaseLanguageFromSurveyID($surveyid);
}
}
$sQuestionLanguage = sanitize_languagecode($sQuestionLanguage);
if ($clang->langcode != $sQuestionLanguage) {
SetSurveyLanguage($surveyid, $sQuestionLanguage);
}
$s_lang = $clang->langcode;
//checks to see if fieldmap has already been built for this page.
if (isset($_SESSION['fieldmap-' . $surveyid . $s_lang]) && !$force_refresh && $questionid == false) {
if (isset($_SESSION['adminlang']) && $clang->langcode != $_SESSION['adminlang']) {
$clang = new limesurvey_lang($_SESSION['adminlang']);
}
return $_SESSION['fieldmap-' . $surveyid . $s_lang];
}
$fieldmap["id"]=array("fieldname"=>"id", 'sid'=>$surveyid, 'type'=>"id", "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["id"]['title']="";
$fieldmap["id"]['question']=$clang->gT("Response ID");
$fieldmap["id"]['group_name']="";
}
$fieldmap["submitdate"]=array("fieldname"=>"submitdate", 'type'=>"submitdate", 'sid'=>$surveyid, "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["submitdate"]['title']="";
$fieldmap["submitdate"]['question']=$clang->gT("Date submitted");
$fieldmap["submitdate"]['group_name']="";
}
$fieldmap["lastpage"]=array("fieldname"=>"lastpage", 'sid'=>$surveyid, 'type'=>"lastpage", "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["lastpage"]['title']="";
$fieldmap["lastpage"]['question']=$clang->gT("Last page");
$fieldmap["lastpage"]['group_name']="";
}
$fieldmap["startlanguage"]=array("fieldname"=>"startlanguage", 'sid'=>$surveyid, 'type'=>"startlanguage", "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["startlanguage"]['title']="";
$fieldmap["startlanguage"]['question']=$clang->gT("Start language");
$fieldmap["startlanguage"]['group_name']="";
}
//Check for any additional fields for this survey and create necessary fields (token and datestamp and ipaddr)
$pquery = "SELECT anonymized, datestamp, ipaddr, refurl FROM ".db_table_name('surveys')." WHERE sid=$surveyid";
$presult=db_execute_assoc($pquery); //Checked
while($prow=$presult->FetchRow())
{
if ($prow['anonymized'] == "N")
{
$fieldmap["token"]=array("fieldname"=>"token", 'sid'=>$surveyid, 'type'=>"token", "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["token"]['title']="";
$fieldmap["token"]['question']=$clang->gT("Token");
$fieldmap["token"]['group_name']="";
}
}
if ($prow['datestamp'] == "Y")
{
$fieldmap["datestamp"]=array("fieldname"=>"datestamp",
'type'=>"datestamp",
'sid'=>$surveyid,
"gid"=>"",
"qid"=>"",
"aid"=>"");
if ($style == "full")
{
$fieldmap["datestamp"]['title']="";
$fieldmap["datestamp"]['question']=$clang->gT("Date last action");
$fieldmap["datestamp"]['group_name']="";
}
$fieldmap["startdate"]=array("fieldname"=>"startdate",
'type'=>"startdate",
'sid'=>$surveyid,
"gid"=>"",
"qid"=>"",
"aid"=>"");
if ($style == "full")
{
$fieldmap["startdate"]['title']="";
$fieldmap["startdate"]['question']=$clang->gT("Date started");
$fieldmap["startdate"]['group_name']="";
}
}
if ($prow['ipaddr'] == "Y")
{
$fieldmap["ipaddr"]=array("fieldname"=>"ipaddr",
'type'=>"ipaddress",
'sid'=>$surveyid,
"gid"=>"",
"qid"=>"",
"aid"=>"");
if ($style == "full")
{
$fieldmap["ipaddr"]['title']="";
$fieldmap["ipaddr"]['question']=$clang->gT("IP address");
$fieldmap["ipaddr"]['group_name']="";
}
}
// Add 'refurl' to fieldmap.
if ($prow['refurl'] == "Y")
{
$fieldmap["refurl"]=array("fieldname"=>"refurl", 'type'=>"url", 'sid'=>$surveyid, "gid"=>"", "qid"=>"", "aid"=>"");
if ($style == "full")
{
$fieldmap["refurl"]['title']="";
$fieldmap["refurl"]['question']=$clang->gT("Referrer URL");
$fieldmap["refurl"]['group_name']="";
}
}
}
// Collect all default values once so don't need separate query for each question with defaults
// First collect language specific defaults
$defaultsQuery = "SELECT a.qid, a.sqid, a.scale_id, a.specialtype, a.defaultvalue"
. " FROM ".db_table_name('defaultvalues')." as a, ".db_table_name('questions')." as b"
. " WHERE a.qid = b.qid"
. " AND a.language = b.language"
. " AND a.language = '$s_lang'"
. " AND b.same_default=0"
. " AND b.sid = ".$surveyid;
$defaultResults = db_execute_assoc($defaultsQuery) or safe_die ("Couldn't get list of default values in createFieldMap. $defaultsQuery ".$conect->ErrorMsg());
$defaultValues = array(); // indexed by question then subquestion
foreach($defaultResults as $dv)
{
if ($dv['specialtype'] != '') {
$sq = $dv['specialtype'];
}
else {
$sq = $dv['sqid'];
}
$defaultValues[$dv['qid'].'~'.$sq] = $dv['defaultvalue'];
}
// Now overwrite language-specific defaults (if any) base language values for each question that uses same_defaults=1
$baseLanguage = GetBaseLanguageFromSurveyID($surveyid);
$defaultsQuery = "SELECT a.qid, a.sqid, a.scale_id, a.specialtype, a.defaultvalue"
. " FROM ".db_table_name('defaultvalues')." as a, ".db_table_name('questions')." as b"
. " WHERE a.qid = b.qid"
. " AND a.language = b.language"
. " AND a.language = '$baseLanguage'"
. " AND b.same_default=1"
. " AND b.sid = ".$surveyid;
$defaultResults = db_execute_assoc($defaultsQuery) or safe_die ("Couldn't get list of default values in createFieldMap. $defaultsQuery ".$conect->ErrorMsg());
foreach($defaultResults as $dv)
{
if ($dv['specialtype'] != '') {
$sq = $dv['specialtype'];
}
else {
$sq = $dv['sqid'];
}
$defaultValues[$dv['qid'].'~'.$sq] = $dv['defaultvalue'];
}
$qtypes=getqtypelist('','array');
$aquery = "SELECT * "
." FROM ".db_table_name('questions')." as questions, ".db_table_name('groups')." as groups"
." WHERE questions.gid=groups.gid AND "
." questions.sid=$surveyid AND "
." questions.language='{$s_lang}' AND "
." questions.parent_qid=0 AND "
." groups.language='{$s_lang}' ";
if ($questionid!==false)
{
$aquery.=" and questions.qid={$questionid} ";
}
$aquery.=" ORDER BY group_order, question_order";
$aresult = db_execute_assoc($aquery) or safe_die ("Couldn't get list of questions in createFieldMap function. $query ".$connect->ErrorMsg()); //Checked
$questionSeq=-1; // this is incremental question sequence across all groups
$groupSeq=-1;
$_groupOrder=-1;
while ($arow=$aresult->FetchRow()) //With each question, create the appropriate field(s)
{
++$questionSeq;
// fix fact taht group_order may have gaps
if ($_groupOrder != $arow['group_order']) {
$_groupOrder = $arow['group_order'];
++$groupSeq;
}
// Conditions indicators are obsolete with EM. However, they are so tightly coupled into LS code that easider to just set values to 'N' for now and refactor later.
$conditions = 'N';
$usedinconditions = 'N';
// Field identifier
// GXQXSXA
// G=Group Q=Question S=Subquestion A=Answer Option
// If S or A don't exist then set it to 0
// Implicit (subqestion intermal to a question type ) or explicit qubquestions/answer count starts at 1
// Types "L", "!" , "O", "D", "G", "N", "X", "Y", "5","S","T","U","*"
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}";
if ($qtypes[$arow['type']]['subquestions']==0 && $arow['type'] != "R" && $arow['type'] != "|")
{
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>"{$arow['type']}", 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>"");
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
if (isset($defaultValues[$arow['qid'].'~0'])) {
$fieldmap[$fieldname]['defaultvalue'] = $defaultValues[$arow['qid'].'~0'];
}
}
switch($arow['type'])
{
case "L": //RADIO LIST
case "!": //DROPDOWN LIST
$fieldmap[$fieldname]['other']=$arow['other']; // so that base variable knows whether has other value
if ($arow['other'] == "Y")
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}other";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
"gid"=>$arow['gid'],
"qid"=>$arow['qid'],
"aid"=>"other");
// dgk bug fix line above. aid should be set to "other" for export to append to the field name in the header line.
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$clang->gT("Other");
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['other']=$arow['other'];
if (isset($defaultValues[$arow['qid'].'~other'])) {
$fieldmap[$fieldname]['defaultvalue'] = $defaultValues[$arow['qid'].'~other'];
}
}
}
break;
case "O": //DROPDOWN LIST WITH COMMENT
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}comment";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
"gid"=>$arow['gid'],
"qid"=>$arow['qid'],
"aid"=>"comment");
// dgk bug fix line below. aid should be set to "comment" for export to append to the field name in the header line. Also needed set the type element correctly.
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$clang->gT("Comment");
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
break;
}
}
// For Multi flexi question types
elseif ($qtypes[$arow['type']]['subquestions']==2 && $qtypes[$arow['type']]['answerscales']==0)
{
//MULTI FLEXI
$abrows = getSubQuestions($surveyid,$arow['qid'],$s_lang);
//Now first process scale=1
$answerset=array();
$answerList = array();
foreach ($abrows as $key=>$abrow)
{
if($abrow['scale_id']==1) {
$answerset[]=$abrow;
$answerList[] = array(
'code'=>$abrow['title'],
'answer'=>$abrow['question'],
);
unset($abrows[$key]);
}
}
reset($abrows);
foreach ($abrows as $abrow)
{
foreach($answerset as $answer)
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}{$abrow['title']}_{$answer['title']}";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
"gid"=>$arow['gid'],
"qid"=>$arow['qid'],
"aid"=>$abrow['title']."_".$answer['title'],
"sqid"=>$abrow['qid']);
if ($abrow['other']=="Y") {$alsoother="Y";}
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion1']=$abrow['question'];
$fieldmap[$fieldname]['subquestion2']=$answer['question'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['preg']=$arow['preg'];
$fieldmap[$fieldname]['answerList']=$answerList;
}
}
}
unset($answerset);
}
elseif ($arow['type'] == "1")
{
$abrows = getSubQuestions($surveyid,$arow['qid'],$s_lang);
foreach ($abrows as $abrow)
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}{$abrow['title']}#0";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>$abrow['title'], "scale_id"=>0);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$abrow['question'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['scale']=$clang->gT('Scale 1');
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}{$abrow['title']}#1";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>$abrow['title'], "scale_id"=>1);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$abrow['question'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['scale']=$clang->gT('Scale 2');
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
}
}
elseif ($arow['type'] == "R")
{
//MULTI ENTRY
$slots=$connect->GetOne("select count(code) from ".db_table_name('answers')." where qid={$arow['qid']} and language='{$s_lang}'");
for ($i=1; $i<=$slots; $i++)
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}$i";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>$i);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=sprintf($clang->gT('Rank %s'),$i);
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
}
}
elseif ($arow['type'] == "|")
{
$abquery = "SELECT value FROM ".db_table_name('question_attributes')
." WHERE attribute='max_num_of_files' AND qid=".$arow['qid'];
$abresult = db_execute_assoc($abquery) or safe_die ("Couldn't get maximum
number of files that can be uploaded $abquery ".$connect->ErrorMsg());
$abrow = $abresult->FetchRow();
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}";
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
"gid"=>$arow['gid'],
"qid"=>$arow['qid'],
"aid"=>''
);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['max_files']=$abrow['value'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}"."_filecount";
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
"gid"=>$arow['gid'],
"qid"=>$arow['qid'],
"aid"=>"filecount"
);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']="filecount - ".$arow['question'];
//$fieldmap[$fieldname]['subquestion']=$clang->gT("Comment");
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
}
else // Question types with subquestions and one answer per subquestion (M/A/B/C/E/F/H/P)
{
//MULTI ENTRY
$abrows = getSubQuestions($surveyid,$arow['qid'],$s_lang);
foreach ($abrows as $abrow)
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}{$abrow['title']}";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname,
'type'=>$arow['type'],
'sid'=>$surveyid,
'gid'=>$arow['gid'],
'qid'=>$arow['qid'],
'aid'=>$abrow['title'],
'sqid'=>$abrow['qid']);
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$abrow['question'];
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['preg']=$arow['preg'];
if (isset($defaultValues[$arow['qid'].'~'.$abrow['qid']])) {
$fieldmap[$fieldname]['defaultvalue'] = $defaultValues[$arow['qid'].'~'.$abrow['qid']];
}
}
if ($arow['type'] == "P")
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}{$abrow['title']}comment";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>$abrow['title']."comment");
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$clang->gT('Comment');
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
}
}
}
if ($arow['other']=="Y" && ($arow['type']=="M" || $arow['type']=="P"))
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}other";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>"other");
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$clang->gT('Other');
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['other']=$arow['other'];
}
if ($arow['type']=="P")
{
$fieldname="{$arow['sid']}X{$arow['gid']}X{$arow['qid']}othercomment";
if (isset($fieldmap[$fieldname])) $aDuplicateQIDs[$arow['qid']]=array('fieldname'=>$fieldname,'question'=>$arow['question'],'gid'=>$arow['gid']);
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>$arow['type'], 'sid'=>$surveyid, "gid"=>$arow['gid'], "qid"=>$arow['qid'], "aid"=>"othercomment");
if ($style == "full")
{
$fieldmap[$fieldname]['title']=$arow['title'];
$fieldmap[$fieldname]['question']=$arow['question'];
$fieldmap[$fieldname]['subquestion']=$clang->gT('Other comment');
$fieldmap[$fieldname]['group_name']=$arow['group_name'];
$fieldmap[$fieldname]['mandatory']=$arow['mandatory'];
$fieldmap[$fieldname]['hasconditions']=$conditions;
$fieldmap[$fieldname]['usedinconditions']=$usedinconditions;
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['other']=$arow['other'];
}
}
}
}
if (isset($fieldmap[$fieldname])) // only add these fields if there is actually a valid field
{
$fieldmap[$fieldname]['relevance']=$arow['relevance'];
$fieldmap[$fieldname]['grelevance']=$arow['grelevance'];
$fieldmap[$fieldname]['questionSeq']=$questionSeq;
$fieldmap[$fieldname]['groupSeq']=$groupSeq;
$fieldmap[$fieldname]['preg']=$arow['preg'];
$fieldmap[$fieldname]['other']=$arow['other'];
$fieldmap[$fieldname]['help']=$arow['help'];
}
else
{
--$questionSeq; // didn't generate a valid $fieldmap entry, so decrement the question counter to ensure they are sequential
}
}
if (isset($fieldmap)) {
if ($questionid == false)
{
// If the fieldmap was randomized, the master will contain the proper order. Copy that fieldmap with the new language settings.
if (isset($_SESSION['fieldmap-' . $surveyid . '-randMaster']))
{
$masterFieldmap = $_SESSION['fieldmap-' . $surveyid . '-randMaster'];
$mfieldmap = $_SESSION[$masterFieldmap];
foreach ($mfieldmap as $fieldname => $mf)
{
if (isset($fieldmap[$fieldname]))
{
$f = $fieldmap[$fieldname];
if (isset($f['question']))
{
$mf['question'] = $f['question'];
}
if (isset($f['subquestion']))
{
$mf['subquestion'] = $f['subquestion'];
}
if (isset($f['subquestion1']))
{
$mf['subquestion1'] = $f['subquestion1'];
}
if (isset($f['subquestion2']))
{
$mf['subquestion2'] = $f['subquestion2'];
}
if (isset($f['group_name']))
{
$mf['group_name'] = $f['group_name'];
}
if (isset($f['answerList']))
{
$mf['answerList'] = $f['answerList'];
}
if (isset($f['defaultvalue']))
{
$mf['defaultvalue'] = $f['defaultvalue'];
}
if (isset($f['help']))
{
$mf['help'] = $f['help'];
}
}
$mfieldmap[$fieldname] = $mf;
}
$fieldmap = $mfieldmap;
}
$_SESSION['fieldmap-' . $surveyid . $clang->langcode]=$fieldmap;
}
if (isset($_SESSION['adminlang']) && $clang->langcode != $_SESSION['adminlang']) {
$clang = new limesurvey_lang($_SESSION['adminlang']);
}
return $fieldmap;
}
}
/**
* This function generates an array containing the fieldcode, and matching data in the same order as the activate script
*
* @param string $surveyid The Survey ID
* @param mixed $style 'short' (default) or 'full' - full creates extra information like default values
* @param mixed $force_refresh - Forces to really refresh the array, not just take the session copy
* @param int $questionid Limit to a certain qid only (for question preview) - default is false
* @return array
*/
function createTimingsFieldMap($surveyid, $style='full', $force_refresh=false, $questionid=false, $sQuestionLanguage=null) {
global $dbprefix, $connect, $clang, $aDuplicateQIDs;
static $timingsFieldMap;
$surveyid=sanitize_int($surveyid);
//checks to see if fieldmap has already been built for this page.
if (isset($timingsFieldMap[$surveyid][$style][$clang->langcode]) && $force_refresh==false) {
return $timingsFieldMap[$surveyid][$style][$clang->langcode];
}
//do something
$fields = createFieldMap($surveyid, $style, $force_refresh, $questionid, $sQuestionLanguage);
$fieldmap['interviewtime']=array('fieldname'=>'interviewtime','type'=>'interview_time','sid'=>$surveyid, 'gid'=>'', 'qid'=>'', 'aid'=>'', 'question'=>$clang->gT('Total time'), 'title'=>'interviewtime');
foreach ($fields as $field) {
if (!empty($field['gid'])) {
// field for time spent on page
$fieldname="{$field['sid']}X{$field['gid']}time";
if (!isset($fieldmap[$fieldname]))
{
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>"page_time", 'sid'=>$surveyid, "gid"=>$field['gid'], "group_name"=>$field['group_name'], "qid"=>'', 'aid'=>'', 'title'=>'groupTime'.$field['gid'], 'question'=>$clang->gT('Group time').": ".$field['group_name']);
}
// field for time spent on answering a question
$fieldname="{$field['sid']}X{$field['gid']}X{$field['qid']}time";
if (!isset($fieldmap[$fieldname]))
{
$fieldmap[$fieldname]=array("fieldname"=>$fieldname, 'type'=>"answer_time", 'sid'=>$surveyid, "gid"=>$field['gid'], "group_name"=>$field['group_name'], "qid"=>$field['qid'], 'aid'=>'', "title"=>$field['title'].'Time', "question"=>$clang->gT('Question time').": ".$field['title']);
}
}
}
$timingsFieldMap[$surveyid][$style][$clang->langcode] = $fieldmap;
return $timingsFieldMap[$surveyid][$style][$clang->langcode];
}
/**
* put your comment there...
*
* @param mixed $needle
* @param mixed $haystack
* @param mixed $keyname
* @param mixed $maxanswers
*/
function arraySearchByKey($needle, $haystack, $keyname, $maxanswers="") {
$output=array();
foreach($haystack as $hay) {
if (array_key_exists($keyname, $hay)) {
if ($hay[$keyname] == $needle) {
if ($maxanswers == 1) {
return $hay;
} else {
$output[]=$hay;
}
}
}
}
return $output;
}
/**
* This function returns a count of the number of saved responses to a survey
*
* @param mixed $surveyid Survey ID
*/
function getSavedCount($surveyid)
{
global $dbprefix, $connect;
$surveyid=(int)$surveyid;
$query = "SELECT COUNT(*) FROM ".db_table_name('saved_control')." WHERE sid=$surveyid";
$count=$connect->getOne($query);
return $count;
}
function GetBaseLanguageFromSurveyID($surveyid)
{
static $cache = array();
global $connect,$defaultlang;
$surveyid=(int)($surveyid);
if (!isset($cache[$surveyid])) {
$query = "SELECT language FROM ".db_table_name('surveys')." WHERE sid=$surveyid";
$surveylanguage = $connect->GetOne($query); //Checked
if (is_null($surveylanguage))
{
$surveylanguage=$defaultlang;
}
$cache[$surveyid] = $surveylanguage;
} else {
$surveylanguage = $cache[$surveyid];
}
return $surveylanguage;
}
function GetAdditionalLanguagesFromSurveyID($surveyid)
{
static $cache = array();
global $connect;
$surveyid=sanitize_int($surveyid);
if (!isset($cache[$surveyid])) {
$query = "SELECT additional_languages FROM ".db_table_name('surveys')." WHERE sid=$surveyid";
$additional_languages = $connect->GetOne($query);
if (trim($additional_languages)=='')
{
$additional_languages = array();
}
else
{
$additional_languages = explode(" ", trim($additional_languages));
}
$cache[$surveyid] = $additional_languages;
} else {
$additional_languages = $cache[$surveyid];
}
return $additional_languages;
}
//For multilanguage surveys
// If null or 0 is given for $surveyid then the default language from config-defaults.php is returned
function SetSurveyLanguage($surveyid, $language)
{
global $rootdir, $defaultlang, $clang;
$surveyid=sanitize_int($surveyid);
require_once($rootdir.'/classes/core/language.php');
if (isset($surveyid) && $surveyid>0)
{
// see if language actually is present in survey
# $query = "SELECT language, additional_languages FROM ".db_table_name('surveys')." WHERE sid=$surveyid";
# $result = db_execute_assoc($query); //Checked
# while ($result && ($row=$result->FetchRow())) {
# $additional_languages = $row['additional_languages'];
# $default_language = $row['language'];
# }
$default_language=GetBaseLanguageFromSurveyID($surveyid);
$additional_languages=GetAdditionalLanguagesFromSurveyID($surveyid);
if ( !isset($language) || ($language=='')
|| !( in_array($language,$additional_languages) || $language==$default_language)
)
{
// Language not supported, fall back to survey's default language
$_SESSION['s_lang'] = $default_language;
}
else
{
$_SESSION['s_lang'] = $language;
}
$clang = new limesurvey_lang($_SESSION['s_lang']);
}
else {
$clang = new limesurvey_lang($defaultlang);
}
$thissurvey=getSurveyInfo($surveyid, $_SESSION['s_lang']);
$_SESSION['dateformats'] = getDateFormatData($thissurvey['surveyls_dateformat']);
LimeExpressionManager::SetEMLanguage($_SESSION['s_lang']);
return $clang;
}
function buildLabelSetCheckSumArray()
{
global $connect;
// BUILD CHECKSUMS FOR ALL EXISTING LABEL SETS
$query = "SELECT lid
FROM ".db_table_name('labelsets')."
ORDER BY lid";
$result = db_execute_assoc($query) or safe_die("safe_died collecting labelset ids $query ".$connect->ErrorMsg()); //Checked
$csarray=array();
while ($row=$result->FetchRow())
{
$thisset="";
$query2 = "SELECT code, title, sortorder, language, assessment_value
FROM ".db_table_name('labels')."
WHERE lid={$row['lid']}
ORDER BY language, sortorder, code";
$result2 = db_execute_num($query2) or safe_die("safe_died querying labelset $lid $query2 ".$connect->ErrorMsg()); //Checked
while($row2=$result2->FetchRow())
{
$thisset .= implode('.', $row2);
} // while
$csarray[$row['lid']]=dechex(crc32($thisset)*1);
}
return $csarray;
}
/**
*
* Returns a flat array with all question attributes for the question only (and the qid we gave it)!
* @author: c_schmitz
* @param $qid The question ID
* @param $type optional The question type - saves a DB query if you provide it
* @return array{attribute=>value , attribute=>value} or false if the question ID does not exist (anymore)
*/
function getQuestionAttributes($qid, $type='')
{
static $cache = array();
static $availableattributesarr = null;
if (isset($cache[$qid])) {
return $cache[$qid];
}
if ($type=='') // If type is not given find it out
{
$query = "SELECT type FROM ".db_table_name('questions')." WHERE qid=$qid and parent_qid=0 group by type";
$result = db_execute_assoc($query) or safe_die("Error finding question attributes"); //Checked
$row=$result->FetchRow();
if ($row===false) // Question was deleted while running the survey
{
$cache[$qid]=false;
return false;
}
$type=$row['type'];
}
//Now read available attributes, make sure we do this only once per request to save
//processing cycles and memory
if (is_null($availableattributesarr)) $availableattributesarr=questionAttributes();
if (isset($availableattributesarr[$type]))
{
$availableattributes=$availableattributesarr[$type];
}
else
{
$cache[$qid]=array();
return array();
}
foreach($availableattributes as $attribute){
$defaultattributes[$attribute['name']]=$attribute['default'];
}
$setattributes=array();
$qid=sanitize_int($qid);
$query = "SELECT attribute, value FROM ".db_table_name('question_attributes')." WHERE qid=$qid";
$result = db_execute_assoc($query) or safe_die("Error finding question attributes"); //Checked
$setattributes=array();
while ($row=$result->FetchRow())
{
$setattributes[$row['attribute']]=$row['value'];
}
//echo "
";print_r($qid_attributes);echo "
";
$qid_attributes=array_merge($defaultattributes,$setattributes);
$cache[$qid]=$qid_attributes;
return $qid_attributes;
}
/**
*
* Returns the questionAttribtue value set or '' if not set
* @author: lemeur
* @param $questionAttributeArray
* @param $attributeName
* @return string
*/
function getQuestionAttributeValue($questionAttributeArray, $attributeName)
{
if (isset($questionAttributeArray[$attributeName]))
{
return $questionAttributeArray[$attributeName];
}
else
{
return '';
}
}
/**
* Returns array of question type chars with attributes
*
* @param mixed $returnByName If set to true the array will be by attribute name
*/
function questionAttributes($returnByName=false)
{
global $clang;
//For each question attribute include a key:
// name - the display name
// types - a string with one character representing each question typy to which the attribute applies
// help - a short explanation
// If you insert a new attribute please do it in correct alphabetical order!
$qattributes["alphasort"]=array(
"types"=>"!LO",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT("Sort the answer options alphabetically"),
"caption"=>$clang->gT('Sort answers alphabetically'));
$qattributes["answer_width"]=array(
"types"=>"ABCEF1:;",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'integer',
'min'=>'1',
'max'=>'100',
"help"=>$clang->gT('Set the percentage width of the answer column (1-100)'),
"caption"=>$clang->gT('Answer width'));
$qattributes["array_filter"]=array(
"types"=>"1ABCEF:;MPLKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT("Enter the code(s) of Multiple choice question(s) (separated by semicolons) to only show the matching answer options in this question."),
"caption"=>$clang->gT('Array filter'));
$qattributes["array_filter_exclude"]=array(
"types"=>"1ABCEF:;MPLKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT("Enter the code(s) of Multiple choice question(s) (separated by semicolons) to exclude the matching answer options in this question."),
"caption"=>$clang->gT('Array filter exclusion'));
$qattributes["array_filter_style"]=array(
"types"=>"1ABCEF:;MPLKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Hidden'),
1=>$clang->gT('Disabled')),
'default'=>0,
"help"=>$clang->gT("Specify how array-filtered sub-questions should be displayed"),
"caption"=>$clang->gT('Array filter style'));
$qattributes["assessment_value"]=array(
"types"=>"MP",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'default'=>'1',
'inputtype'=>'integer',
"help"=>$clang->gT("If one of the subquestions is marked then for each marked subquestion this value is added as assessment."),
"caption"=>$clang->gT('Assessment value'));
$qattributes["category_separator"]=array(
"types"=>"!",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Category separator'),
"caption"=>$clang->gT('Category separator'));
$qattributes["display_columns"]=array(
"types"=>"LM",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'integer',
'default'=>'1',
'min'=>'1',
'max'=>'100',
"help"=>$clang->gT('The answer options will be distributed across the number of columns set here'),
"caption"=>$clang->gT('Display columns'));
$qattributes["display_rows"]=array(
"types"=>"QSTU",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('How many rows to display'),
"caption"=>$clang->gT('Display rows'));
$qattributes["dropdown_dates"]=array(
"types"=>"D",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Use accessible dropdown boxes instead of calendar popup'),
"caption"=>$clang->gT('Display dropdown boxes'));
$qattributes["dropdown_dates_year_min"]=array(
"types"=>"D",
'category'=>$clang->gT('Display'),
'sortorder'=>110,
'inputtype'=>'text',
"help"=>$clang->gT('Minimum year value in calendar'),
"caption"=>$clang->gT('Minimum year'));
$qattributes["dropdown_dates_year_max"]=array(
"types"=>"D",
'category'=>$clang->gT('Display'),
'sortorder'=>111,
'inputtype'=>'text',
"help"=>$clang->gT('Maximum year value for calendar'),
"caption"=>$clang->gT('Maximum year'));
$qattributes["dropdown_prepostfix"]=array(
"types"=>"1",
'category'=>$clang->gT('Display'),
'sortorder'=>112,
'inputtype'=>'text',
"help"=>$clang->gT('Prefix|Suffix for dropdown lists'),
"caption"=>$clang->gT('Dropdown prefix/suffix'));
$qattributes["dropdown_separators"]=array(
"types"=>"1",
'category'=>$clang->gT('Display'),
'sortorder'=>120,
'inputtype'=>'text',
"help"=>$clang->gT('Post-Answer-Separator|Inter-Dropdownlist-Separator for dropdown lists'),
"caption"=>$clang->gT('Dropdown separator'));
$qattributes["dualscale_headerA"]=array(
"types"=>"1",
'category'=>$clang->gT('Display'),
'sortorder'=>110,
'inputtype'=>'text',
"help"=>$clang->gT('Enter a header text for the first scale'),
"caption"=>$clang->gT('Header for first scale'));
$qattributes["dualscale_headerB"]=array(
"types"=>"1",
'category'=>$clang->gT('Display'),
'sortorder'=>111,
'inputtype'=>'text',
"help"=>$clang->gT('Enter a header text for the second scale'),
"caption"=>$clang->gT('Header for second scale'));
$qattributes["equals_num_value"]=array(
"types"=>"K",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Multiple numeric inputs sum must equal this value'),
"caption"=>$clang->gT('Equals sum value'));
$qattributes["em_validation_q"]=array(
"types"=>":;ABCEFKMNPQRSTU",
'category'=>$clang->gT('Logic'),
'sortorder'=>200,
'inputtype'=>'textarea',
"help"=>$clang->gT('Boolean equation to validate the whole question.'),
"caption"=>$clang->gT('Question validation equation'));
$qattributes["em_validation_q_tip"]=array(
"types"=>":;ABCEFKMNPQRSTU",
'category'=>$clang->gT('Logic'),
'sortorder'=>210,
'inputtype'=>'textarea',
"help"=>$clang->gT('Tip to show user describing the question validation equation.'),
"caption"=>$clang->gT('Question validation tip'));
$qattributes["em_validation_sq"]=array(
"types"=>";:KQSTUN",
'category'=>$clang->gT('Logic'),
'sortorder'=>220,
'inputtype'=>'textarea',
"help"=>$clang->gT('Boolean equation to validate each sub-question.'),
"caption"=>$clang->gT('Sub-question validation equation'));
$qattributes["em_validation_sq_tip"]=array(
"types"=>";:KQSTUN",
'category'=>$clang->gT('Logic'),
'sortorder'=>230,
'inputtype'=>'textarea',
"help"=>$clang->gT('Tip to show user describing the sub-question validation equation.'),
"caption"=>$clang->gT('Sub-question validation tip'));
$qattributes["exclude_all_others"]=array(
"types"=>":ABCEFMPKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>130,
'inputtype'=>'text',
"help"=>$clang->gT('Excludes all other options if a certain answer is selected - just enter the answer code(s) seperated with a semikolon.'),
"caption"=>$clang->gT('Exclusive option'));
$qattributes["exclude_all_others_auto"]=array(
"types"=>"MP",
'category'=>$clang->gT('Logic'),
'sortorder'=>131,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('If the participant marks all options, uncheck all and check the option set in the "Exclusive option" setting'),
"caption"=>$clang->gT('Auto-check exclusive option if all others are checked'));
// Map Options
$qattributes["location_city"]=array(
"types"=>"S",
'readonly_when_active'=>true,
'category'=>$clang->gT('Location'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Yes'),
1=>$clang->gT('No')),
"help"=>$clang->gT("Store the city?"),
"caption"=>$clang->gT("Save city"));
$qattributes["location_state"]=array(
"types"=>"S",
'readonly_when_active'=>true,
'category'=>$clang->gT('Location'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Yes'),
1=>$clang->gT('No')),
"help"=>$clang->gT("Store the state?"),
"caption"=>$clang->gT("Save state"));
$qattributes["location_postal"]=array(
"types"=>"S",
'readonly_when_active'=>true,
'category'=>$clang->gT('Location'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Yes'),
1=>$clang->gT('No')),
"help"=>$clang->gT("Store the postal code?"),
"caption"=>$clang->gT("Save postal code"));
$qattributes["location_country"]=array(
"types"=>"S",
'readonly_when_active'=>true,
'category'=>$clang->gT('Location'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Yes'),
1=>$clang->gT('No')),
"help"=>$clang->gT("Store the country?"),
"caption"=>$clang->gT("Save country"));
$qattributes["location_mapservice"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>90,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Off'),
1=>$clang->gT('Google Maps')),
"help"=>$clang->gT("Activate this to show a map above the input field where the user can select a location"),
"caption"=>$clang->gT("Use mapping service"));
$qattributes["location_mapwidth"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>102,
'inputtype'=>'text',
'default'=>'500',
"help"=>$clang->gT("Width of the map in pixel"),
"caption"=>$clang->gT("Map width"));
$qattributes["location_mapheight"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>103,
'inputtype'=>'text',
'default'=>'300',
"help"=>$clang->gT("Height of the map in pixel"),
"caption"=>$clang->gT("Map height"));
$qattributes["location_nodefaultfromip"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>91,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Yes'),
1=>$clang->gT('No')),
"help"=>$clang->gT("Get the default location using the user's IP address?"),
"caption"=>$clang->gT("IP as default location"));
$qattributes["location_defaultcoordinates"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>101,
'inputtype'=>'text',
"help"=>$clang->gT('Default coordinates of the map when the page first loads. Format: latitude [space] longtitude'),
"caption"=>$clang->gT('Default position'));
$qattributes["location_mapzoom"]=array(
"types"=>"S",
'category'=>$clang->gT('Location'),
'sortorder'=>101,
'inputtype'=>'text',
'default'=>'11',
"help"=>$clang->gT("Map zoom level"),
"caption"=>$clang->gT("Zoom level"));
// End Map Options
$qattributes["hide_tip"]=array(
"types"=>"15ABCDEFGHIKLMNOPQRSTUXY!:;|",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Hide the tip that is normally shown with a question'),
"caption"=>$clang->gT('Hide tip'));
$qattributes['hidden']=array(
'types'=>'15ABCDEFGHIKLMNOPQRSTUXY!:;|*',
'category'=>$clang->gT('Display'),
'sortorder'=>101,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
'help'=>$clang->gT('Hide this question at any time. This is useful for including data using answer prefilling.'),
'caption'=>$clang->gT('Always hide this question'));
$qattributes["max_answers"]=array(
"types"=>"MPR1:;ABCEFKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>11,
'inputtype'=>'integer',
"help"=>$clang->gT('Limit the number of possible answers'),
"caption"=>$clang->gT('Maximum answers'));
$qattributes["max_num_value"]=array(
"types"=>"K",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Maximum sum value of multiple numeric input'),
"caption"=>$clang->gT('Maximum sum value'));
$qattributes["max_num_value_n"]=array(
"types"=>"NK",
'category'=>$clang->gT('Input'),
'sortorder'=>110,
'inputtype'=>'integer',
"help"=>$clang->gT('Maximum value of the numeric input'),
"caption"=>$clang->gT('Maximum value'));
$qattributes["maximum_chars"]=array(
"types"=>"STUNQK:;",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Maximum characters allowed'),
"caption"=>$clang->gT('Maximum characters'));
$qattributes["min_answers"]=array(
"types"=>"MPR1:;ABCEFKQ",
'category'=>$clang->gT('Logic'),
'sortorder'=>10,
'inputtype'=>'integer',
"help"=>$clang->gT('Ensure a minimum number of possible answers (0=No limit)'),
"caption"=>$clang->gT('Minimum answers'));
$qattributes["min_num_value"]=array(
"types"=>"K",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('The sum of the multiple numeric inputs must be greater than this value'),
"caption"=>$clang->gT('Minimum sum value'));
$qattributes["min_num_value_n"]=array(
"types"=>"NK",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'integer',
"help"=>$clang->gT('Minimum value of the numeric input'),
"caption"=>$clang->gT('Minimum value'));
$qattributes["multiflexible_max"]=array(
"types"=>":",
'category'=>$clang->gT('Display'),
'sortorder'=>112,
'inputtype'=>'text',
"help"=>$clang->gT('Maximum value for array(mult-flexible) question type'),
"caption"=>$clang->gT('Maximum value'));
$qattributes["multiflexible_min"]=array(
"types"=>":",
'category'=>$clang->gT('Display'),
'sortorder'=>110,
'inputtype'=>'text',
"help"=>$clang->gT('Minimum value for array(multi-flexible) question type'),
"caption"=>$clang->gT('Minimum value'));
$qattributes["multiflexible_step"]=array(
"types"=>":",
'category'=>$clang->gT('Display'),
'sortorder'=>111,
'inputtype'=>'text',
"help"=>$clang->gT('Step value'),
"caption"=>$clang->gT('Step value'));
$qattributes["multiflexible_checkbox"]=array(
"types"=>":",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Use checkbox layout'),
"caption"=>$clang->gT('Checkbox layout'));
$qattributes["reverse"]=array(
"types"=>"D:",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Present answer options in reverse order'),
"caption"=>$clang->gT('Reverse answer order'));
$qattributes["num_value_int_only"]=array(
"types"=>"N",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(
0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Restrict input to integer values'),
"caption"=>$clang->gT('Integer only'));
$qattributes["numbers_only"]=array(
"types"=>"Q;S*",
'category'=>$clang->gT('Other'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(
0=>$clang->gT('No'),
1=>$clang->gT('Yes')
),
'default'=>0,
"help"=>$clang->gT('Allow only numerical input'),
"caption"=>$clang->gT('Numbers only')
);
$qattributes['show_totals'] = array(
'types' => ';',
'category' => $clang->gT('Other'),
'sortorder' => 100,
'inputtype' => 'singleselect',
'options' => array(
'X' => $clang->gT('Off'),
'R' => $clang->gT('Rows'),
'C' => $clang->gT('Columns'),
'B' => $clang->gT('Both rows and columns')
),
'default' => 'X',
'help' => $clang->gT('Show totals for either rows, columns or both rows and columns'),
'caption' => $clang->gT('Show totals for')
);
$qattributes['show_grand_total'] = array(
'types' => ';',
'category' => $clang->gT('Other'),
'sortorder' => 100,
'inputtype' => 'singleselect',
'options' => array(
0 => $clang->gT('No'),
1 => $clang->gT('Yes')
),
'default' => 0,
'help' => $clang->gT('Show grand total for either columns or rows'),
'caption' => $clang->gT('Show grand total')
);
$qattributes["input_boxes"]=array(
"types"=>":",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT("Present as text input boxes instead of dropdown lists"),
"caption"=>$clang->gT("Text inputs"));
$qattributes["other_comment_mandatory"]=array(
"types"=>"PL!",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT("Make the 'Other:' comment field mandatory when the 'Other:' option is active"),
"caption"=>$clang->gT("'Other:' comment mandatory"));
$qattributes["other_numbers_only"]=array(
"types"=>"LMP",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT("Allow only numerical input for 'Other' text"),
"caption"=>$clang->gT("Numbers only for 'Other'"));
$qattributes["other_replace_text"]=array(
"types"=>"LMP!",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT("Replaces the label of the 'Other:' answer option with a custom text"),
"caption"=>$clang->gT("Label for 'Other:' option"));
$qattributes["page_break"]=array(
"types"=>"15ABCDEFGHKLMNOPQRSTUXY!:;|*",
'category'=>$clang->gT('Other'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Insert a page break before this question in printable view by setting this to Yes.'),
"caption"=>$clang->gT('Insert page break in printable view'));
$qattributes["prefix"]=array(
"types"=>"KNQS",
'category'=>$clang->gT('Display'),
'sortorder'=>10,
'inputtype'=>'text',
"help"=>$clang->gT('Add a prefix to the answer field'),
"caption"=>$clang->gT('Answer prefix'));
$qattributes["public_statistics"]=array(
"types"=>"15ABCEFGHKLMNOPRY!:*",
'category'=>$clang->gT('Other'),
'sortorder'=>80,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Show statistics of this question in the public statistics page'),
"caption"=>$clang->gT('Show in public statistics'));
$qattributes["random_order"]=array(
"types"=>"!ABCEFHKLMOPQR1:;",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Present answers in random order'),
"caption"=>$clang->gT('Random answer order'));
$qattributes["slider_layout"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>1,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Use slider layout'),
"caption"=>$clang->gT('Use slider layout'));
$qattributes["slider_min"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Slider minimum value'),
"caption"=>$clang->gT('Slider minimum value'));
$qattributes["slider_max"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Slider maximum value'),
"caption"=>$clang->gT('Slider maximum value'));
$qattributes["slider_accuracy"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Slider accuracy'),
"caption"=>$clang->gT('Slider accuracy'));
$qattributes["slider_default"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Slider initial value'),
"caption"=>$clang->gT('Slider initial value'));
$qattributes["slider_middlestart"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>10,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('The handle is displayed at the middle of the slider (this will not set the initial value)'),
"caption"=>$clang->gT('Slider starts at the middle position'));
$qattributes["slider_rating"]=array(
"types"=>"5",
'category'=>$clang->gT('Display'),
'sortorder'=>90,
'inputtype'=>'singleselect',
'options'=>array(
0=>$clang->gT('No'),
1=>$clang->gT('Yes - stars'),
2=>$clang->gT('Yes - slider with emoticon'),
),
'default'=>0,
"help"=>$clang->gT('Use slider layout'),
"caption"=>$clang->gT('Use slider layout'));
$qattributes["slider_showminmax"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Display min and max value under the slider'),
"caption"=>$clang->gT('Display slider min and max value'));
$qattributes["slider_separator"]=array(
"types"=>"K",
'category'=>$clang->gT('Slider'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Answer|Left-slider-text|Right-slider-text separator character'),
"caption"=>$clang->gT('Slider left/right text separator'));
$qattributes["suffix"]=array(
"types"=>"KNQS",
'category'=>$clang->gT('Display'),
'sortorder'=>11,
'inputtype'=>'text',
"help"=>$clang->gT('Add a suffix to the answer field'),
"caption"=>$clang->gT('Answer suffix'));
$qattributes["text_input_width"]=array(
"types"=>"KNSTUQ;",
'category'=>$clang->gT('Display'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT('Width of text input box'),
"caption"=>$clang->gT('Input box width'));
$qattributes["use_dropdown"]=array(
"types"=>"1F",
'category'=>$clang->gT('Display'),
'sortorder'=>112,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>0,
"help"=>$clang->gT('Use dropdown boxes instead of list of radio buttons'),
"caption"=>$clang->gT('Use dropdown boxes'));
$qattributes["dropdown_size"]=array(
"types"=>"!", // TODO add these later? "1F",
'category'=>$clang->gT('Display'),
'sortorder'=>200,
'inputtype'=>'text',
'default'=>0,
"help"=>$clang->gT('For list dropdown boxes, show up to this many rows'),
"caption"=>$clang->gT('Height of dropdown'));
$qattributes["dropdown_prefix"]=array(
"types"=>"!", // TODO add these later? "1F",
'category'=>$clang->gT('Display'),
'sortorder'=>201,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('None'),
1=>$clang->gT('Order'),
),
'default'=>0,
"help"=>$clang->gT('Accelerator keys for list items'),
"caption"=>$clang->gT('Prefix for list items'));
$qattributes["scale_export"]=array(
"types"=>"CEFGHLMOPY1!:*",
'category'=>$clang->gT('Other'),
'sortorder'=>100,
'inputtype'=>'singleselect',
'options'=>array(0=>$clang->gT('Default'),
1=>$clang->gT('Nominal'),
2=>$clang->gT('Ordinal'),
3=>$clang->gT('Scale')),
'default'=>0,
"help"=>$clang->gT("Set a specific SPSS export scale type for this question"),
"caption"=>$clang->gT('SPSS export scale type'));
//Timer attributes
$qattributes["time_limit"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>90,
"inputtype"=>"integer",
"help"=>$clang->gT("Limit time to answer question (in seconds)"),
"caption"=>$clang->gT("Time limit"));
$qattributes["time_limit_action"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>92,
'inputtype'=>'singleselect',
'options'=>array(1=>$clang->gT('Warn and move on'),
2=>$clang->gT('Move on without warning'),
3=>$clang->gT('Disable only')),
"help"=>$clang->gT("Action to perform when time limit is up"),
"caption"=>$clang->gT("Time limit action"));
$qattributes["time_limit_disable_next"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>94,
"inputtype"=>"singleselect",
'default'=>0,
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
"help"=>$clang->gT("Disable the next button until time limit expires"),
"caption"=>$clang->gT("Time limit disable next"));
$qattributes["time_limit_disable_prev"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>96,
"inputtype"=>"singleselect",
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
"help"=>$clang->gT("Disable the prev button until the time limit expires"),
"caption"=>$clang->gT("Time limit disable prev"));
$qattributes["time_limit_countdown_message"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>98,
"inputtype"=>"textarea",
"help"=>$clang->gT("The text message that displays in the countdown timer during the countdown"),
"caption"=>$clang->gT("Time limit countdown message"));
$qattributes["time_limit_timer_style"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>100,
"inputtype"=>"textarea",
"help"=>$clang->gT("CSS Style for the message that displays in the countdown timer during the countdown"),
"caption"=>$clang->gT("Time limit timer CSS style"));
$qattributes["time_limit_message_delay"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>102,
"inputtype"=>"integer",
"help"=>$clang->gT("Display the 'time limit expiry message' for this many seconds before performing the 'time limit action' (defaults to 1 second if left blank)"),
"caption"=>$clang->gT("Time limit expiry message display time"));
$qattributes["time_limit_message"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>104,
"inputtype"=>"textarea",
"help"=>$clang->gT("The message to display when the time limit has expired (a default message will display if this setting is left blank)"),
"caption"=>$clang->gT("Time limit expiry message"));
$qattributes["time_limit_message_style"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>106,
"inputtype"=>"textarea",
"help"=>$clang->gT("CSS style for the 'time limit expiry message'"),
"caption"=>$clang->gT("Time limit message CSS style"));
$qattributes["time_limit_warning"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>108,
"inputtype"=>"integer",
"help"=>$clang->gT("Display a 'time limit warning' when there are this many seconds remaining in the countdown (warning will not display if left blank)"),
"caption"=>$clang->gT("1st time limit warning message timer"));
$qattributes["time_limit_warning_display_time"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>110,
"inputtype"=>"integer",
"help"=>$clang->gT("The 'time limit warning' will stay visible for this many seconds (will not turn off if this setting is left blank)"),
"caption"=>$clang->gT("1st time limit warning message display time"));
$qattributes["time_limit_warning_message"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>112,
"inputtype"=>"textarea",
"help"=>$clang->gT("The message to display as a 'time limit warning' (a default warning will display if this is left blank)"),
"caption"=>$clang->gT("1st time limit warning message"));
$qattributes["time_limit_warning_style"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>114,
"inputtype"=>"textarea",
"help"=>$clang->gT("CSS style used when the 'time limit warning' message is displayed"),
"caption"=>$clang->gT("1st time limit warning CSS style"));
$qattributes["time_limit_warning_2"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>116,
"inputtype"=>"integer",
"help"=>$clang->gT("Display the 2nd 'time limit warning' when there are this many seconds remaining in the countdown (warning will not display if left blank)"),
"caption"=>$clang->gT("2nd time limit warning message timer"));
$qattributes["time_limit_warning_2_display_time"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>118,
"inputtype"=>"integer",
"help"=>$clang->gT("The 2nd 'time limit warning' will stay visible for this many seconds (will not turn off if this setting is left blank)"),
"caption"=>$clang->gT("2nd time limit warning message display time"));
$qattributes["time_limit_warning_2_message"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>120,
"inputtype"=>"textarea",
"help"=>$clang->gT("The 2nd message to display as a 'time limit warning' (a default warning will display if this is left blank)"),
"caption"=>$clang->gT("2nd time limit warning message"));
$qattributes["time_limit_warning_2_style"]=array(
"types"=>"STUX",
'category'=>$clang->gT('Timer'),
'sortorder'=>122,
"inputtype"=>"textarea",
"help"=>$clang->gT("CSS style used when the 2nd 'time limit warning' message is displayed"),
"caption"=>$clang->gT("2nd time limit warning CSS style"));
$qattributes["show_title"]=array(
"types"=>"|",
'category'=>$clang->gT('File metadata'),
'sortorder'=>124,
"inputtype"=>"singleselect",
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>1,
"help"=>$clang->gT("Is the participant required to give a title to the uploaded file?"),
"caption"=>$clang->gT("Show title"));
$qattributes["show_comment"]=array(
"types"=>"|",
'category'=>$clang->gT('File metadata'),
'sortorder'=>126,
"inputtype"=>"singleselect",
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>1,
"help"=>$clang->gT("Is the participant required to give a comment to the uploaded file?"),
"caption"=>$clang->gT("Show comment"));
$qattributes["max_filesize"]=array(
"types"=>"|",
'category'=>$clang->gT('Other'),
'sortorder'=>128,
"inputtype"=>"integer",
'default'=>1024,
"help"=>$clang->gT("The participant cannot upload a single file larger than this size"),
"caption"=>$clang->gT("Maximum file size allowed (in KB)"));
$qattributes["max_num_of_files"]=array(
"types"=>"|",
'category'=>$clang->gT('Other'),
'sortorder'=>130,
"inputtype"=>"text",
'default'=>1,
"help"=>$clang->gT("Maximum number of files that the participant can upload for this question"),
"caption"=>$clang->gT("Max number of files"));
$qattributes["min_num_of_files"]=array(
"types"=>"|",
'category'=>$clang->gT('Other'),
'sortorder'=>132,
"inputtype"=>"text",
'default'=>0,
"help"=>$clang->gT("Minimum number of files that the participant must upload for this question"),
"caption"=>$clang->gT("Min number of files"));
$qattributes["allowed_filetypes"]=array(
"types"=>"|",
'category'=>$clang->gT('Other'),
'sortorder'=>134,
'inputtype'=>'text',
'default'=>"png, gif, doc, odt",
"help"=>$clang->gT("Allowed file types in comma separated format. e.g. pdf,doc,odt"),
"caption"=>$clang->gT("Allowed file types"));
$qattributes["random_group"]=array(
"types"=>"15ABCDEFGHIKLMNOPQRSTUXY!:;|",
'category'=>$clang->gT('Logic'),
'sortorder'=>100,
'inputtype'=>'text',
"help"=>$clang->gT("Place questions into a specified randomization group, all questions included in the specified group will appear in a random order"),
"caption"=>$clang->gT("Randomization group name"));
// This is added to support historical behavior. Early versions of 1.92 used a value of "No", so if there was a min_sum_value or equals_sum_value, the question was not valid
// unless those criteria were met. In later releases of 1.92, the default was changed so that missing values were allowed even if those attributes were set
// This attribute lets authors control whether missing values should be allowed in those cases without needing to set min_answers
// Existing surveys will use the old behavior, but if the author edits the question, the default will be the new behavior.
$qattributes["value_range_allows_missing"]=array(
"types"=>"K",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
"inputtype"=>"singleselect",
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>1,
"help"=>$clang->gT("Is no answer (missing) allowed when either 'Equals sum value' or 'Minimum sum value' are set?"),
"caption"=>$clang->gT("Value range allows missing"));
//This builds a more useful array (don't modify)
if ($returnByName==false)
{
foreach($qattributes as $qname=>$qvalue)
{
for ($i=0; $i<=strlen($qvalue['types'])-1; $i++)
{
$qat[substr($qvalue['types'], $i, 1)][]=array("name"=>$qname,
"inputtype"=>$qvalue['inputtype'],
"category"=>$qvalue['category'],
"sortorder"=>$qvalue['sortorder'],
"readonly"=>isset($qvalue['readonly_when_active'])?$qvalue['readonly_when_active']:false,
"options"=>isset($qvalue['options'])?$qvalue['options']:'',
"default"=>isset($qvalue['default'])?$qvalue['default']:'',
"help"=>$qvalue['help'],
"caption"=>$qvalue['caption']);
}
}
return $qat;
}
else {
return $qattributes;
}
}
function CategorySort($a, $b)
{
$result=strnatcasecmp($a['category'], $b['category']);
if ($result==0)
{
$result=$a['sortorder']-$b['sortorder'];
}
return $result;
}
// make sure the given string (which comes from a POST or GET variable)
// is safe to use in MySQL. This does nothing if gpc_magic_quotes is on.
function auto_escape($str) {
global $connect;
return $connect->escape($str);
}
// the opposite of the above: takes a POST or GET variable which may or
// may not have been 'auto-quoted', and return the *unquoted* version.
// this is useful when the value is destined for a web page (eg) not
// a SQL query.
function auto_unescape($str) {
if (!isset($str)) {return null;};
return $str;
}
// make a string safe to include in an HTML 'value' attribute.
function html_escape($str) {
// escape newline characters, too, in case we put a value from
// a TEXTAREA into an value attribute.
return str_replace(array("\x0A","\x0D"),array("
","
"),
htmlspecialchars( $str, ENT_QUOTES ));
}
// make a string safe to include in a JavaScript String parameter.
function javascript_escape($str, $strip_tags=false, $htmldecode=false) {
$new_str ='';
if ($htmldecode==true) {
$str=html_entity_decode($str,ENT_QUOTES,'UTF-8');
}
if ($strip_tags==true)
{
$str=strip_tags($str);
}
return str_replace(array('\'','"', "\n", "\r"),
array("\\'",'\u0022', "\\n",'\r'),
$str);
}
// This function returns the header as result string
// If you want to echo the header use doHeader() !
function getHeader($meta = false)
{
global $embedded, $surveyid, $rooturl, $defaultlang, $js_header_includes, $css_header_includes;
$js_header_includes = array_unique($js_header_includes);
$css_header_includes = array_unique($css_header_includes);
$interviewer=returnglobal('interviewer');
if (empty($interviewer))
{
$interviewer = false;
}
if (!isset($_SESSION['interviewer'])) {
$_SESSION['interviewer'] = $interviewer;
}
if ($_SESSION['interviewer'])
{
$js_header_includes[] = '/../../js/popup.js'; //queXS Addition
include_once("quexs.php");
if (AUTO_LOGOUT_MINUTES !== false)
{
$js_header_includes[] = $rooturl . "/../../js/childnap.js"; //queXS Addition
}
}
if (isset($_SESSION['s_lang']) && $_SESSION['s_lang'])
{
$surveylanguage= $_SESSION['s_lang'];
}
elseif (isset($surveyid) && $surveyid)
{
$surveylanguage=GetBaseLanguageFromSurveyID($surveyid);
}
else
{
$surveylanguage=$defaultlang;
}
$js_header = ''; $css_header='';
foreach ($js_header_includes as $jsinclude)
{
if (substr($jsinclude,0,4) == 'http')
$js_header .= "\n";
else
$js_header .= "\n";
}
foreach ($css_header_includes as $cssinclude)
{
$css_header .= "\n";
}
$header= "\n"
. "\n\t\n"
. $css_header
. "\n"
. "\n"
. "\n"
. ""
. ""
. $js_header;
if ($meta)
$header .= $meta;
if ( !$embedded )
{
return $header;
}
else
{
global $embedded_headerfunc;
if ( function_exists( $embedded_headerfunc ) )
return $embedded_headerfunc($header);
}
}
function doHeader()
{
echo getHeader();
}
function doAdminFooter()
{
echo getAdminFooter();
}
function getAdminFooter($url, $explanation)
{
global $js_admin_includes, $homeurl;
global $versionnumber, $buildnumber, $setfont, $imageurl, $clang;
if ($buildnumber != "")
{
$buildtext="Build $buildnumber";
}
else
{
$buildtext="";
}
//If user is not logged in, don't print the version number information in the footer.
$versiontitle=$clang->gT('Version');
if(!isset($_SESSION['loginID']))
{
$versionnumber="";
$buildtext="";
$versiontitle="";
}
$strHTMLFooter = "\n";
$js_admin_includes = array_unique($js_admin_includes);
foreach ($js_admin_includes as $jsinclude)
{
$strHTMLFooter .= "\n";
}
$strHTMLFooter.="\n";
return $strHTMLFooter;
}
/**
* This function returns the header for the printable survey
* @return String
*
*/
function getPrintableHeader()
{
global $rooturl,$homeurl;
$headelements = '
';
return $headelements;
}
// This function returns the Footer as result string
// If you want to echo the Footer use doFooter() !
function getFooter()
{
global $embedded;
if ( !$embedded )
{
return "\n\n\t