From eee83acce7189e8c253d895e1ea1db0fcc1bd7b7 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Sun, 22 Jan 2012 17:32:12 +0000 Subject: [PATCH] Fixed issue #5628: SQL error after setting a filter in statistics and removing it again git-svn-id: file:///Users/Shitiz/Downloads/lssvn/source/limesurvey_dev@12156 b72ed6b6-b9f8-46b5-92b4-906544132732 --- admin/statistics_function.php | 5226 ++++++------ common_functions.php | 14253 ++++++++++++++++---------------- 2 files changed, 9731 insertions(+), 9748 deletions(-) diff --git a/admin/statistics_function.php b/admin/statistics_function.php index 4bacf28bee7..68bb2b5cf98 100644 --- a/admin/statistics_function.php +++ b/admin/statistics_function.php @@ -1,210 +1,210 @@ alert("HI");'; - */ - -//split up results to extend statistics -> NOT WORKING YET! DO NOT ENABLE THIS! -//$showcombinedresults = 0; - - - - - -//don't call this script directly! -if (isset($_REQUEST['homedir'])) {die('You cannot start this script directly');} - - -/** -* Generates statistics -* -* @param int $surveyid The survey id -* @param mixed $allfields -* @param mixed $q2show -* @param mixed $usegraph -* @param string $outputType Optional - Can be xls, html or pdf - Defaults to pdf -* @param string $pdfOutput Sets the target for the PDF output: DD=File download , F=Save file to local disk -* @param string $statlangcode Lamguage for statistics -* @param mixed $browse Show browse buttons -* @return buffer -*/ -function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, $outputType='pdf', $pdfOutput='I',$statlangcode=null, $browse = true) -{ - //$allfields =""; - global $connect, $dbprefix, $clang, - $rooturl, $rootdir, $homedir, $homeurl, $tempdir, $tempurl, $scriptname, $imagedir, - $chartfontfile, $chartfontsize, $admintheme, $pdfdefaultfont, $pdffontsize, $showaggregateddata; - - $fieldmap=createFieldMap($surveyid, "full"); - - if (is_null($statlangcode)) - { - $statlang=$clang; - } - else - { - $statlang = new limesurvey_lang($statlangcode); - } + /* + * LimeSurvey + * Copyright (C) 2007 The LimeSurvey Project Team / Carsten Schmitz + * All rights reserved. + * License: GNU/GPL License v2 or later, see LICENSE.php + * LimeSurvey is free software. This version may have been modified pursuant + * to the GNU General Public License, and as distributed it includes or + * is derivative of works licensed under the GNU General Public License or + * other free or open source software licenses. + * See COPYRIGHT.php for copyright notices and details. + * + * $Id$ + * + */ /* - * this variable is used in the function shortencode() which cuts off a question/answer title - * after $maxchars and shows the rest as tooltip (in html mode) - */ - $maxchars = 13; - //we collect all the html-output within this variable - $statisticsoutput =''; - /** - * $outputType: html || pdf || - */ + * We need this later: + * 1 - Array Dual Scale + * 5 - 5 Point Choice + * A - Array (5 Point Choice) + * B - Array (10 Point Choice) + * C - Array (Yes/No/Uncertain) + * D - Date + * E - Array (Increase, Same, Decrease) + * F - Array + * G - Gender + * H - Array by column + * I - Language Switch + * K - Multiple Numerical Input + * L - List (Radio) + * M - Multiple choice + * N - Numerical Input + * O - List With Comment + * P - Multiple choice with comments + * Q - Multiple Short Text + * R - Ranking + * S - Short Free Text + * T - Long Free Text + * U - Huge Free Text + * X - Boilerplate Question + * Y - Yes/No + * ! - List (Dropdown) + * : - Array multiple drop down + * ; - Array multiple texts + * | - File Upload + + + Debugging help: + echo ''; + */ + + //split up results to extend statistics -> NOT WORKING YET! DO NOT ENABLE THIS! + //$showcombinedresults = 0; + + + + + + //don't call this script directly! + if (isset($_REQUEST['homedir'])) {die('You cannot start this script directly');} + + /** - * get/set Survey Details - */ + * Generates statistics + * + * @param int $surveyid The survey id + * @param mixed $allfields + * @param mixed $q2show + * @param mixed $usegraph + * @param string $outputType Optional - Can be xls, html or pdf - Defaults to pdf + * @param string $pdfOutput Sets the target for the PDF output: DD=File download , F=Save file to local disk + * @param string $statlangcode Lamguage for statistics + * @param mixed $browse Show browse buttons + * @return buffer + */ + function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, $outputType='pdf', $pdfOutput='I',$statlangcode=null, $browse = true) + { + //$allfields =""; + global $connect, $dbprefix, $clang, + $rooturl, $rootdir, $homedir, $homeurl, $tempdir, $tempurl, $scriptname, $imagedir, + $chartfontfile, $chartfontsize, $admintheme, $pdfdefaultfont, $pdffontsize, $showaggregateddata; + + $fieldmap=createFieldMap($surveyid, "full"); + + if (is_null($statlangcode)) + { + $statlang=$clang; + } + else + { + $statlang = new limesurvey_lang($statlangcode); + } - //no survey ID? -> come and get one - if (!isset($surveyid)) {$surveyid=returnglobal('sid');} + /* + * this variable is used in the function shortencode() which cuts off a question/answer title + * after $maxchars and shows the rest as tooltip (in html mode) + */ + $maxchars = 13; + //we collect all the html-output within this variable + $statisticsoutput =''; + /** + * $outputType: html || pdf || + */ + /** + * get/set Survey Details + */ - //Get an array of codes of all available languages in this survey - $surveylanguagecodes = GetAdditionalLanguagesFromSurveyID($surveyid); - $surveylanguagecodes[] = GetBaseLanguageFromSurveyID($surveyid); + //no survey ID? -> come and get one + if (!isset($surveyid)) {$surveyid=returnglobal('sid');} - // Set language for questions and answers to base language of this survey - $language=$statlangcode; + //Get an array of codes of all available languages in this survey + $surveylanguagecodes = GetAdditionalLanguagesFromSurveyID($surveyid); + $surveylanguagecodes[] = GetBaseLanguageFromSurveyID($surveyid); - if ($usegraph==1) - { - //for creating graphs we need some more scripts which are included here - require_once(dirname(__FILE__).'/../classes/pchart/pchart/pChart.class'); - require_once(dirname(__FILE__).'/../classes/pchart/pchart/pData.class'); - require_once(dirname(__FILE__).'/../classes/pchart/pchart/pCache.class'); - $MyCache = new pCache($tempdir.'/'); - - //pick the best font file if font setting is 'auto' - if ($chartfontfile=='auto') + // Set language for questions and answers to base language of this survey + $language=$statlangcode; + + if ($usegraph==1) { - $chartfontfile='vera.ttf'; - if ( $language=='ar') + //for creating graphs we need some more scripts which are included here + require_once(dirname(__FILE__).'/../classes/pchart/pchart/pChart.class'); + require_once(dirname(__FILE__).'/../classes/pchart/pchart/pData.class'); + require_once(dirname(__FILE__).'/../classes/pchart/pchart/pCache.class'); + $MyCache = new pCache($tempdir.'/'); + + //pick the best font file if font setting is 'auto' + if ($chartfontfile=='auto') { - $chartfontfile='KacstOffice.ttf'; - } - elseif ($language=='fa' ) - { - $chartfontfile='KacstFarsi.ttf'; - } + $chartfontfile='vera.ttf'; + if ( $language=='ar') + { + $chartfontfile='KacstOffice.ttf'; + } + elseif ($language=='fa' ) + { + $chartfontfile='KacstFarsi.ttf'; + } + } } - } - if($q2show=='all' ) - { - $summarySql=" SELECT gid, parent_qid, qid, type " - ." FROM {$dbprefix}questions WHERE parent_qid=0" - ." AND sid=$surveyid "; + if($q2show=='all' ) + { + $summarySql=" SELECT gid, parent_qid, qid, type " + ." FROM {$dbprefix}questions WHERE parent_qid=0" + ." AND sid=$surveyid "; - $summaryRs = db_execute_assoc($summarySql); + $summaryRs = db_execute_assoc($summarySql); - foreach($summaryRs as $field) - { - $myField = $surveyid."X".$field['gid']."X".$field['qid']; - - // Multiple choice get special treatment - if ($field['type'] == "M") {$myField = "M$myField";} - if ($field['type'] == "P") {$myField = "P$myField";} - //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) - if ($field['type'] == "N") {$myField = "N$myField";} - - if ($field['type'] == "|") {$myField = "|$myField";} - - if ($field['type'] == "Q") {$myField = "Q$myField";} - // textfields get special treatment - if ($field['type'] == "S" || $field['type'] == "T" || $field['type'] == "U"){$myField = "T$myField";} - //statistics for Date questions are not implemented yet. - if ($field['type'] == "D") {$myField = "D$myField";} - if ($field['type'] == "F" || $field['type'] == "H") + foreach($summaryRs as $field) { - //Get answers. We always use the answer code because the label might be too long elsewise - $query = "SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='".$field['qid']."' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; - $result = db_execute_num($query) or safe_die ("Couldn't get answers!
$query
".$connect->ErrorMsg()); - $counter2=0; - - //check all the answers - while ($row=$result->FetchRow()) + $myField = $surveyid."X".$field['gid']."X".$field['qid']; + + // Multiple choice get special treatment + if ($field['type'] == "M") {$myField = "M$myField";} + if ($field['type'] == "P") {$myField = "P$myField";} + //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) + if ($field['type'] == "N") {$myField = "N$myField";} + + if ($field['type'] == "|") {$myField = "|$myField";} + + if ($field['type'] == "Q") {$myField = "Q$myField";} + // textfields get special treatment + if ($field['type'] == "S" || $field['type'] == "T" || $field['type'] == "U"){$myField = "T$myField";} + //statistics for Date questions are not implemented yet. + if ($field['type'] == "D") {$myField = "D$myField";} + if ($field['type'] == "F" || $field['type'] == "H") { - $myField = "$myField{$row[0]}"; - } - //$myField = "{$surveyid}X{$flt[1]}X{$flt[0]}{$row[0]}[]"; + //Get answers. We always use the answer code because the label might be too long elsewise + $query = "SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='".$field['qid']."' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; + $result = db_execute_num($query) or safe_die ("Couldn't get answers!
$query
".$connect->ErrorMsg()); + $counter2=0; + + //check all the answers + while ($row=$result->FetchRow()) + { + $myField = "$myField{$row[0]}"; + } + //$myField = "{$surveyid}X{$flt[1]}X{$flt[0]}{$row[0]}[]"; - } - if($q2show=='all') - $summary[]=$myField; + } + if($q2show=='all') + $summary[]=$myField; - //$allfields[]=$myField; + //$allfields[]=$myField; + } } - } - else - { - // This gets all the 'to be shown questions' from the POST and puts these into an array - if (!is_array($q2show)) - $summary=returnglobal('summary'); else - $summary = $q2show; - - //print_r($_POST); - //if $summary isn't an array we create one - if (isset($summary) && !is_array($summary)) { - $summary = explode("+", $summary); + // This gets all the 'to be shown questions' from the POST and puts these into an array + if (!is_array($q2show)) + $summary=returnglobal('summary'); + else + $summary = $q2show; + + //print_r($_POST); + //if $summary isn't an array we create one + if (isset($summary) && !is_array($summary)) + { + $summary = explode("+", $summary); + } } - } - /* Some variable depend on output type, actually : only line feed */ - switch($outputType) + /* Some variable depend on output type, actually : only line feed */ + switch($outputType) { case 'xls': $linefeed = "\n"; @@ -217,1176 +217,1204 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, break; default: - break; + break; } - /** - * pdf Config - */ - if($outputType=='pdf') - { - require_once('classes/tcpdf/config/lang/eng.php'); - global $l; - $l['w_page'] = $statlang->gT("Page",'unescaped'); - require_once('classes/tcpdf/mypdf.php'); + /** + * pdf Config + */ + if($outputType=='pdf') + { + require_once('classes/tcpdf/config/lang/eng.php'); + global $l; + $l['w_page'] = $statlang->gT("Page",'unescaped'); + require_once('classes/tcpdf/mypdf.php'); - // create new PDF document - $pdf = new MyPDF(); - $pdf->SetFont($pdfdefaultfont,'',$pdffontsize); + // create new PDF document + $pdf = new MyPDF(); + $pdf->SetFont($pdfdefaultfont,'',$pdffontsize); - $surveyInfo = getSurveyInfo($surveyid,$language); + $surveyInfo = getSurveyInfo($surveyid,$language); - // set document information - $pdf->SetCreator(PDF_CREATOR); - $pdf->SetAuthor('LimeSurvey'); - $pdf->SetTitle('Statistic survey '.$surveyid); - $pdf->SetSubject($surveyInfo['surveyls_title']); - $pdf->SetKeywords('LimeSurvey, Statistics, Survey '.$surveyid.''); - $pdf->SetDisplayMode('fullpage', 'two'); + // set document information + $pdf->SetCreator(PDF_CREATOR); + $pdf->SetAuthor('LimeSurvey'); + $pdf->SetTitle('Statistic survey '.$surveyid); + $pdf->SetSubject($surveyInfo['surveyls_title']); + $pdf->SetKeywords('LimeSurvey, Statistics, Survey '.$surveyid.''); + $pdf->SetDisplayMode('fullpage', 'two'); - // set header and footer fonts - $pdf->setHeaderFont(Array($pdfdefaultfont, '', PDF_FONT_SIZE_MAIN)); - $pdf->setFooterFont(Array($pdfdefaultfont, '', PDF_FONT_SIZE_DATA)); + // set header and footer fonts + $pdf->setHeaderFont(Array($pdfdefaultfont, '', PDF_FONT_SIZE_MAIN)); + $pdf->setFooterFont(Array($pdfdefaultfont, '', PDF_FONT_SIZE_DATA)); - // set default header data - // the path looks awkward - did not find a better solution to set the image path? - $pdf->SetHeaderData("statistics.png", 10, $statlang->gT("Quick statistics",'unescaped') , $statlang->gT("Survey")." ".$surveyid." '".FlattenText($surveyInfo['surveyls_title'],true,'UTF-8')."'"); + // set default header data + // the path looks awkward - did not find a better solution to set the image path? + $pdf->SetHeaderData("statistics.png", 10, $statlang->gT("Quick statistics",'unescaped') , $statlang->gT("Survey")." ".$surveyid." '".FlattenText($surveyInfo['surveyls_title'],true,'UTF-8')."'"); - // set default monospaced font - $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); + // set default monospaced font + $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); - //set margins - $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); - $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); - $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); + //set margins + $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); + $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); + $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); - //set auto page breaks - $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); + //set auto page breaks + $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); - //set image scale factor - $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); + //set image scale factor + $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); - //set some language-dependent strings - $pdf->setLanguageArray($l); - } - if($outputType=='xls') - { - /** - * Initiate the Spreadsheet_Excel_Writer - */ - include_once(dirname(__FILE__)."/classes/pear/Spreadsheet/Excel/Writer.php"); - if($pdfOutput=='F') - $workbook = new Spreadsheet_Excel_Writer($tempdir.'/statistic-survey'.$surveyid.'.xls'); - else - $workbook = new Spreadsheet_Excel_Writer(); + //set some language-dependent strings + $pdf->setLanguageArray($l); + } + if($outputType=='xls') + { + /** + * Initiate the Spreadsheet_Excel_Writer + */ + include_once(dirname(__FILE__)."/classes/pear/Spreadsheet/Excel/Writer.php"); + if($pdfOutput=='F') + $workbook = new Spreadsheet_Excel_Writer($tempdir.'/statistic-survey'.$surveyid.'.xls'); + else + $workbook = new Spreadsheet_Excel_Writer(); - $workbook->setVersion(8); - // Inform the module that our data will arrive as UTF-8. - // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) - if (!empty($tempdir)) { - $workbook->setTempDir($tempdir); + $workbook->setVersion(8); + // Inform the module that our data will arrive as UTF-8. + // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) + if (!empty($tempdir)) { + $workbook->setTempDir($tempdir); + } + if ($pdfOutput!='F') + $workbook->send('statistic-survey'.$surveyid.'.xls'); + + // Creating the first worksheet + $sheet =& $workbook->addWorksheet(utf8_decode('results-survey'.$surveyid)); + $sheet->setInputEncoding('utf-8'); + $sheet->setColumn(0,20,20); + $separator="~|"; } - if ($pdfOutput!='F') - $workbook->send('statistic-survey'.$surveyid.'.xls'); - - // Creating the first worksheet - $sheet =& $workbook->addWorksheet(utf8_decode('results-survey'.$surveyid)); - $sheet->setInputEncoding('utf-8'); - $sheet->setColumn(0,20,20); - $separator="~|"; - } - /** - * Start generating - */ + /** + * Start generating + */ - // creates array of post variable names - for (reset($_POST); $key=key($_POST); next($_POST)) { $postvars[]=$key;} + // creates array of post variable names + for (reset($_POST); $key=key($_POST); next($_POST)) { $postvars[]=$key;} - $aQuestionMap=array(); - foreach ($fieldmap as $field) - { - if(isset($field['qid']) && $field['qid']!='') - $aQuestionMap[]=$field['sid'].'X'.$field['gid'].'X'.$field['qid']; - } + $aQuestionMap=array(); + foreach ($fieldmap as $field) + { + if(isset($field['qid']) && $field['qid']!='') + $aQuestionMap[]=$field['sid'].'X'.$field['gid'].'X'.$field['qid']; + } - /* - * Iterate through postvars to create "nice" data for SQL later. - * - * Remember there might be some filters applied which have to be put into an SQL statement - */ - if(isset($postvars)) + /* + * Iterate through postvars to create "nice" data for SQL later. + * + * Remember there might be some filters applied which have to be put into an SQL statement + */ + if(isset($postvars)) - foreach ($postvars as $pv) - { - //Only do this if there is actually a value for the $pv - if (in_array($pv, $allfields) || in_array(substr($pv,1),$aQuestionMap) || in_array($pv,$aQuestionMap) || (($pv[0]=='D' || $pv[0]=='N' || $pv[0]=='K') && in_array(substr($pv,1,strlen($pv)-2),$aQuestionMap))) - { - $firstletter=substr($pv,0,1); - /* - * these question types WON'T be handled here: - * M = Multiple choice - * T - Long Free Text - * Q - Multiple Short Text - * D - Date - * N - Numerical Input - * | - File Upload - * K - Multiple Numerical Input - */ - if ($pv != "sid" && $pv != "display" && $firstletter != "M" && $firstletter != "P" && $firstletter != "T" && - $firstletter != "Q" && $firstletter != "D" && $firstletter != "N" && $firstletter != "K" && $firstletter != "|" && - $pv != "summary" && substr($pv, 0, 2) != "id" && substr($pv, 0, 9) != "datestamp") //pull out just the fieldnames + foreach ($postvars as $pv) { - //put together some SQL here - $thisquestion = db_quote_id($pv)." IN ("; - - foreach ($_POST[$pv] as $condition) + //Only do this if there is actually a value for the $pv + if (in_array($pv, $allfields) || in_array(substr($pv,1),$aQuestionMap) || in_array($pv,$aQuestionMap) || (($pv[0]=='D' || $pv[0]=='N' || $pv[0]=='K') && in_array(substr($pv,1,strlen($pv)-2),$aQuestionMap))) { - $thisquestion .= "'$condition', "; - } - - $thisquestion = substr($thisquestion, 0, -2) - . ")"; + $firstletter=substr($pv,0,1); + /* + * these question types WON'T be handled here: + * M = Multiple choice + * T - Long Free Text + * Q - Multiple Short Text + * D - Date + * N - Numerical Input + * | - File Upload + * K - Multiple Numerical Input + */ + if ($pv != "sid" && $pv != "display" && $firstletter != "M" && $firstletter != "P" && $firstletter != "T" && + $firstletter != "Q" && $firstletter != "D" && $firstletter != "N" && $firstletter != "K" && $firstletter != "|" && + $pv != "summary" && substr($pv, 0, 2) != "id" && substr($pv, 0, 9) != "datestamp") //pull out just the fieldnames + { + //put together some SQL here + $thisquestion = db_quote_id($pv)." IN ("; - //we collect all the to be selected data in this array - $selects[]=$thisquestion; - } + foreach ($_POST[$pv] as $condition) + { + $thisquestion .= "'$condition', "; + } - //M - Multiple choice - //P - Multiple choice with comments - elseif ($firstletter == "M" || $firstletter == "P") - { - $mselects=array(); - //create a list out of the $pv array - list($lsid, $lgid, $lqid) = explode("X", $pv); + $thisquestion = substr($thisquestion, 0, -2) + . ")"; - $aquery="SELECT title FROM ".db_table_name("questions")." WHERE parent_qid=$lqid AND language='{$language}' and scale_id=0 ORDER BY question_order"; - $aresult=db_execute_num($aquery) or safe_die ("Couldn't get subquestions
$aquery
".$connect->ErrorMsg()); + //we collect all the to be selected data in this array + $selects[]=$thisquestion; + } - // go through every possible answer - while ($arow=$aresult->FetchRow()) - { - // only add condition if answer has been chosen - if (in_array($arow[0], $_POST[$pv])) + //M - Multiple choice + //P - Multiple choice with comments + elseif ($firstletter == "M" || $firstletter == "P") { - $mselects[]=db_quote_id(substr($pv, 1, strlen($pv)).$arow[0])." = 'Y'"; - } - } - if ($mselects) - { - $thismulti=implode(" OR ", $mselects); - $selects[]="($thismulti)"; - $mselects = ""; - } - } + $mselects=array(); + //create a list out of the $pv array + list($lsid, $lgid, $lqid) = explode("X", $pv); + $aquery="SELECT title FROM ".db_table_name("questions")." WHERE parent_qid=$lqid AND language='{$language}' and scale_id=0 ORDER BY question_order"; + $aresult=db_execute_num($aquery) or safe_die ("Couldn't get subquestions
$aquery
".$connect->ErrorMsg()); - //N - Numerical Input - //K - Multiple Numerical Input - elseif ($firstletter == "N" || $firstletter == "K") - { - //value greater than - if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") - { - $selects[]=db_quote_id(substr($pv, 1, -1))." > ".sanitize_int($_POST[$pv]); - } + // go through every possible answer + while ($arow=$aresult->FetchRow()) + { + // only add condition if answer has been chosen + if (in_array($arow[0], $_POST[$pv])) + { + $mselects[]=db_quote_id(substr($pv, 1, strlen($pv)).$arow[0])." = 'Y'"; + } + } + if ($mselects) + { + $thismulti=implode(" OR ", $mselects); + $selects[]="($thismulti)"; + $mselects = ""; + } + } - //value less than - if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") - { - $selects[]=db_quote_id(substr($pv, 1, -1))." < ".sanitize_int($_POST[$pv]); - } - } - //| - File Upload Question Type - else if ($firstletter == "|") - { - // no. of files greater than - if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") - $selects[]=db_quote_id(substr($pv, 1, -1)."_filecount")." > ".sanitize_int($_POST[$pv]); + //N - Numerical Input + //K - Multiple Numerical Input + elseif ($firstletter == "N" || $firstletter == "K") + { + //value greater than + if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") + { + $selects[]=db_quote_id(substr($pv, 1, -1))." > ".sanitize_int($_POST[$pv]); + } - // no. of files less than - if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") - $selects[]=db_quote_id(substr($pv, 1, -1)."_filecount")." < ".sanitize_int($_POST[$pv]); - } + //value less than + if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") + { + $selects[]=db_quote_id(substr($pv, 1, -1))." < ".sanitize_int($_POST[$pv]); + } + } - //"id" is a built in field, the unique database id key of each response row - elseif (substr($pv, 0, 2) == "id") - { - if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") - { - $selects[]=db_quote_id(substr($pv, 0, -1))." > '".$_POST[$pv]."'"; - } - if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") - { - $selects[]=db_quote_id(substr($pv, 0, -1))." < '".$_POST[$pv]."'"; - } - } + //| - File Upload Question Type + else if ($firstletter == "|") + { + // no. of files greater than + if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") + $selects[]=db_quote_id(substr($pv, 1, -1)."_filecount")." > ".sanitize_int($_POST[$pv]); - //T - Long Free Text - //Q - Multiple Short Text - elseif (($firstletter == "T" || $firstletter == "Q" ) && $_POST[$pv] != "") - { - $selectSubs = array(); - //We intepret and * and % as wildcard matches, and use ' OR ' and , as the seperators - $pvParts = explode(",",str_replace('*','%', str_replace(' OR ',',',$_POST[$pv]))); - if(is_array($pvParts) AND count($pvParts)){ - foreach($pvParts AS $pvPart){ - $selectSubs[]=db_quote_id(substr($pv, 1, strlen($pv)))." LIKE '".trim($pvPart)."'"; + // no. of files less than + if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") + $selects[]=db_quote_id(substr($pv, 1, -1)."_filecount")." < ".sanitize_int($_POST[$pv]); } - if(count($selectSubs)){ - $selects[] = ' ('.implode(' OR ',$selectSubs).') '; - } - } - } - //D - Date - elseif ($firstletter == "D" && $_POST[$pv] != "") - { - //Date equals - if (substr($pv, -1, 1) == "=") - { - $selects[]=db_quote_id(substr($pv, 1, strlen($pv)-2))." = '".$_POST[$pv]."'"; - } - else - { - //date less than - if (substr($pv, -1, 1) == "<") + //"id" is a built in field, the unique database id key of each response row + elseif (substr($pv, 0, 2) == "id") { - $selects[]= db_quote_id(substr($pv, 1, strlen($pv)-2)) . " >= '".$_POST[$pv]."'"; + if (substr($pv, strlen($pv)-1, 1) == "G" && $_POST[$pv] != "") + { + $selects[]=db_quote_id(substr($pv, 0, -1))." > '".$_POST[$pv]."'"; + } + if (substr($pv, strlen($pv)-1, 1) == "L" && $_POST[$pv] != "") + { + $selects[]=db_quote_id(substr($pv, 0, -1))." < '".$_POST[$pv]."'"; + } } - //date greater than - if (substr($pv, -1, 1) == ">") + //T - Long Free Text + //Q - Multiple Short Text + elseif (($firstletter == "T" || $firstletter == "Q" ) && $_POST[$pv] != "") { - $selects[]= db_quote_id(substr($pv, 1, strlen($pv)-2)) . " <= '".$_POST[$pv]."'"; + $selectSubs = array(); + //We intepret and * and % as wildcard matches, and use ' OR ' and , as the seperators + $pvParts = explode(",",str_replace('*','%', str_replace(' OR ',',',$_POST[$pv]))); + if(is_array($pvParts) AND count($pvParts)){ + foreach($pvParts AS $pvPart){ + $selectSubs[]=db_quote_id(substr($pv, 1, strlen($pv)))." LIKE '".trim($pvPart)."'"; + } + if(count($selectSubs)){ + $selects[] = ' ('.implode(' OR ',$selectSubs).') '; + } + } } - } - } - - //check for datestamp of given answer - elseif (substr($pv, 0, 9) == "datestamp") - { - //timestamp equals - $formatdata=getDateFormatData($_SESSION['dateformat']); - if (substr($pv, -1, 1) == "E" && !empty($_POST[$pv])) - { - $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); - $_POST[$pv]=$datetimeobj->convert("Y-m-d"); - $selects[] = db_quote_id('datestamp')." >= '".$_POST[$pv]." 00:00:00' and ".db_quote_id('datestamp')." <= '".$_POST[$pv]." 23:59:59'"; - } - else - { - //timestamp less than - if (substr($pv, -1, 1) == "L" && !empty($_POST[$pv])) + //D - Date + elseif ($firstletter == "D" && $_POST[$pv] != "") { - $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); - $_POST[$pv]=$datetimeobj->convert("Y-m-d H:i:s"); - $selects[]= db_quote_id('datestamp')." < '".$_POST[$pv]."'"; - } + //Date equals + if (substr($pv, -1, 1) == "=") + { + $selects[]=db_quote_id(substr($pv, 1, strlen($pv)-2))." = '".$_POST[$pv]."'"; + } + else + { + //date less than + if (substr($pv, -1, 1) == "<") + { + $selects[]= db_quote_id(substr($pv, 1, strlen($pv)-2)) . " >= '".$_POST[$pv]."'"; + } - //timestamp greater than - if (substr($pv, -1, 1) == "G" && !empty($_POST[$pv])) - { - $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); - $_POST[$pv]=$datetimeobj->convert("Y-m-d H:i:s"); - $selects[]= db_quote_id('datestamp')." > '".$_POST[$pv]."'"; + //date greater than + if (substr($pv, -1, 1) == ">") + { + $selects[]= db_quote_id(substr($pv, 1, strlen($pv)-2)) . " <= '".$_POST[$pv]."'"; + } + } } - } - } - } - else - { - $statisticsoutput .= ""; - } - } //end foreach -> loop through filter options to create SQL + //check for datestamp of given answer + elseif (substr($pv, 0, 9) == "datestamp") + { + //timestamp equals + $formatdata=getDateFormatData($_SESSION['dateformat']); + if (substr($pv, -1, 1) == "E" && !empty($_POST[$pv])) + { + $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); + $_POST[$pv]=$datetimeobj->convert("Y-m-d"); - //count number of answers - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid"); + $selects[] = db_quote_id('datestamp')." >= '".$_POST[$pv]." 00:00:00' and ".db_quote_id('datestamp')." <= '".$_POST[$pv]." 23:59:59'"; + } + else + { + //timestamp less than + if (substr($pv, -1, 1) == "L" && !empty($_POST[$pv])) + { + $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); + $_POST[$pv]=$datetimeobj->convert("Y-m-d H:i:s"); + $selects[]= db_quote_id('datestamp')." < '".$_POST[$pv]."'"; + } - //if incompleted answers should be filtert submitdate has to be not null - if (incompleteAnsFilterstate() == "inc") {$query .= " WHERE submitdate is null";} - elseif (incompleteAnsFilterstate() == "filter") {$query .= " WHERE submitdate is not null";} - $result = db_execute_num($query) or safe_die ("Couldn't get total
$query
".$connect->ErrorMsg()); + //timestamp greater than + if (substr($pv, -1, 1) == "G" && !empty($_POST[$pv])) + { + $datetimeobj = new Date_Time_Converter($_POST[$pv], $formatdata['phpdate'].' H:i'); + $_POST[$pv]=$datetimeobj->convert("Y-m-d H:i:s"); + $selects[]= db_quote_id('datestamp')." > '".$_POST[$pv]."'"; + } + } + } + } + else + { + $statisticsoutput .= ""; + } - //$total = total number of answers - while ($row=$result->FetchRow()) {$total=$row[0];} + } //end foreach -> loop through filter options to create SQL - //are there any filters that have to be taken care of? - if (isset($selects) && $selects) - { - //filter incomplete answers? - if (incompleteAnsFilterstate() == "filter" || incompleteAnsFilterstate() == "inc") {$query .= " AND ";} + //count number of answers + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid"); - else {$query .= " WHERE ";} + //if incompleted answers should be filtert submitdate has to be not null + if (incompleteAnsFilterstate() == "inc") {$query .= " WHERE submitdate is null";} + elseif (incompleteAnsFilterstate() == "filter") {$query .= " WHERE submitdate is not null";} + $result = db_execute_num($query) or safe_die ("Couldn't get total
$query
".$connect->ErrorMsg()); - //add filter criteria to SQL - $query .= implode(" AND ", $selects); - } + //$total = total number of answers + while ($row=$result->FetchRow()) {$total=$row[0];} - //$_POST['sql'] is a post field that is sent from the statistics script to the export script in order - // to export just those results filtered by this statistics script. It can also be passed to the statistics - // script to filter from external scripts. - elseif (isset($_SESSION['sql']) && $_SESSION['sql']!='NULL' && !isset($_POST['id='])) - { - $newsql=substr($_SESSION['sql'], strpos($_SESSION['sql'], "WHERE")+5, strlen($_SESSION['sql'])); + //are there any filters that have to be taken care of? + if (isset($selects) && $selects) + { + //filter incomplete answers? + if (incompleteAnsFilterstate() == "filter" || incompleteAnsFilterstate() == "inc") {$query .= " AND ";} - //for debugging only - //$query = $_POST['sql']; + else {$query .= " WHERE ";} - //filter incomplete answers? - if (incompleteAnsFilterstate() == "inc") {$query .= " AND ".$newsql;} - elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND ".$newsql;} + //add filter criteria to SQL + $query .= implode(" AND ", $selects); + } - else {$query .= " WHERE ".$newsql;} - } - //get me some data Scotty - $result=db_execute_num($query) or safe_die("Couldn't get results
$query
".$connect->ErrorMsg()); + //get me some data Scotty + $result=db_execute_num($query) or safe_die("Couldn't get results
$query
".$connect->ErrorMsg()); - //put all results into $results - while ($row=$result->FetchRow()) {$results=$row[0];} + //put all results into $results + while ($row=$result->FetchRow()) {$results=$row[0];} - if ($total) - { - $percent=sprintf("%01.2f", ($results/$total)*100); + if ($total) + { + $percent=sprintf("%01.2f", ($results/$total)*100); - } - switch($outputType) - { - case "xls": - $xlsRow = 0; - $sheet->write($xlsRow,0,$statlang->gT("Number of records in this query:")); - $sheet->write($xlsRow,1,$results); - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Total records in survey:")); - $sheet->write($xlsRow,1,$total); - - if($total) - { + } + switch($outputType) + { + case "xls": + $xlsRow = 0; + $sheet->write($xlsRow,0,$statlang->gT("Number of records in this query:")); + $sheet->write($xlsRow,1,$results); ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Percentage of total:")); - $sheet->write($xlsRow,1,$percent."%"); - } - - break; - case 'pdf': + $sheet->write($xlsRow,0,$statlang->gT("Total records in survey:")); + $sheet->write($xlsRow,1,$total); - // add summary to pdf - $array = array(); - //$array[] = array($statlang->gT("Results"),""); - $array[] = array($statlang->gT("Number of records in this query:"), $results); - $array[] = array($statlang->gT("Total records in survey:"), $total); - - if($total) - $array[] = array($statlang->gT("Percentage of total:"), $percent."%"); - - $pdf->addPage('P','A4'); + if($total) + { + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Percentage of total:")); + $sheet->write($xlsRow,1,$percent."%"); + } - $pdf->Bookmark($pdf->delete_html($statlang->gT("Results")), 0, 0); - $pdf->titleintopdf($statlang->gT("Results"),$statlang->gT("Survey")." ".$surveyid); - $pdf->tableintopdf($array); + break; + case 'pdf': - $pdf->addPage('P','A4'); + // add summary to pdf + $array = array(); + //$array[] = array($statlang->gT("Results"),""); + $array[] = array($statlang->gT("Number of records in this query:"), $results); + $array[] = array($statlang->gT("Total records in survey:"), $total); - break; - case 'html': + if($total) + $array[] = array($statlang->gT("Percentage of total:"), $percent."%"); - $statisticsoutput .= "
\n\n" - ."\t\n" - ."\t' - ."\n" - ."\t' - ."\n"; + $pdf->addPage('P','A4'); - //only calculate percentage if $total is set - if ($total) - { - $percent=sprintf("%01.2f", ($results/$total)*100); - $statisticsoutput .= "\t' - ."\n"; - } - $statisticsoutput .="
".$statlang->gT("Results")."
".$statlang->gT("Number of records in this query:").'$results
".$statlang->gT("Total records in survey:").'$total
".$statlang->gT("Percentage of total:").'$percent%
\n"; + $pdf->Bookmark($pdf->delete_html($statlang->gT("Results")), 0, 0); + $pdf->titleintopdf($statlang->gT("Results"),$statlang->gT("Survey")." ".$surveyid); + $pdf->tableintopdf($array); - break; - default: + $pdf->addPage('P','A4'); + break; + case 'html': - break; - } + $statisticsoutput .= "
\n\n" + ."\t\n" + ."\t' + ."\n" + ."\t' + ."\n"; - //put everything from $selects array into a string connected by AND - if (isset ($selects) && $selects) {$sql=implode(" AND ", $selects);} + //only calculate percentage if $total is set + if ($total) + { + $percent=sprintf("%01.2f", ($results/$total)*100); + $statisticsoutput .= "\t' + ."\n"; + } + $statisticsoutput .="
".$statlang->gT("Results")."
".$statlang->gT("Number of records in this query:").'$results
".$statlang->gT("Total records in survey:").'$total
".$statlang->gT("Percentage of total:").'$percent%
\n"; - elseif (!empty($newsql)) {$sql = $newsql;} + break; + default: - if (!isset($sql) || !$sql) {$sql="NULL";} - //only continue if we have something to output - if ($results > 0) - { - if($outputType=='html' && $browse === true) - { - $_SESSION['sql']=$sql; - //add a buttons to browse results - $statisticsoutput .= "
\n" - ."\t\t

" - ."\t\t\t\n" - ."\t\t\t\n" - ."\t\t\t\n" - ."\t\t

" - ."\t\t
\n"; + break; } - } //end if (results > 0) - //Show Summary results - if (isset($summary) && $summary) - { - //let's run through the survey - $runthrough=$summary; + //put everything from $selects array into a string connected by AND + if (isset ($selects) && $selects) {$sql=implode(" AND ", $selects);} - //START Chop up fieldname and find matching questions + elseif (!empty($newsql)) {$sql = $newsql;} - //GET LIST OF LEGIT QIDs FOR TESTING LATER - $lq = "SELECT DISTINCT qid FROM ".db_table_name("questions")." WHERE sid=$surveyid and parent_qid=0"; - $lr = db_execute_assoc($lq); + if (!isset($sql) || !$sql) {$sql="NULL";} - //loop through the IDs - while ($lw = $lr->FetchRow()) + //only continue if we have something to output + if ($results > 0) { - //this creates an array of question id's' - $legitqids[] = $lw['qid']; - } + if($outputType=='html' && $browse === true) + { + $_SESSION['sql']=$sql; + //add a buttons to browse results + $statisticsoutput .= "
\n" + ."\t\t

" + ."\t\t\t\n" + ."\t\t\t\n" + ."\t\t\t\n" + ."\t\t

" + ."\t\t
\n"; + } + } //end if (results > 0) - //loop through all selected questions - foreach ($runthrough as $rt) + //Show Summary results + if (isset($summary) && $summary) { + //let's run through the survey + $runthrough=$summary; + + //START Chop up fieldname and find matching questions + + //GET LIST OF LEGIT QIDs FOR TESTING LATER + $lq = "SELECT DISTINCT qid FROM ".db_table_name("questions")." WHERE sid=$surveyid and parent_qid=0"; + $lr = db_execute_assoc($lq); - $firstletter = substr($rt, 0, 1); - // 1. Get answers for question ############################################################## + //loop through the IDs + while ($lw = $lr->FetchRow()) + { + //this creates an array of question id's' + $legitqids[] = $lw['qid']; + } - //M - Multiple choice, therefore multiple fields - if ($firstletter == "M" || $firstletter == "P") + //loop through all selected questions + foreach ($runthrough as $rt) { - //get SGQ data - list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - //select details for this question - $nquery = "SELECT title, type, question, parent_qid, other FROM ".db_table_name("questions")." WHERE language='{$language}' AND parent_qid=0 AND qid='$qqid'"; - $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); + $firstletter = substr($rt, 0, 1); + // 1. Get answers for question ############################################################## - //loop through question data - while ($nrow=$nresult->FetchRow()) + //M - Multiple choice, therefore multiple fields + if ($firstletter == "M" || $firstletter == "P") { - $qtitle=$nrow[0]; - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); - $qlid=$nrow[3]; - $qother=$nrow[4]; - } + //get SGQ data + list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - //1. Get list of answers - $query="SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qqid' AND language='{$language}' and scale_id=0 ORDER BY question_order"; - $result=db_execute_num($query) or safe_die("Couldn't get list of subquestions for multitype
$query
".$connect->ErrorMsg()); + //select details for this question + $nquery = "SELECT title, type, question, parent_qid, other FROM ".db_table_name("questions")." WHERE language='{$language}' AND parent_qid=0 AND qid='$qqid'"; + $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); - //loop through multiple answers - while ($row=$result->FetchRow()) - { - $mfield=substr($rt, 1, strlen($rt))."$row[0]"; + //loop through question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=$nrow[0]; + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + $qlid=$nrow[3]; + $qother=$nrow[4]; + } + + //1. Get list of answers + $query="SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qqid' AND language='{$language}' and scale_id=0 ORDER BY question_order"; + $result=db_execute_num($query) or safe_die("Couldn't get list of subquestions for multitype
$query
".$connect->ErrorMsg()); + + //loop through multiple answers + while ($row=$result->FetchRow()) + { + $mfield=substr($rt, 1, strlen($rt))."$row[0]"; + + //create an array containing answer code, answer and fieldname(??) + $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); + } + + //check "other" field. is it set? + if ($qother == "Y") + { + $mfield=substr($rt, 1, strlen($rt))."other"; - //create an array containing answer code, answer and fieldname(??) - $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); + //create an array containing answer code, answer and fieldname(??) + $alist[]=array($statlang->gT("Other"), $statlang->gT("Other"), $mfield); + } } - //check "other" field. is it set? - if ($qother == "Y") + + //S - Short Free Text + //T - Long Free Text + elseif ($firstletter == "T" || $firstletter == "S") //Short and long text { - $mfield=substr($rt, 1, strlen($rt))."other"; - //create an array containing answer code, answer and fieldname(??) - $alist[]=array($statlang->gT("Other"), $statlang->gT("Other"), $mfield); - } - } + //search for key + $fld = substr($rt, 1, strlen($rt)); + $fielddata=$fieldmap[$fld]; + //get SGQA IDs + $qsid=$fielddata['sid']; + $qgid=$fielddata['gid']; + $qqid=$fielddata['qid']; - //S - Short Free Text - //T - Long Free Text - elseif ($firstletter == "T" || $firstletter == "S") //Short and long text - { - //search for key - $fld = substr($rt, 1, strlen($rt)); - $fielddata=$fieldmap[$fld]; + list($qanswer, $qlid)=!empty($fielddata['aid']) ? explode("_", $fielddata['aid']) : array("", ""); + //get SGQ data + //list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - //get SGQA IDs - $qsid=$fielddata['sid']; - $qgid=$fielddata['gid']; - $qqid=$fielddata['qid']; + //get question data + $nquery = "SELECT title, type, question, other, parent_qid FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); + + //loop through question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=FlattenText($nrow[0]); + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + $nlid=$nrow[4]; + } - list($qanswer, $qlid)=!empty($fielddata['aid']) ? explode("_", $fielddata['aid']) : array("", ""); - //get SGQ data - //list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); + $mfield=substr($rt, 1, strlen($rt)); + //Text questions either have an answer, or they don't. There's no other way of quantising the results. + // So, instead of building an array of predefined answers like we do with lists & other types, + // we instead create two "types" of possible answer - either there is a response.. or there isn't. + // This question type then can provide a % of the question answered in the summary. + $alist[]=array("Answers", $statlang->gT("Answer"), $mfield); + $alist[]=array("NoAnswer", $statlang->gT("No answer"), $mfield); + } - //get question data - $nquery = "SELECT title, type, question, other, parent_qid FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); - //loop through question data - while ($nrow=$nresult->FetchRow()) + //Multiple short text + elseif ($firstletter == "Q") { - $qtitle=FlattenText($nrow[0]); - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); - $nlid=$nrow[4]; - } + //get SGQ data + list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - $mfield=substr($rt, 1, strlen($rt)); + //separating another ID + $tmpqid=substr($qqid, 0, strlen($qqid)-1); - //Text questions either have an answer, or they don't. There's no other way of quantising the results. - // So, instead of building an array of predefined answers like we do with lists & other types, - // we instead create two "types" of possible answer - either there is a response.. or there isn't. - // This question type then can provide a % of the question answered in the summary. - $alist[]=array("Answers", $statlang->gT("Answer"), $mfield); - $alist[]=array("NoAnswer", $statlang->gT("No answer"), $mfield); - } + //check if we have legid QIDs. if not create them by substringing + while (!in_array ($tmpqid,$legitqids)) $tmpqid=substr($tmpqid, 0, strlen($tmpqid)-1); + //length of QID + $qidlength=strlen($tmpqid); - //Multiple short text - elseif ($firstletter == "Q") - { - //get SGQ data - list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); + //we somehow get the answer code (see SQL later) from the $qqid + $qaid=substr($qqid, $qidlength, strlen($qqid)-$qidlength); - //separating another ID - $tmpqid=substr($qqid, 0, strlen($qqid)-1); + //get some question data + $nquery = "SELECT title, type, question, other FROM ".db_table_name("questions")." WHERE qid='".substr($qqid, 0, $qidlength)."' AND parent_qid=0 AND language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); - //check if we have legid QIDs. if not create them by substringing - while (!in_array ($tmpqid,$legitqids)) $tmpqid=substr($tmpqid, 0, strlen($tmpqid)-1); + //more substrings + $count = substr($qqid, strlen($qqid)-1); + + //loop through question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=FlattenText($nrow[0]).'-'.$count; + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + } - //length of QID - $qidlength=strlen($tmpqid); + //get answers + $qquery = "SELECT title as code, question as answer FROM ".db_table_name("questions")." WHERE parent_qid='".substr($qqid, 0, $qidlength)."' AND title='$qaid' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 5p Q)
$qquery
".$connect->ErrorMsg()); - //we somehow get the answer code (see SQL later) from the $qqid - $qaid=substr($qqid, $qidlength, strlen($qqid)-$qidlength); + //loop through answer data + while ($qrow=$qresult->FetchRow()) + { + //store each answer here + $atext=FlattenText($qrow[1]); + } - //get some question data - $nquery = "SELECT title, type, question, other FROM ".db_table_name("questions")." WHERE qid='".substr($qqid, 0, $qidlength)."' AND parent_qid=0 AND language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); + //add this to the question title + $qtitle .= " [$atext]"; - //more substrings - $count = substr($qqid, strlen($qqid)-1); + //even more substrings... + $mfield=substr($rt, 1, strlen($rt)); - //loop through question data - while ($nrow=$nresult->FetchRow()) - { - $qtitle=FlattenText($nrow[0]).'-'.$count; - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); + //Text questions either have an answer, or they don't. There's no other way of quantising the results. + // So, instead of building an array of predefined answers like we do with lists & other types, + // we instead create two "types" of possible answer - either there is a response.. or there isn't. + // This question type then can provide a % of the question answered in the summary. + $alist[]=array("Answers", $statlang->gT("Answer"), $mfield); + $alist[]=array("NoAnswer", $statlang->gT("No answer"), $mfield); } - //get answers - $qquery = "SELECT title as code, question as answer FROM ".db_table_name("questions")." WHERE parent_qid='".substr($qqid, 0, $qidlength)."' AND title='$qaid' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 5p Q)
$qquery
".$connect->ErrorMsg()); - //loop through answer data - while ($qrow=$qresult->FetchRow()) + //RANKING OPTION THEREFORE CONFUSING + elseif ($firstletter == "R") { - //store each answer here - $atext=FlattenText($qrow[1]); - } + //getting the needed IDs somehow + $lengthofnumeral=substr($rt, strpos($rt, "-")+1, 1); + list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strpos($rt, "-")-($lengthofnumeral+1)), 3); - //add this to the question title - $qtitle .= " [$atext]"; + //get question data + $nquery = "SELECT title, type, question FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); - //even more substrings... - $mfield=substr($rt, 1, strlen($rt)); - - //Text questions either have an answer, or they don't. There's no other way of quantising the results. - // So, instead of building an array of predefined answers like we do with lists & other types, - // we instead create two "types" of possible answer - either there is a response.. or there isn't. - // This question type then can provide a % of the question answered in the summary. - $alist[]=array("Answers", $statlang->gT("Answer"), $mfield); - $alist[]=array("NoAnswer", $statlang->gT("No answer"), $mfield); - } + //loop through question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=FlattenText($nrow[0]). " [".substr($rt, strpos($rt, "-")-($lengthofnumeral), $lengthofnumeral)."]"; + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]). "[".$statlang->gT("Ranking")." ".substr($rt, strpos($rt, "-")-($lengthofnumeral), $lengthofnumeral)."]"; + } + //get answers + $query="SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='$qqid' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; + $result=db_execute_num($query) or safe_die("Couldn't get list of answers for multitype
$query
".$connect->ErrorMsg()); - //RANKING OPTION THEREFORE CONFUSING - elseif ($firstletter == "R") - { - //getting the needed IDs somehow - $lengthofnumeral=substr($rt, strpos($rt, "-")+1, 1); - list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strpos($rt, "-")-($lengthofnumeral+1)), 3); + //loop through answers + while ($row=$result->FetchRow()) + { + //create an array containing answer code, answer and fieldname(??) + $mfield=substr($rt, 1, strpos($rt, "-")-1); + $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); + } + } - //get question data - $nquery = "SELECT title, type, question FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); + else if ($firstletter == "|") // File UPload + { - //loop through question data - while ($nrow=$nresult->FetchRow()) - { - $qtitle=FlattenText($nrow[0]). " [".substr($rt, strpos($rt, "-")-($lengthofnumeral), $lengthofnumeral)."]"; - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]). "[".$statlang->gT("Ranking")." ".substr($rt, strpos($rt, "-")-($lengthofnumeral), $lengthofnumeral)."]"; - } + //get SGQ data + list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - //get answers - $query="SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='$qqid' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; - $result=db_execute_num($query) or safe_die("Couldn't get list of answers for multitype
$query
".$connect->ErrorMsg()); + //select details for this question + $nquery = "SELECT title, type, question, parent_qid, other FROM ".db_table_name("questions")." WHERE language='{$language}' AND parent_qid=0 AND qid='$qqid'"; + $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); - //loop through answers - while ($row=$result->FetchRow()) - { - //create an array containing answer code, answer and fieldname(??) - $mfield=substr($rt, 1, strpos($rt, "-")-1); - $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); - } - } + //loop through question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=$nrow[0]; + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + $qlid=$nrow[3]; + $qother=$nrow[4]; + } - else if ($firstletter == "|") // File UPload - { + /* + 4) Average size of file per respondent + 5) Average no. of files + 5) Summary/count of file types (ie: 37 jpg, 65 gif, 12 png) + 6) Total size of all files (useful if you're about to download them all) + 7) You could also add things like smallest file size, largest file size, median file size + 8) no. of files corresponding to each extension + 9) max file size + 10) min file size + */ + + // 1) Total number of files uploaded + // 2) Number of respondents who uploaded at least one file (with the inverse being the number of respondents who didn’t upload any) + $fieldname=substr($rt, 1, strlen($rt)); + $query = "SELECT SUM(".db_quote_id($fieldname.'_filecount').") as sum, AVG(".db_quote_id($fieldname.'_filecount').") as avg FROM ".db_table_name("survey_$surveyid"); + $result=db_execute_assoc($query) or safe_die("Couldn't fetch the records
$query
".$connect->ErrorMsg()); + + $showem = array(); + + while ($row = $result->FetchRow()) + { + $showem[]=array($statlang->gT("Total number of files"), $row['sum']); + $showem[]=array($statlang->gT("Average no. of files per respondent"), $row['avg']); + } - //get SGQ data - list($qsid, $qgid, $qqid) = explode("X", substr($rt, 1, strlen($rt)), 3); - //select details for this question - $nquery = "SELECT title, type, question, parent_qid, other FROM ".db_table_name("questions")." WHERE language='{$language}' AND parent_qid=0 AND qid='$qqid'"; - $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); + $query = "SELECT ". $fieldname ." as json FROM ".db_table_name("survey_$surveyid"); + $result=db_execute_assoc($query) or safe_die("Couldn't fetch the records
$query
".$connect->ErrorMsg()); - //loop through question data - while ($nrow=$nresult->FetchRow()) - { - $qtitle=$nrow[0]; - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); - $qlid=$nrow[3]; - $qother=$nrow[4]; - } + $responsecount = 0; + $filecount = 0; + $size = 0; - /* - 4) Average size of file per respondent - 5) Average no. of files - 5) Summary/count of file types (ie: 37 jpg, 65 gif, 12 png) - 6) Total size of all files (useful if you're about to download them all) - 7) You could also add things like smallest file size, largest file size, median file size - 8) no. of files corresponding to each extension - 9) max file size - 10) min file size - */ - - // 1) Total number of files uploaded - // 2) Number of respondents who uploaded at least one file (with the inverse being the number of respondents who didn’t upload any) - $fieldname=substr($rt, 1, strlen($rt)); - $query = "SELECT SUM(".db_quote_id($fieldname.'_filecount').") as sum, AVG(".db_quote_id($fieldname.'_filecount').") as avg FROM ".db_table_name("survey_$surveyid"); - $result=db_execute_assoc($query) or safe_die("Couldn't fetch the records
$query
".$connect->ErrorMsg()); - - $showem = array(); - - while ($row = $result->FetchRow()) - { - $showem[]=array($statlang->gT("Total number of files"), $row['sum']); - $showem[]=array($statlang->gT("Average no. of files per respondent"), $row['avg']); - } + while ($row = $result->FetchRow()) + { + $json = $row['json']; + $phparray = json_decode($json); - $query = "SELECT ". $fieldname ." as json FROM ".db_table_name("survey_$surveyid"); - $result=db_execute_assoc($query) or safe_die("Couldn't fetch the records
$query
".$connect->ErrorMsg()); + foreach ($phparray as $metadata) + { + $size += (int) $metadata->size; + $filecount++; + } + $responsecount++; + } + $showem[] = array($statlang->gT("Total size of files"), $size." KB"); + $showem[] = array($statlang->gT("Average file size"), $size/$filecount . " KB"); + $showem[] = array($statlang->gT("Average size per respondent"), $size/$responsecount . " KB"); - $responsecount = 0; - $filecount = 0; - $size = 0; + /* $query="SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qqid' AND language='{$language}' ORDER BY question_order"; + $result=db_execute_num($query) or safe_die("Couldn't get list of subquestions for multitype
$query
".$connect->ErrorMsg()); - while ($row = $result->FetchRow()) - { + //loop through multiple answers + while ($row=$result->FetchRow()) + { + $mfield=substr($rt, 1, strlen($rt))."$row[0]"; - $json = $row['json']; - $phparray = json_decode($json); + //create an array containing answer code, answer and fieldname(??) + $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); + } - foreach ($phparray as $metadata) - { - $size += (int) $metadata->size; - $filecount++; - } - $responsecount++; - } - $showem[] = array($statlang->gT("Total size of files"), $size." KB"); - $showem[] = array($statlang->gT("Average file size"), $size/$filecount . " KB"); - $showem[] = array($statlang->gT("Average size per respondent"), $size/$responsecount . " KB"); + */ + //outputting + switch($outputType) + { + case 'xls': -/* $query="SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qqid' AND language='{$language}' ORDER BY question_order"; - $result=db_execute_num($query) or safe_die("Couldn't get list of subquestions for multitype
$query
".$connect->ErrorMsg()); + $headXLS = array(); + $tableXLS = array(); + $footXLS = array(); - //loop through multiple answers - while ($row=$result->FetchRow()) - { - $mfield=substr($rt, 1, strlen($rt))."$row[0]"; + $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); + $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); + ++$xlsRow; + ++$xlsRow; - //create an array containing answer code, answer and fieldname(??) - $alist[]=array("$row[0]", FlattenText($row[1]), $mfield); - } + ++$xlsRow; + $sheet->setCellValueByColumnAndRow(0,$xlsRow,$xlsTitle); + ++$xlsRow; + $sheet->setCellValueByColumnAndRow(0,$xlsRow,$xlsDesc); -*/ - //outputting - switch($outputType) - { - case 'xls': + $headXLS[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); + ++$xlsRow; + $sheet->setCellValueByColumnAndRow(0, $xlsRow,$statlang->gT("Calculation")); + $sheet->setCellValueByColumnAndRow(1, $xlsRow,$statlang->gT("Result")); - $headXLS = array(); - $tableXLS = array(); - $footXLS = array(); + break; + case 'pdf': - $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); - $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - ++$xlsRow; - ++$xlsRow; + $headPDF = array(); + $tablePDF = array(); + $footPDF = array(); - ++$xlsRow; - $sheet->setCellValueByColumnAndRow(0,$xlsRow,$xlsTitle); - ++$xlsRow; - $sheet->setCellValueByColumnAndRow(0,$xlsRow,$xlsDesc); + $pdfTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); + $titleDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - $headXLS[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); - ++$xlsRow; - $sheet->setCellValueByColumnAndRow(0, $xlsRow,$statlang->gT("Calculation")); - $sheet->setCellValueByColumnAndRow(1, $xlsRow,$statlang->gT("Result")); + $headPDF[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); - break; - case 'pdf': + break; - $headPDF = array(); - $tablePDF = array(); - $footPDF = array(); + case 'html': - $pdfTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); - $titleDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); + $statisticsoutput .= "\n\n" + ."\t\n" + ."\t\n" + ."\t\n\t\t\n" + ."\t\t\n" + ."\t\n"; + + foreach ($showem as $res) + $statisticsoutput .= ""; + break; - $headPDF[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); + default: + break; + } + } - break; + //N = numerical input + //K = multiple numerical input + elseif ($firstletter == "N" || $firstletter == "K") //NUMERICAL TYPE + { + //Zero handling + if (!isset($excludezeros)) //If this hasn't been set, set it to on as default: + { + $excludezeros=1; + } + //check last character, greater/less/equals don't need special treatment + if (substr($rt, -1) == "G" || substr($rt, -1) == "L" || substr($rt, -1) == "=") + { + //DO NOTHING + } + else + { + //create SGQ identifier + list($qsid, $qgid, $qqid) = explode("X", $rt, 3); - case 'html': + //multiple numerical input + if($firstletter == "K") + { + // This is a multiple numerical question so we need to strip of the answer id to find the question title + $tmpqid=substr($qqid, 0, strlen($qqid)-1); - $statisticsoutput .= "\n
".sprintf($statlang->gT("Field summary for %s"),$qtitle).":" + ."
$qquestion
" + .$statlang->gT("Calculation")."" + .$statlang->gT("Result")."
".$res[0]."".$res[1]."
\n" - ."\t\n" - ."\t\n" - ."\t\n\t\t\n" - ."\t\t\n" - ."\t\n"; + //did we get a valid ID? + while (!in_array ($tmpqid,$legitqids)) + $tmpqid=substr($tmpqid, 0, strlen($tmpqid)-1); - foreach ($showem as $res) - $statisticsoutput .= ""; - break; + //check lenght of ID + $qidlength=strlen($tmpqid); - default: - break; - } - } + //get answer ID from qid + $qaid=substr($qqid, $qidlength, strlen($qqid)-$qidlength); - //N = numerical input - //K = multiple numerical input - elseif ($firstletter == "N" || $firstletter == "K") //NUMERICAL TYPE - { - //Zero handling - if (!isset($excludezeros)) //If this hasn't been set, set it to on as default: - { - $excludezeros=1; - } - //check last character, greater/less/equals don't need special treatment - if (substr($rt, -1) == "G" || substr($rt, -1) == "L" || substr($rt, -1) == "=") - { - //DO NOTHING - } - else - { - //create SGQ identifier - list($qsid, $qgid, $qqid) = explode("X", $rt, 3); + //get question details from DB + $nquery = "SELECT title, type, question, qid, parent_qid + FROM ".db_table_name("questions")." + WHERE parent_qid=0 AND qid='".substr($qqid, 0, $qidlength)."' + AND language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); + } - //multiple numerical input - if($firstletter == "K") - { - // This is a multiple numerical question so we need to strip of the answer id to find the question title - $tmpqid=substr($qqid, 0, strlen($qqid)-1); + //probably question type "N" = numerical input + else + { + //we can use the qqid without any editing + $nquery = "SELECT title, type, question, qid, parent_qid FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); + } - //did we get a valid ID? - while (!in_array ($tmpqid,$legitqids)) - $tmpqid=substr($tmpqid, 0, strlen($tmpqid)-1); + //loop through results + while ($nrow=$nresult->FetchRow()) + { + $qtitle=FlattenText($nrow[0]); //clean up title + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + $qiqid=$nrow[3]; + $qlid=$nrow[4]; + } - //check lenght of ID - $qidlength=strlen($tmpqid); + //Get answer texts for multiple numerical + if(substr($rt, 0, 1) == "K") + { + //get answer data + $atext=$connect->GetOne("SELECT question FROM ".db_table_name("questions")." WHERE parent_qid='{$qiqid}' AND scale_id=0 AND title='{$qaid}' AND language='{$language}'"); + //put single items in brackets at output + $qtitle .= " [$atext]"; + } - //get answer ID from qid - $qaid=substr($qqid, $qidlength, strlen($qqid)-$qidlength); + //outputting + switch($outputType) + { + case 'xls': - //get question details from DB - $nquery = "SELECT title, type, question, qid, parent_qid - FROM ".db_table_name("questions")." - WHERE parent_qid=0 AND qid='".substr($qqid, 0, $qidlength)."' - AND language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die("Couldn't get text question
$nquery
".$connect->ErrorMsg()); - } + $headXLS = array(); + $tableXLS = array(); + $footXLS = array(); - //probably question type "N" = numerical input - else - { - //we can use the qqid without any editing - $nquery = "SELECT title, type, question, qid, parent_qid FROM ".db_table_name("questions")." WHERE parent_qid=0 AND qid='$qqid' AND language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); - } + $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); + $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); + ++$xlsRow; + ++$xlsRow; - //loop through results - while ($nrow=$nresult->FetchRow()) - { - $qtitle=FlattenText($nrow[0]); //clean up title - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); - $qiqid=$nrow[3]; - $qlid=$nrow[4]; - } + ++$xlsRow; + $sheet->write($xlsRow, 0,$xlsTitle); + ++$xlsRow; + $sheet->write($xlsRow, 0,$xlsDesc); - //Get answer texts for multiple numerical - if(substr($rt, 0, 1) == "K") - { - //get answer data - $atext=$connect->GetOne("SELECT question FROM ".db_table_name("questions")." WHERE parent_qid='{$qiqid}' AND scale_id=0 AND title='{$qaid}' AND language='{$language}'"); - //put single items in brackets at output - $qtitle .= " [$atext]"; - } + $headXLS[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); + ++$xlsRow; + $sheet->write($xlsRow, 0,$statlang->gT("Calculation")); + $sheet->write($xlsRow, 1,$statlang->gT("Result")); - //outputting - switch($outputType) - { - case 'xls': + break; + case 'pdf': - $headXLS = array(); - $tableXLS = array(); - $footXLS = array(); + $headPDF = array(); + $tablePDF = array(); + $footPDF = array(); - $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); - $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - ++$xlsRow; - ++$xlsRow; + $pdfTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); + $titleDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - ++$xlsRow; - $sheet->write($xlsRow, 0,$xlsTitle); - ++$xlsRow; - $sheet->write($xlsRow, 0,$xlsDesc); + $headPDF[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); - $headXLS[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); - ++$xlsRow; - $sheet->write($xlsRow, 0,$statlang->gT("Calculation")); - $sheet->write($xlsRow, 1,$statlang->gT("Result")); + break; + case 'html': - break; - case 'pdf': + $statisticsoutput .= "\n
".sprintf($statlang->gT("Field summary for %s"),$qtitle).":" - ."
$qquestion
" - .$statlang->gT("Calculation")."" - .$statlang->gT("Result")."
".$res[0]."".$res[1]."
\n" + ."\t\n" + ."\t\n" + ."\t\n\t\t\n" + ."\t\t\n" + ."\t\n"; - $headPDF = array(); - $tablePDF = array(); - $footPDF = array(); + break; + default: - $pdfTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); - $titleDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - $headPDF[] = array($statlang->gT("Calculation"),$statlang->gT("Result")); + break; + } - break; - case 'html': + //this field is queried using mathematical functions + $fieldname=substr($rt, 1, strlen($rt)); - $statisticsoutput .= "\n
".sprintf($statlang->gT("Field summary for %s"),$qtitle).":" + ."
$qquestion
" + .$statlang->gT("Calculation")."" + .$statlang->gT("Result")."
\n" - ."\t\n" - ."\t\n" - ."\t\n\t\t\n" - ."\t\t\n" - ."\t\n"; + //special treatment for MS SQL databases + if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') + { + //standard deviation + $query = "SELECT STDEVP(".db_quote_id($fieldname)."*1) as stdev"; + } - break; - default: + //other databases (MySQL, Postgres) + else + { + //standard deviation + $query = "SELECT STDDEV(".db_quote_id($fieldname).") as stdev"; + } + //sum + $query .= ", SUM(".db_quote_id($fieldname)."*1) as sum"; - break; - } + //average + $query .= ", AVG(".db_quote_id($fieldname)."*1) as average"; - //this field is queried using mathematical functions - $fieldname=substr($rt, 1, strlen($rt)); + //min + $query .= ", MIN(".db_quote_id($fieldname)."*1) as minimum"; - //special treatment for MS SQL databases - if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') - { - //standard deviation - $query = "SELECT STDEVP(".db_quote_id($fieldname)."*1) as stdev"; - } + //max + $query .= ", MAX(".db_quote_id($fieldname)."*1) as maximum"; + //Only select responses where there is an actual number response, ignore nulls and empties (if these are included, they are treated as zeroes, and distort the deviation/mean calculations) - //other databases (MySQL, Postgres) - else - { - //standard deviation - $query = "SELECT STDDEV(".db_quote_id($fieldname).") as stdev"; - } + //special treatment for MS SQL databases + if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') + { + //no NULL/empty values please + $query .= " FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT NULL"; + if(!$excludezeros) + { + //NO ZERO VALUES + $query .= " AND (".db_quote_id($fieldname)." <> 0)"; + } + } - //sum - $query .= ", SUM(".db_quote_id($fieldname)."*1) as sum"; + //other databases (MySQL, Postgres) + else + { + //no NULL/empty values please + $query .= " FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT NULL"; + if(!$excludezeros) + { + //NO ZERO VALUES + $query .= " AND (".db_quote_id($fieldname)." != 0)"; + } + } - //average - $query .= ", AVG(".db_quote_id($fieldname)."*1) as average"; + //filter incomplete answers if set + if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} + elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} - //min - $query .= ", MIN(".db_quote_id($fieldname)."*1) as minimum"; + //$sql was set somewhere before + if ($sql != "NULL") {$query .= " AND $sql";} - //max - $query .= ", MAX(".db_quote_id($fieldname)."*1) as maximum"; - //Only select responses where there is an actual number response, ignore nulls and empties (if these are included, they are treated as zeroes, and distort the deviation/mean calculations) + //execute query + $result=db_execute_assoc($query) or safe_die("Couldn't do maths testing
$query
".$connect->ErrorMsg()); - //special treatment for MS SQL databases - if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') - { - //no NULL/empty values please - $query .= " FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT NULL"; - if(!$excludezeros) + //get calculated data + while ($row=$result->FetchRow()) { - //NO ZERO VALUES - $query .= " AND (".db_quote_id($fieldname)." <> 0)"; + //put translation of mean and calculated data into $showem array + $showem[]=array($statlang->gT("Sum"), $row['sum']); + $showem[]=array($statlang->gT("Standard deviation"), round($row['stdev'],2)); + $showem[]=array($statlang->gT("Average"), round($row['average'],2)); + $showem[]=array($statlang->gT("Minimum"), $row['minimum']); + + //Display the maximum and minimum figures after the quartiles for neatness + $maximum=$row['maximum']; + $minimum=$row['minimum']; } - } - //other databases (MySQL, Postgres) - else - { - //no NULL/empty values please - $query .= " FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT NULL"; + + + //CALCULATE QUARTILES + + //get data + $query ="SELECT ".db_quote_id($fieldname)." FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT null"; + //NO ZEROES if(!$excludezeros) { - //NO ZERO VALUES - $query .= " AND (".db_quote_id($fieldname)." != 0)"; + $query .= " AND ".db_quote_id($fieldname)." != 0"; } - } - //filter incomplete answers if set - if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} - elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} + //filtering enabled? + if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} + elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} - //$sql was set somewhere before - if ($sql != "NULL") {$query .= " AND $sql";} + //if $sql values have been passed to the statistics script from another script, incorporate them + if ($sql != "NULL") {$query .= " AND $sql";} - //execute query - $result=db_execute_assoc($query) or safe_die("Couldn't do maths testing
$query
".$connect->ErrorMsg()); - - //get calculated data - while ($row=$result->FetchRow()) - { - //put translation of mean and calculated data into $showem array - $showem[]=array($statlang->gT("Sum"), $row['sum']); - $showem[]=array($statlang->gT("Standard deviation"), round($row['stdev'],2)); - $showem[]=array($statlang->gT("Average"), round($row['average'],2)); - $showem[]=array($statlang->gT("Minimum"), $row['minimum']); - - //Display the maximum and minimum figures after the quartiles for neatness - $maximum=$row['maximum']; - $minimum=$row['minimum']; - } + //execute query + $result=$connect->Execute($query) or safe_die("Disaster during median calculation
$query
".$connect->ErrorMsg()); + $querystarter="SELECT ".db_quote_id($fieldname)." FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT null"; + //No Zeroes + if(!$excludezeros) + { + $querystart .= " AND ".db_quote_id($fieldname)." != 0"; + } + //filtering enabled? + if (incompleteAnsFilterstate() == "inc") {$querystarter .= " AND submitdate is null";} + elseif (incompleteAnsFilterstate() == "filter") {$querystarter .= " AND submitdate is not null";} + //if $sql values have been passed to the statistics script from another script, incorporate them + if ($sql != "NULL") {$querystarter .= " AND $sql";} - //CALCULATE QUARTILES + //we just count the number of records returned + $medcount=$result->RecordCount(); - //get data - $query ="SELECT ".db_quote_id($fieldname)." FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT null"; - //NO ZEROES - if(!$excludezeros) - { - $query .= " AND ".db_quote_id($fieldname)." != 0"; - } + //put the total number of records at the beginning of this array + array_unshift($showem, array($statlang->gT("Count"), $medcount)); - //filtering enabled? - if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} - elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} - //if $sql values have been passed to the statistics script from another script, incorporate them - if ($sql != "NULL") {$query .= " AND $sql";} + //no more comment from Mazi regarding the calculation - //execute query - $result=$connect->Execute($query) or safe_die("Disaster during median calculation
$query
".$connect->ErrorMsg()); + // Calculating only makes sense with more than one result + if ($medcount>1) + { + //1ST QUARTILE (Q1) + $q1=(1/4)*($medcount+1); + $q1b=(int)((1/4)*($medcount+1)); + $q1c=$q1b-1; + $q1diff=$q1-$q1b; + $total=0; - $querystarter="SELECT ".db_quote_id($fieldname)." FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($fieldname)." IS NOT null"; - //No Zeroes - if(!$excludezeros) - { - $querystart .= " AND ".db_quote_id($fieldname)." != 0"; - } - //filtering enabled? - if (incompleteAnsFilterstate() == "inc") {$querystarter .= " AND submitdate is null";} - elseif (incompleteAnsFilterstate() == "filter") {$querystarter .= " AND submitdate is not null";} + // fix if there are too few values to evaluate. + if ($q1c<0) {$q1c=0;} - //if $sql values have been passed to the statistics script from another script, incorporate them - if ($sql != "NULL") {$querystarter .= " AND $sql";} + if ($q1 != $q1b) + { + //ODD NUMBER + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; + $result=db_select_limit_assoc($query, 2, $q1c) or safe_die("1st Quartile query failed
".$connect->ErrorMsg()); - //we just count the number of records returned - $medcount=$result->RecordCount(); + while ($row=$result->FetchRow()) + { + if ($total == 0) {$total=$total-$row[$fieldname];} - //put the total number of records at the beginning of this array - array_unshift($showem, array($statlang->gT("Count"), $medcount)); + else {$total=$total+$row[$fieldname];} + $lastnumber=$row[$fieldname]; + } - //no more comment from Mazi regarding the calculation + $q1total=$lastnumber-((1-$q1diff)*$total); - // Calculating only makes sense with more than one result - if ($medcount>1) - { - //1ST QUARTILE (Q1) - $q1=(1/4)*($medcount+1); - $q1b=(int)((1/4)*($medcount+1)); - $q1c=$q1b-1; - $q1diff=$q1-$q1b; - $total=0; + if ($q1total < $minimum) {$q1total=$minimum;} - // fix if there are too few values to evaluate. - if ($q1c<0) {$q1c=0;} + $showem[]=array($statlang->gT("1st quartile (Q1)"), $q1total); + } + else + { + //EVEN NUMBER + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; + $result=db_select_limit_assoc($query,1, $q1c) or safe_die ("1st Quartile query failed
".$connect->ErrorMsg()); - if ($q1 != $q1b) - { - //ODD NUMBER - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; - $result=db_select_limit_assoc($query, 2, $q1c) or safe_die("1st Quartile query failed
".$connect->ErrorMsg()); + while ($row=$result->FetchRow()) + { + $showem[]=array($statlang->gT("1st quartile (Q1)"), $row[$fieldname]); + } + } - while ($row=$result->FetchRow()) - { - if ($total == 0) {$total=$total-$row[$fieldname];} + $total=0; - else {$total=$total+$row[$fieldname];} - $lastnumber=$row[$fieldname]; - } + //MEDIAN (Q2) + $median=(1/2)*($medcount+1); + $medianb=(int)((1/2)*($medcount+1)); + $medianc=$medianb-1; + $mediandiff=$median-$medianb; - $q1total=$lastnumber-((1-$q1diff)*$total); + if ($median != $medianb) + { + //remainder + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; + $result=db_select_limit_assoc($query,2, $medianc) or safe_die("What a complete mess with the remainder
$query
".$connect->ErrorMsg()); - if ($q1total < $minimum) {$q1total=$minimum;} + while + ( + $row=$result->FetchRow()) {$total=$total+$row[$fieldname]; + } - $showem[]=array($statlang->gT("1st quartile (Q1)"), $q1total); - } - else - { - //EVEN NUMBER - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; - $result=db_select_limit_assoc($query,1, $q1c) or safe_die ("1st Quartile query failed
".$connect->ErrorMsg()); + $showem[]=array($statlang->gT("2nd quartile (Median)"), $total/2); + } - while ($row=$result->FetchRow()) + else { - $showem[]=array($statlang->gT("1st quartile (Q1)"), $row[$fieldname]); + //EVEN NUMBER + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; + $result=db_select_limit_assoc($query,1, $medianc-1) or safe_die("What a complete mess
$query
".$connect->ErrorMsg()); + + while ($row=$result->FetchRow()) + { + $showem[]=array($statlang->gT("Median value"), $row[$fieldname]); + } } - } - $total=0; + $total=0; - //MEDIAN (Q2) - $median=(1/2)*($medcount+1); - $medianb=(int)((1/2)*($medcount+1)); - $medianc=$medianb-1; - $mediandiff=$median-$medianb; + //3RD QUARTILE (Q3) + $q3=(3/4)*($medcount+1); + $q3b=(int)((3/4)*($medcount+1)); + $q3c=$q3b-1; + $q3diff=$q3-$q3b; - if ($median != $medianb) - { - //remainder - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; - $result=db_select_limit_assoc($query,2, $medianc) or safe_die("What a complete mess with the remainder
$query
".$connect->ErrorMsg()); + if ($q3 != $q3b) + { + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; + $result = db_select_limit_assoc($query,2,$q3c) or safe_die("3rd Quartile query failed
".$connect->ErrorMsg()); - while - ( - $row=$result->FetchRow()) {$total=$total+$row[$fieldname]; - } + while ($row=$result->FetchRow()) + { + if ($total == 0) {$total=$total-$row[$fieldname];} - $showem[]=array($statlang->gT("2nd quartile (Median)"), $total/2); - } + else {$total=$total+$row[$fieldname];} - else - { - //EVEN NUMBER - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; - $result=db_select_limit_assoc($query,1, $medianc-1) or safe_die("What a complete mess
$query
".$connect->ErrorMsg()); + $lastnumber=$row[$fieldname]; + } + $q3total=$lastnumber-((1-$q3diff)*$total); - while ($row=$result->FetchRow()) - { - $showem[]=array($statlang->gT("Median value"), $row[$fieldname]); + if ($q3total < $maximum) {$q1total=$maximum;} + + $showem[]=array($statlang->gT("3rd quartile (Q3)"), $q3total); } - } - $total=0; + else + { + $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1"; + $result = db_select_limit_assoc($query,1, $q3c) or safe_die("3rd Quartile even query failed
".$connect->ErrorMsg()); + while ($row=$result->FetchRow()) + { + $showem[]=array($statlang->gT("3rd quartile (Q3)"), $row[$fieldname]); + } + } - //3RD QUARTILE (Q3) - $q3=(3/4)*($medcount+1); - $q3b=(int)((3/4)*($medcount+1)); - $q3c=$q3b-1; - $q3diff=$q3-$q3b; + $total=0; - if ($q3 != $q3b) - { - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1 "; - $result = db_select_limit_assoc($query,2,$q3c) or safe_die("3rd Quartile query failed
".$connect->ErrorMsg()); + $showem[]=array($statlang->gT("Maximum"), $maximum); - while ($row=$result->FetchRow()) + //output results + foreach ($showem as $shw) { - if ($total == 0) {$total=$total-$row[$fieldname];} + switch($outputType) + { + case 'xls': - else {$total=$total+$row[$fieldname];} + ++$xlsRow; + $sheet->write($xlsRow, 0,html_entity_decode($shw[0],ENT_QUOTES,'UTF-8')); + $sheet->write($xlsRow, 1,html_entity_decode($shw[1],ENT_QUOTES,'UTF-8')); - $lastnumber=$row[$fieldname]; - } - $q3total=$lastnumber-((1-$q3diff)*$total); - if ($q3total < $maximum) {$q1total=$maximum;} + $tableXLS[] = array($shw[0],$shw[1]); - $showem[]=array($statlang->gT("3rd quartile (Q3)"), $q3total); - } + break; + case 'pdf': - else - { - $query = $querystarter . " ORDER BY ".db_quote_id($fieldname)."*1"; - $result = db_select_limit_assoc($query,1, $q3c) or safe_die("3rd Quartile even query failed
".$connect->ErrorMsg()); + $tablePDF[] = array(html_entity_decode($shw[0],ENT_QUOTES,'UTF-8'),html_entity_decode($shw[1],ENT_QUOTES,'UTF-8')); - while ($row=$result->FetchRow()) - { - $showem[]=array($statlang->gT("3rd quartile (Q3)"), $row[$fieldname]); - } - } + break; + case 'html': - $total=0; + $statisticsoutput .= "\t\n" + ."\t\t\n" + ."\t\t\n" + ."\t\n"; + + break; + default: - $showem[]=array($statlang->gT("Maximum"), $maximum); - //output results - foreach ($showem as $shw) - { + break; + } + } switch($outputType) { case 'xls': ++$xlsRow; - $sheet->write($xlsRow, 0,html_entity_decode($shw[0],ENT_QUOTES,'UTF-8')); - $sheet->write($xlsRow, 1,html_entity_decode($shw[1],ENT_QUOTES,'UTF-8')); - + $sheet->write($xlsRow, 0,$statlang->gT("Null values are ignored in calculations")); + ++$xlsRow; + $sheet->write($xlsRow, 0,sprintf($statlang->gT("Q1 and Q3 calculated using %s"), $statlang->gT("minitab method"))); - $tableXLS[] = array($shw[0],$shw[1]); + $footXLS[] = array($statlang->gT("Null values are ignored in calculations")); + $footXLS[] = array(sprintf($statlang->gT("Q1 and Q3 calculated using %s"), $statlang->gT("minitab method"))); break; case 'pdf': - $tablePDF[] = array(html_entity_decode($shw[0],ENT_QUOTES,'UTF-8'),html_entity_decode($shw[1],ENT_QUOTES,'UTF-8')); + $footPDF[] = array($statlang->gT("Null values are ignored in calculations")); + $footPDF[] = array(sprintf($statlang->gT("Q1 and Q3 calculated using %s"), "".$statlang->gT("minitab method")."")); + $pdf->addPage('P','A4'); + $pdf->Bookmark($pdf->delete_html($qquestion), 1, 0); + $pdf->titleintopdf($pdfTitle,$titleDesc); + + $pdf->headTable($headPDF, $tablePDF); + + $pdf->tablehead($footPDF); break; case 'html': + //footer of question type "N" $statisticsoutput .= "\t\n" - ."\t\t\n" - ."\t\t\n" - ."\t\n"; + ."\t\t\n" + ."\t\n
".sprintf($statlang->gT("Field summary for %s"),$qtitle).":" - ."
$qquestion
" - .$statlang->gT("Calculation")."" - .$statlang->gT("Result")."
$shw[0]$shw[1]
$shw[0]$shw[1]
\n" + ."\t\t\t".$statlang->gT("Null values are ignored in calculations")."
\n" + ."\t\t\t".sprintf($statlang->gT("Q1 and Q3 calculated using %s"), "".$statlang->gT("minitab method")."") + ."
\n" + ."\t\t
\n"; break; default: @@ -1394,800 +1422,857 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, break; } - } - switch($outputType) - { - case 'xls': - ++$xlsRow; - $sheet->write($xlsRow, 0,$statlang->gT("Null values are ignored in calculations")); - ++$xlsRow; - $sheet->write($xlsRow, 0,sprintf($statlang->gT("Q1 and Q3 calculated using %s"), $statlang->gT("minitab method"))); + //clean up + unset($showem); - $footXLS[] = array($statlang->gT("Null values are ignored in calculations")); - $footXLS[] = array(sprintf($statlang->gT("Q1 and Q3 calculated using %s"), $statlang->gT("minitab method"))); + } //end if (enough results?) - break; - case 'pdf': - - $footPDF[] = array($statlang->gT("Null values are ignored in calculations")); - $footPDF[] = array(sprintf($statlang->gT("Q1 and Q3 calculated using %s"), "".$statlang->gT("minitab method")."")); - $pdf->addPage('P','A4'); - $pdf->Bookmark($pdf->delete_html($qquestion), 1, 0); - $pdf->titleintopdf($pdfTitle,$titleDesc); + //not enough (<1) results for calculation + else + { + switch($outputType) + { + case 'xls': - $pdf->headTable($headPDF, $tablePDF); + $tableXLS = array(); + $tableXLS[] = array($statlang->gT("Not enough values for calculation")); - $pdf->tablehead($footPDF); + ++$xlsRow; + $sheet->write($xlsRow, 0, $statlang->gT("Not enough values for calculation")); - break; - case 'html': - //footer of question type "N" - $statisticsoutput .= "\t\n" - ."\t\t\n" - ."\t\t\t".$statlang->gT("Null values are ignored in calculations")."
\n" - ."\t\t\t".sprintf($statlang->gT("Q1 and Q3 calculated using %s"), "".$statlang->gT("minitab method")."") - ."
\n" - ."\t\t\n" - ."\t\n\n"; - break; - default: + break; + case 'pdf': + $tablePDF = array(); + $tablePDF[] = array($statlang->gT("Not enough values for calculation")); + $pdf->addPage('P','A4'); + $pdf->Bookmark($pdf->delete_html($qquestion), 1, 0); + $pdf->titleintopdf($pdfTitle,$titleDesc); - break; - } + $pdf->equalTable($tablePDF); - //clean up - unset($showem); + break; + case 'html': - } //end if (enough results?) + //output + $statisticsoutput .= "\t\n" + ."\t\t".$statlang->gT("Not enough values for calculation")."\n" + ."\t\n
\n"; - //not enough (<1) results for calculation - else - { - switch($outputType) - { - case 'xls': + break; + default: - $tableXLS = array(); - $tableXLS[] = array($statlang->gT("Not enough values for calculation")); - ++$xlsRow; - $sheet->write($xlsRow, 0, $statlang->gT("Not enough values for calculation")); + break; + } + unset($showem); + } - break; - case 'pdf': + } //end else -> check last character, greater/less/equals don't need special treatment - $tablePDF = array(); - $tablePDF[] = array($statlang->gT("Not enough values for calculation")); - $pdf->addPage('P','A4'); - $pdf->Bookmark($pdf->delete_html($qquestion), 1, 0); - $pdf->titleintopdf($pdfTitle,$titleDesc); + } //end else-if -> multiple numerical types - $pdf->equalTable($tablePDF); + //is there some "id", "datestamp" or "D" within the type? + elseif (substr($rt, 0, 2) == "id" || substr($rt, 0, 9) == "datestamp" || ($firstletter == "D")) + { + /* + * DON'T show anything for date questions + * because there aren't any statistics implemented yet! + * + * See bug report #2539 and + * feature request #2620 + */ + } - break; - case 'html': - //output - $statisticsoutput .= "\t\n" - ."\t\t".$statlang->gT("Not enough values for calculation")."\n" - ."\t\n
\n"; + // NICE SIMPLE SINGLE OPTION ANSWERS + else + { + //search for key + $fielddata=$fieldmap[$rt]; + //print_r($fielddata); + //get SGQA IDs + $qsid=$fielddata['sid']; + $qgid=$fielddata['gid']; + $qqid=$fielddata['qid']; + $qanswer=$fielddata['aid']; - break; - default: + //question type + $qtype=$fielddata['type']; + //question string + $qastring=$fielddata['question']; - break; - } + //question ID + $rqid=$qqid; - unset($showem); + //get question data + $nquery = "SELECT title, type, question, qid, parent_qid, other FROM ".db_table_name("questions")." WHERE qid='{$rqid}' AND parent_qid=0 and language='{$language}'"; + $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); + //loop though question data + while ($nrow=$nresult->FetchRow()) + { + $qtitle=FlattenText($nrow[0]); + $qtype=$nrow[1]; + $qquestion=FlattenText($nrow[2]); + $qiqid=$nrow[3]; + $qparentqid=$nrow[4]; + $qother=$nrow[5]; } - } //end else -> check last character, greater/less/equals don't need special treatment - - } //end else-if -> multiple numerical types - - //is there some "id", "datestamp" or "D" within the type? - elseif (substr($rt, 0, 2) == "id" || substr($rt, 0, 9) == "datestamp" || ($firstletter == "D")) - { - /* - * DON'T show anything for date questions - * because there aren't any statistics implemented yet! - * - * See bug report #2539 and - * feature request #2620 - */ - } - - - // NICE SIMPLE SINGLE OPTION ANSWERS - else - { - //search for key - $fielddata=$fieldmap[$rt]; - //print_r($fielddata); - //get SGQA IDs - $qsid=$fielddata['sid']; - $qgid=$fielddata['gid']; - $qqid=$fielddata['qid']; - $qanswer=$fielddata['aid']; - - //question type - $qtype=$fielddata['type']; - - //question string - $qastring=$fielddata['question']; - - //question ID - $rqid=$qqid; - - //get question data - $nquery = "SELECT title, type, question, qid, parent_qid, other FROM ".db_table_name("questions")." WHERE qid='{$rqid}' AND parent_qid=0 and language='{$language}'"; - $nresult = db_execute_num($nquery) or safe_die ("Couldn't get question
$nquery
".$connect->ErrorMsg()); - - //loop though question data - while ($nrow=$nresult->FetchRow()) - { - $qtitle=FlattenText($nrow[0]); - $qtype=$nrow[1]; - $qquestion=FlattenText($nrow[2]); - $qiqid=$nrow[3]; - $qparentqid=$nrow[4]; - $qother=$nrow[5]; - } - - //check question types - switch($qtype) - { - //Array of 5 point choices (several items to rank!) - case "A": + //check question types + switch($qtype) + { + //Array of 5 point choices (several items to rank!) + case "A": - //get data - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 5p Q)
$qquery
".$connect->ErrorMsg()); + //get data + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 5p Q)
$qquery
".$connect->ErrorMsg()); - //loop through results - while ($qrow=$qresult->FetchRow()) - { - //5-point array - for ($i=1; $i<=5; $i++) + //loop through results + while ($qrow=$qresult->FetchRow()) { - //add data - $alist[]=array("$i", "$i"); + //5-point array + for ($i=1; $i<=5; $i++) + { + //add data + $alist[]=array("$i", "$i"); + } + //add counter + $atext=FlattenText($qrow[1]); } - //add counter - $atext=FlattenText($qrow[1]); - } - //list IDs and answer codes in brackets - $qquestion .= $linefeed."[".$atext."]"; - $qtitle .= "($qanswer)"; - break; + //list IDs and answer codes in brackets + $qquestion .= $linefeed."[".$atext."]"; + $qtitle .= "($qanswer)"; + break; - //Array of 10 point choices - //same as above just with 10 items - case "B": - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 10p Q)
$qquery
".$connect->ErrorMsg()); - while ($qrow=$qresult->FetchRow()) - { - for ($i=1; $i<=10; $i++) + //Array of 10 point choices + //same as above just with 10 items + case "B": + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details (Array 10p Q)
$qquery
".$connect->ErrorMsg()); + while ($qrow=$qresult->FetchRow()) { - $alist[]=array("$i", "$i"); + for ($i=1; $i<=10; $i++) + { + $alist[]=array("$i", "$i"); + } + $atext=FlattenText($qrow[1]); } - $atext=FlattenText($qrow[1]); - } - $qquestion .= $linefeed."[".$atext."]"; - $qtitle .= "($qanswer)"; - break; + $qquestion .= $linefeed."[".$atext."]"; + $qtitle .= "($qanswer)"; + break; - //Array of Yes/No/$statlang->gT("Uncertain") - case "C": - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); + //Array of Yes/No/$statlang->gT("Uncertain") + case "C": + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); - //loop thorugh results - while ($qrow=$qresult->FetchRow()) - { - //add results - $alist[]=array("Y", $statlang->gT("Yes")); - $alist[]=array("N", $statlang->gT("No")); - $alist[]=array("U", $statlang->gT("Uncertain")); - $atext=FlattenText($qrow[1]); - } - //output - $qquestion .= $linefeed."[".$atext."]"; - $qtitle .= "($qanswer)"; - break; + //loop thorugh results + while ($qrow=$qresult->FetchRow()) + { + //add results + $alist[]=array("Y", $statlang->gT("Yes")); + $alist[]=array("N", $statlang->gT("No")); + $alist[]=array("U", $statlang->gT("Uncertain")); + $atext=FlattenText($qrow[1]); + } + //output + $qquestion .= $linefeed."[".$atext."]"; + $qtitle .= "($qanswer)"; + break; - //Array of Yes/No/$statlang->gT("Uncertain") - //same as above - case "E": - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); - while ($qrow=$qresult->FetchRow()) - { - $alist[]=array("I", $statlang->gT("Increase")); - $alist[]=array("S", $statlang->gT("Same")); - $alist[]=array("D", $statlang->gT("Decrease")); - $atext=FlattenText($qrow[1]); - } - $qquestion .= $linefeed."[".$atext."]"; - $qtitle .= "($qanswer)"; - break; + //Array of Yes/No/$statlang->gT("Uncertain") + //same as above + case "E": + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); + while ($qrow=$qresult->FetchRow()) + { + $alist[]=array("I", $statlang->gT("Increase")); + $alist[]=array("S", $statlang->gT("Same")); + $alist[]=array("D", $statlang->gT("Decrease")); + $atext=FlattenText($qrow[1]); + } + $qquestion .= $linefeed."[".$atext."]"; + $qtitle .= "($qanswer)"; + break; - case ";": //Array (Multi Flexi) (Text) - list($qacode, $licode)=explode("_", $qanswer); + case ";": //Array (Multi Flexi) (Text) + list($qacode, $licode)=explode("_", $qanswer); - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qacode' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qacode' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); - while ($qrow=$qresult->FetchRow()) - { - $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qiqid}' AND scale_id=0 AND code = '{$licode}' AND language='{$language}'ORDER BY sortorder, code"; - $fresult = db_execute_assoc($fquery); - while ($frow=$fresult->FetchRow()) + while ($qrow=$qresult->FetchRow()) { - $alist[]=array($frow['code'], $frow['answer']); - $ltext=$frow['answer']; + $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qiqid}' AND scale_id=0 AND code = '{$licode}' AND language='{$language}'ORDER BY sortorder, code"; + $fresult = db_execute_assoc($fquery); + while ($frow=$fresult->FetchRow()) + { + $alist[]=array($frow['code'], $frow['answer']); + $ltext=$frow['answer']; + } + $atext=FlattenText($qrow[1]); } - $atext=FlattenText($qrow[1]); - } - - $qquestion .= $linefeed."[".$atext."] [".$ltext."]"; - $qtitle .= "($qanswer)"; - break; + $qquestion .= $linefeed."[".$atext."] [".$ltext."]"; + $qtitle .= "($qanswer)"; + break; - case ":": //Array (Multiple Flexi) (Numbers) - $qidattributes=getQuestionAttributes($qiqid); - if (trim($qidattributes['multiflexible_max'])!='') { - $maxvalue=$qidattributes['multiflexible_max']; - } - else { - $maxvalue=10; - } - if (trim($qidattributes['multiflexible_min'])!='') - { - $minvalue=$qidattributes['multiflexible_min']; - } - else { - $minvalue=1; - } + case ":": //Array (Multiple Flexi) (Numbers) + $qidattributes=getQuestionAttributes($qiqid); + if (trim($qidattributes['multiflexible_max'])!='') { + $maxvalue=$qidattributes['multiflexible_max']; + } + else { + $maxvalue=10; + } - if (trim($qidattributes['multiflexible_step'])!='') - { - $stepvalue=$qidattributes['multiflexible_step']; - } - else { - $stepvalue=1; - } + if (trim($qidattributes['multiflexible_min'])!='') + { + $minvalue=$qidattributes['multiflexible_min']; + } + else { + $minvalue=1; + } - if ($qidattributes['multiflexible_checkbox']!=0) { - $minvalue=0; - $maxvalue=1; - $stepvalue=1; - } + if (trim($qidattributes['multiflexible_step'])!='') + { + $stepvalue=$qidattributes['multiflexible_step']; + } + else { + $stepvalue=1; + } - for($i=$minvalue; $i<=$maxvalue; $i+=$stepvalue) - { - $alist[]=array($i, $i); - } + if ($qidattributes['multiflexible_checkbox']!=0) { + $minvalue=0; + $maxvalue=1; + $stepvalue=1; + } - $qquestion .= $linefeed."[".$fielddata['subquestion1']."] [".$fielddata['subquestion2']."]"; - list($myans, $mylabel)=explode("_", $qanswer); - $qtitle .= "[$myans][$mylabel]"; - break; + for($i=$minvalue; $i<=$maxvalue; $i+=$stepvalue) + { + $alist[]=array($i, $i); + } - case "F": //Array of Flexible - case "H": //Array of Flexible by Column - $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); + $qquestion .= $linefeed."[".$fielddata['subquestion1']."] [".$fielddata['subquestion2']."]"; + list($myans, $mylabel)=explode("_", $qanswer); + $qtitle .= "[$myans][$mylabel]"; + break; - //loop through answers - while ($qrow=$qresult->FetchRow()) - { - //this question type uses its own labels - $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qiqid}' AND scale_id=0 AND language='{$language}'ORDER BY sortorder, code"; - $fresult = db_execute_assoc($fquery); + case "F": //Array of Flexible + case "H": //Array of Flexible by Column + $qquery = "SELECT title, question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $qresult=db_execute_num($qquery) or safe_die ("Couldn't get answer details
$qquery
".$connect->ErrorMsg()); - //add code and title to results for outputting them later - while ($frow=$fresult->FetchRow()) + //loop through answers + while ($qrow=$qresult->FetchRow()) { - $alist[]=array($frow['code'], FlattenText($frow['answer'])); + //this question type uses its own labels + $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qiqid}' AND scale_id=0 AND language='{$language}'ORDER BY sortorder, code"; + $fresult = db_execute_assoc($fquery); + + //add code and title to results for outputting them later + while ($frow=$fresult->FetchRow()) + { + $alist[]=array($frow['code'], FlattenText($frow['answer'])); + } + + //counter + $atext=FlattenText($qrow[1]); } - //counter - $atext=FlattenText($qrow[1]); - } + //output + $qquestion .= $linefeed."[".$atext."]"; + $qtitle .= "($qanswer)"; + break; + - //output - $qquestion .= $linefeed."[".$atext."]"; - $qtitle .= "($qanswer)"; - break; + case "G": //Gender + $alist[]=array("F", $statlang->gT("Female")); + $alist[]=array("M", $statlang->gT("Male")); + break; - case "G": //Gender - $alist[]=array("F", $statlang->gT("Female")); - $alist[]=array("M", $statlang->gT("Male")); - break; + case "Y": //Yes\No + $alist[]=array("Y", $statlang->gT("Yes")); + $alist[]=array("N", $statlang->gT("No")); + break; - case "Y": //Yes\No - $alist[]=array("Y", $statlang->gT("Yes")); - $alist[]=array("N", $statlang->gT("No")); - break; + case "I": //Language + // Using previously defined $surveylanguagecodes array of language codes + foreach ($surveylanguagecodes as $availlang) + { + $alist[]=array($availlang, getLanguageNameFromCode($availlang,false)); + } + break; - case "I": //Language - // Using previously defined $surveylanguagecodes array of language codes - foreach ($surveylanguagecodes as $availlang) - { - $alist[]=array($availlang, getLanguageNameFromCode($availlang,false)); - } - break; + case "5": //5 Point (just 1 item to rank!) + for ($i=1; $i<=5; $i++) + { + $alist[]=array("$i", "$i"); + } + break; - case "5": //5 Point (just 1 item to rank!) - for ($i=1; $i<=5; $i++) - { - $alist[]=array("$i", "$i"); - } - break; + case "1": //array (dual scale) + $sSubquestionQuery = "SELECT question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; + $sSubquestion=FlattenText($connect->GetOne($sSubquestionQuery)); - case "1": //array (dual scale) + //get question attributes + $qidattributes=getQuestionAttributes($qqid); - $sSubquestionQuery = "SELECT question FROM ".db_table_name("questions")." WHERE parent_qid='$qiqid' AND title='$qanswer' AND language='{$language}' ORDER BY question_order"; - $sSubquestion=FlattenText($connect->GetOne($sSubquestionQuery)); + //check last character -> label 1 + if (substr($rt,-1,1) == 0) + { + //get label 1 + $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qqid}' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, code"; - //get question attributes - $qidattributes=getQuestionAttributes($qqid); + //header available? + if (trim($qidattributes['dualscale_headerA'])!='') { + //output + $labelheader= "[".$qidattributes['dualscale_headerA']."]"; + } - //check last character -> label 1 - if (substr($rt,-1,1) == 0) - { - //get label 1 - $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qqid}' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, code"; + //no header + else + { + $labelheader =''; + } - //header available? - if (trim($qidattributes['dualscale_headerA'])!='') { //output - $labelheader= "[".$qidattributes['dualscale_headerA']."]"; + $labelno = sprintf($clang->gT('Label %s'),'1'); } - //no header + //label 2 else { - $labelheader =''; - } + //get label 2 + $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qqid}' AND scale_id=1 AND language='{$language}' ORDER BY sortorder, code"; - //output - $labelno = sprintf($clang->gT('Label %s'),'1'); - } + //header available? + if (trim($qidattributes['dualscale_headerB'])!='') { + //output + $labelheader= "[".$qidattributes['dualscale_headerB']."]"; + } - //label 2 - else - { - //get label 2 - $fquery = "SELECT * FROM ".db_table_name("answers")." WHERE qid='{$qqid}' AND scale_id=1 AND language='{$language}' ORDER BY sortorder, code"; + //no header + else + { + $labelheader =''; + } - //header available? - if (trim($qidattributes['dualscale_headerB'])!='') { //output - $labelheader= "[".$qidattributes['dualscale_headerB']."]"; + $labelno = sprintf($clang->gT('Label %s'),'2'); } - //no header - else + //get data + $fresult = db_execute_assoc($fquery); + + //put label code and label title into array + while ($frow=$fresult->FetchRow()) { - $labelheader =''; + $alist[]=array($frow['code'], FlattenText($frow['answer'])); } - //output - $labelno = sprintf($clang->gT('Label %s'),'2'); - } - - //get data - $fresult = db_execute_assoc($fquery); - - //put label code and label title into array - while ($frow=$fresult->FetchRow()) - { - $alist[]=array($frow['code'], FlattenText($frow['answer'])); - } - - //adapt title and question - $qtitle = $qtitle." [".$sSubquestion."][".$labelno."]"; - $qquestion = $qastring .$labelheader; - break; + //adapt title and question + $qtitle = $qtitle." [".$sSubquestion."][".$labelno."]"; + $qquestion = $qastring .$labelheader; + break; - default: //default handling + default: //default handling - //get answer code and title - $qquery = "SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='$qqid' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; - $qresult = db_execute_num($qquery) or safe_die ("Couldn't get answers list
$qquery
".$connect->ErrorMsg()); + //get answer code and title + $qquery = "SELECT code, answer FROM ".db_table_name("answers")." WHERE qid='$qqid' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; + $qresult = db_execute_num($qquery) or safe_die ("Couldn't get answers list
$qquery
".$connect->ErrorMsg()); - //put answer code and title into array - while ($qrow=$qresult->FetchRow()) - { - $alist[]=array("$qrow[0]", FlattenText($qrow[1])); - } + //put answer code and title into array + while ($qrow=$qresult->FetchRow()) + { + $alist[]=array("$qrow[0]", FlattenText($qrow[1])); + } - //handling for "other" field for list radio or list drowpdown - if ((($qtype == "L" || $qtype == "!") && $qother == "Y")) - { - //add "other" - $alist[]=array($statlang->gT("Other"),$statlang->gT("Other"),$fielddata['fieldname'].'other'); - } - if ( $qtype == "O") - { - //add "comment" - $alist[]=array($statlang->gT("Comments"),$statlang->gT("Comments"),$fielddata['fieldname'].'comment'); - } + //handling for "other" field for list radio or list drowpdown + if ((($qtype == "L" || $qtype == "!") && $qother == "Y")) + { + //add "other" + $alist[]=array($statlang->gT("Other"),$statlang->gT("Other"),$fielddata['fieldname'].'other'); + } + if ( $qtype == "O") + { + //add "comment" + $alist[]=array($statlang->gT("Comments"),$statlang->gT("Comments"),$fielddata['fieldname'].'comment'); + } - } //end switch question type + } //end switch question type - //moved because it's better to have "no answer" at the end of the list instead of the beginning - //put data into array - $alist[]=array("", $statlang->gT("No answer")); + //moved because it's better to have "no answer" at the end of the list instead of the beginning + //put data into array + $alist[]=array("", $statlang->gT("No answer")); - } //end else -> single option answers + } //end else -> single option answers - //foreach ($alist as $al) {$statisticsoutput .= "$al[0] - $al[1]
";} //debugging line - //foreach ($fvalues as $fv) {$statisticsoutput .= "$fv | ";} //debugging line + //foreach ($alist as $al) {$statisticsoutput .= "$al[0] - $al[1]
";} //debugging line + //foreach ($fvalues as $fv) {$statisticsoutput .= "$fv | ";} //debugging line - //2. Collect and Display results ####################################################################### - if (isset($alist) && $alist) //Make sure there really is an answerlist, and if so: - { + //2. Collect and Display results ####################################################################### + if (isset($alist) && $alist) //Make sure there really is an answerlist, and if so: + { - // this will count the answers considered completed - $TotalCompleted = 0; - switch($outputType) - { - case 'xls': + // this will count the answers considered completed + $TotalCompleted = 0; + switch($outputType) + { + case 'xls': - $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); - $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); + $xlsTitle = sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8')); + $xlsDesc = html_entity_decode($qquestion,ENT_QUOTES,'UTF-8'); - ++$xlsRow; - ++$xlsRow; + ++$xlsRow; + ++$xlsRow; - ++$xlsRow; - $sheet->write($xlsRow, 0,$xlsTitle); - ++$xlsRow; - $sheet->write($xlsRow, 0,$xlsDesc); + ++$xlsRow; + $sheet->write($xlsRow, 0,$xlsTitle); + ++$xlsRow; + $sheet->write($xlsRow, 0,$xlsDesc); - $tableXLS = array(); - $footXLS = array(); + $tableXLS = array(); + $footXLS = array(); - break; - case 'pdf': + break; + case 'pdf': - $sPDFQuestion=FlattenText($qquestion,true); - $pdfTitle = $pdf->delete_html(sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8'))); - $titleDesc = $sPDFQuestion; + $sPDFQuestion=FlattenText($qquestion,true); + $pdfTitle = $pdf->delete_html(sprintf($statlang->gT("Field summary for %s"),html_entity_decode($qtitle,ENT_QUOTES,'UTF-8'))); + $titleDesc = $sPDFQuestion; - $pdf->addPage('P','A4'); - $pdf->Bookmark($sPDFQuestion, 1, 0); - $pdf->titleintopdf($pdfTitle,$sPDFQuestion); - $tablePDF = array(); - $footPDF = array(); + $pdf->addPage('P','A4'); + $pdf->Bookmark($sPDFQuestion, 1, 0); + $pdf->titleintopdf($pdfTitle,$sPDFQuestion); + $tablePDF = array(); + $footPDF = array(); - break; - case 'html': - //output - $statisticsoutput .= "\n" - ."\t"; + } // end foreach -> loop through all questions - break; - default: + //output + if($outputType=='html') + $statisticsoutput .= "
 \n"; + } //end if -> show summary results - break; - } + switch($outputType) + { + case 'xls': + //$workbook-> + $workbook->close(); + if($pdfOutput=='F') + { + return $sFileName; } + else + { + return; + } + break; - //close table/output - if($outputType=='html') - $statisticsoutput .= "
" + break; + case 'html': + //output + $statisticsoutput .= "\n" + ."\t\n" - ."\t\n" + ."\t\n" - ."\t\n\t\t\n" + ."\t\n\t\t\n" - ."\t\t\n" - ."\t\t\n" - ."\t\n"; - - if (isset($_POST['showtextinline'])) { - $headPDF2=array(); - $headPDF2[]=array($statlang->gt("Responses")); - $tablePDF2=array(); - $query2 = "SELECT ".db_quote_id($al[2])." FROM ".db_table_name("survey_$surveyid")." WHERE "; - $query2 .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; - $result2=db_execute_num($query2) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); - $fnamelast = "
\n"; - $fnamelast .= "".$clang->gT("Responses")."
\n"; - //$fname .= $query2; - while ($row2=$result2->FetchRow()) - { - $fnamelast .= $row2[0]."
\n"; - $tablePDF2[]=array($row2[0]); - } - $fnamelast .= "
\n"; - - } - } + $statisticsoutput .= "\n" + ."\t\t\n" + ."\t\t\n" + ."\t\n"; + + if (isset($_POST['showtextinline'])) { + $headPDF2=array(); + $headPDF2[]=array($statlang->gt("Responses")); + $tablePDF2=array(); + $query2 = "SELECT ".db_quote_id($al[2])." FROM ".db_table_name("survey_$surveyid")." WHERE "; + $query2 .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; + $result2=db_execute_num($query2) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); + $fnamelast = "
\n"; + $fnamelast .= "".$clang->gT("Responses")."
\n"; + //$fname .= $query2; + while ($row2=$result2->FetchRow()) + { + $fnamelast .= $row2[0]."
\n"; + $tablePDF2[]=array($row2[0]); + } + $fnamelast .= "
\n"; + } + } - //check if aggregated results should be shown - elseif (isset($showaggregateddata) && $showaggregateddata == 1) - { - if(!isset($showheadline) || $showheadline != false) + + //check if aggregated results should be shown + elseif (isset($showaggregateddata) && $showaggregateddata == 1) { - if($qtype == "5" || $qtype == "A") + if(!isset($showheadline) || $showheadline != false) { - switch($outputType) + if($qtype == "5" || $qtype == "A") { - case 'xls': + switch($outputType) + { + case 'xls': - $headXLS = array(); - $headXLS[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage"),$statlang->gT("Sum")); + $headXLS = array(); + $headXLS[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage"),$statlang->gT("Sum")); - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Answer")); - $sheet->write($xlsRow,1,$statlang->gT("Count")); - $sheet->write($xlsRow,2,$statlang->gT("Percentage")); - $sheet->write($xlsRow,3,$statlang->gT("Sum")); + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Answer")); + $sheet->write($xlsRow,1,$statlang->gT("Count")); + $sheet->write($xlsRow,2,$statlang->gT("Percentage")); + $sheet->write($xlsRow,3,$statlang->gT("Sum")); - break; - case 'pdf': + break; + case 'pdf': - $headPDF = array(); - $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage"),$statlang->gT("Sum")); + $headPDF = array(); + $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage"),$statlang->gT("Sum")); - break; - case 'html': - //four columns - $statisticsoutput .= "".$statlang->gT("Answer")."\n" - ."\t\t\n" - ."\t\t\n" - ."\t\t\n" - ."\t\n"; - break; - default: + break; + case 'html': + //four columns + $statisticsoutput .= "".$statlang->gT("Answer")."\n" + ."\t\t\n" + ."\t\t\n" + ."\t\t\n" + ."\t\n"; + break; + default: - break; + break; + } + + + $showheadline = false; } + else + { + switch($outputType) + { + case 'xls': + $headXLS = array(); + $headXLS[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); + + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Answer")); + $sheet->write($xlsRow,1,$statlang->gT("Count")); + $sheet->write($xlsRow,2,$statlang->gT("Percentage")); + + break; + + case 'pdf': + + $headPDF = array(); + $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); + + break; + case 'html': + //three columns + $statisticsoutput .= "".$statlang->gT("Answer")."\n" + ."\t\t\n" + ."\t\t\n" + ."\t\n"; + break; + default: + + + break; + } + + $showheadline = false; + } - $showheadline = false; } - else + + //text for answer column is always needed + $fname="$al[1] ($al[0])"; + + //these question types get special treatment by $showaggregateddata + if($qtype == "5" || $qtype == "A") + { + //put non-edited data in here because $row will be edited later + $grawdata[]=$row[0]; + $showaggregated_indice=count($grawdata) - 1; + $showaggregated_indice_table[$showaggregated_indice]="aggregated"; + $showaggregated_indice=-1; + + //keep in mind that we already added data (will be checked later) + $justadded = true; + + //we need a counter because we want to sum up certain values + //reset counter if 5 items have passed + if(!isset($testcounter) || $testcounter >= 4) + { + $testcounter = 0; + } + else + { + $testcounter++; + } + + //beside the known percentage value a new aggregated value should be shown + //therefore this item is marked in a certain way + + if($testcounter == 0 ) //add 300 to original value + { + //HACK: add three times the total number of results to the value + //This way we get a 300 + X percentage which can be checked later + $row[0] += (3*$results); + } + + //the third value should be shown twice later -> mark it + if($testcounter == 2) //add 400 to original value + { + //HACK: add four times the total number of results to the value + //This way there should be a 400 + X percentage which can be checked later + $row[0] += (4*$results); + } + + //the last value aggregates the data of item 4 + item 5 later + if($testcounter == 4 ) //add 200 to original value + { + //HACK: add two times the total number of results to the value + //This way there should be a 200 + X percentage which can be checked later + $row[0] += (2*$results); + } + + } //end if -> question type = "5"/"A" + + } //end if -> show aggregated data + + //handling what's left + else + { + if(!isset($showheadline) || $showheadline != false) { switch($outputType) { @@ -2202,7 +2287,6 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, $sheet->write($xlsRow,2,$statlang->gT("Percentage")); break; - case 'pdf': $headPDF = array(); @@ -2211,7 +2295,7 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, break; case 'html': //three columns - $statisticsoutput .= "".$statlang->gT("Answer")."\n" + $statisticsoutput .= "".$statlang->gT("Answer")."\n" ."\t\t\n" ."\t\t\n" - ."\t\t\n" - ."\t\t\n" - ."\t\n"; - break; - default: - - - break; + //we want to have some "real" data here + if ($gdata[$i] != "N/A") + { + //calculate percentage + $gdata[$i] = ($grawdata[$i]/$TotalCompleted)*100; + } } - $showheadline = false; + //increase counter + $i++; - } - //answer text - $fname="$al[1] ($al[0])"; - } + } //end while (data available) - //are there some results to play with? - if ($results > 0) - { - //calculate percentage - $gdata[] = ($row[0]/$results)*100; - } - //no results - else - { - //no data! - $gdata[] = "N/A"; - } + } //end if -> noncompleted checked - //only add this if we don't handle question type "5"/"A" - if(!isset($justadded)) - { - //put absolute data into array - $grawdata[]=$row[0]; - } + //noncompleted is NOT checked else { - //unset to handle "no answer" data correctly - unset($justadded); - } + //calculate total number of incompleted records + $TotalIncomplete = $results - $TotalCompleted; - //put question title and code into array - $label[]=$fname; + //output + if ((incompleteAnsFilterstate() != "filter")) + { + $fname=$statlang->gT("Not completed or Not displayed"); + } + else + { + $fname=$statlang->gT("Not displayed"); + } - //put only the code into the array - $justcode[]=$al[0]; + //we need some data + if ($results > 0) + { + //calculate percentage + $gdata[] = ($TotalIncomplete/$results)*100; + } - //edit labels and put them into antoher array - $lbl[] = wordwrap(FlattenText("$al[1] ($row[0])"), 25, "\n"); // NMO 2009-03-24 - $lblrtl[] = utf8_strrev(wordwrap(FlattenText("$al[1] )$row[0]("), 25, "\n")); // NMO 2009-03-24 + //no data :( + else + { + $gdata[] = "N/A"; + } - } //end while -> loop through results + //put data of incompleted records into array + $grawdata[]=$TotalIncomplete; - } //end foreach -> loop through answer data + //put question title ("Not completed") into array + $label[]= $fname; - //no filtering of incomplete answers and NO multiple option questions - //if ((incompleteAnsFilterstate() != "filter") and ($qtype != "M") and ($qtype != "P")) - //error_log("TIBO ".print_r($showaggregated_indice_table,true)); - if (($qtype != "M") and ($qtype != "P")) - { - //is the checkbox "Don't consider NON completed responses (only works when Filter incomplete answers is Disable)" checked? - //if (isset($_POST["noncompleted"]) and ($_POST["noncompleted"] == "on") && (isset($showaggregateddata) && $showaggregateddata == 0)) - // TIBO: TODO WE MUST SKIP THE FOLLOWING SECTION FOR TYPE A and 5 when - // showaggreagated data is set and set to 1 - if (isset($_POST["noncompleted"]) and ($_POST["noncompleted"] == "on") ) - { - //counter - $i=0; + //put the code ("Not completed") into the array + $justcode[]=$fname; - while (isset($gdata[$i])) - { - if (isset($showaggregated_indice_table[$i]) && $showaggregated_indice_table[$i]=="aggregated") - { // do nothing, we don't rewrite aggregated results - // or at least I don't know how !!! (lemeur) + //edit labels and put them into antoher array + if ((incompleteAnsFilterstate() != "filter")) + { + $lbl[] = wordwrap(FlattenText($statlang->gT("Not completed or Not displayed")." ($TotalIncomplete)"), 20, "\n"); // NMO 2009-03-24 } else { - //we want to have some "real" data here - if ($gdata[$i] != "N/A") - { - //calculate percentage - $gdata[$i] = ($grawdata[$i]/$TotalCompleted)*100; - } + $lbl[] = wordwrap(FlattenText($statlang->gT("Not displayed")." ($TotalIncomplete)"), 20, "\n"); // NMO 2009-03-24 } + } //end else -> noncompleted NOT checked - //increase counter - $i++; + } //end if -> no filtering of incomplete answers and no multiple option questions - } //end while (data available) - } //end if -> noncompleted checked + //counter + $i=0; - //noncompleted is NOT checked - else - { - //calculate total number of incompleted records - $TotalIncomplete = $results - $TotalCompleted; + //we need to know which item we are editing + $itemcounter = 1; - //output - if ((incompleteAnsFilterstate() != "filter")) - { - $fname=$statlang->gT("Not completed or Not displayed"); - } - else - { - $fname=$statlang->gT("Not displayed"); - } + //array to store items 1 - 5 of question types "5" and "A" + $stddevarray = array(); - //we need some data - if ($results > 0) - { - //calculate percentage - $gdata[] = ($TotalIncomplete/$results)*100; - } + //loop through all available answers + while (isset($gdata[$i])) + { + //repeat header (answer, count, ...) for each new question + unset($showheadline); - //no data :( - else - { - $gdata[] = "N/A"; - } - //put data of incompleted records into array - $grawdata[]=$TotalIncomplete; + /* + * there are 3 colums: + * + * 1 (50%) = answer (title and code in brackets) + * 2 (25%) = count (absolute) + * 3 (25%) = percentage + */ + $statisticsoutput .= "\t\n\t\t\n" - //put question title ("Not completed") into array - $label[]= $fname; + //output absolute number of records + ."\t\t"; - //put the code ("Not completed") into the array - $justcode[]=$fname; - //edit labels and put them into antoher array - if ((incompleteAnsFilterstate() != "filter")) - { - $lbl[] = wordwrap(FlattenText($statlang->gT("Not completed or Not displayed")." ($TotalIncomplete)"), 20, "\n"); // NMO 2009-03-24 - } - else + //no data + if ($gdata[$i] == "N/A") { - $lbl[] = wordwrap(FlattenText($statlang->gT("Not displayed")." ($TotalIncomplete)"), 20, "\n"); // NMO 2009-03-24 - } - } //end else -> noncompleted NOT checked + switch($outputType) + { + case 'xls': - } //end if -> no filtering of incomplete answers and no multiple option questions + $label[$i]=FlattenText($label[$i]); + $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i]). "%"); + ++$xlsRow; + $sheet->write($xlsRow,0,$label[$i]); + $sheet->write($xlsRow,1,$grawdata[$i]); + $sheet->write($xlsRow,2,sprintf("%01.2f", $gdata[$i]). "%"); - //counter - $i=0; + break; + case 'pdf': - //we need to know which item we are editing - $itemcounter = 1; + $tablePDF[] = array(FlattenText($label[$i]),$grawdata[$i],sprintf("%01.2f", $gdata[$i]). "%", ""); - //array to store items 1 - 5 of question types "5" and "A" - $stddevarray = array(); + break; + case 'html': + //output when having no data + $statisticsoutput .= "\t\t"; + } + elseif ($qtype == "S" || $qtype == "U" || $qtype == "T" || $qtype == "Q") + { + $statisticsoutput .= "\n\t\n"; + } + break; + default: - /* - * there are 3 colums: - * - * 1 (50%) = answer (title and code in brackets) - * 2 (25%) = count (absolute) - * 3 (25%) = percentage - */ - $statisticsoutput .= "\t\n\t\t\n" - //output absolute number of records - ."\t\t"; + break; + } + } - //no data - if ($gdata[$i] == "N/A") - { - switch($outputType) + //data available + else { - case 'xls': + //check if data should be aggregated + if(isset($showaggregateddata) && $showaggregateddata == 1 && ($qtype == "5" || $qtype == "A")) + { + //mark that we have done soemthing special here + $aggregated = true; - $label[$i]=FlattenText($label[$i]); - $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i]). "%"); + //just calculate everything once. the data is there in the array + if($itemcounter == 1) + { + //there are always 5 answers + for($x = 0; $x < 5; $x++) + { + //put 5 items into array for further calculations + array_push($stddevarray, $grawdata[$x]); + } + } - ++$xlsRow; - $sheet->write($xlsRow,0,$label[$i]); - $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $gdata[$i]). "%"); + //"no answer" & items 2 / 4 - nothing special to do here, just adjust output + if($gdata[$i] <= 100) + { + if($itemcounter == 2 && $label[$i+4] == $statlang->gT("No answer")) + { + //prevent division by zero + if(($results - $grawdata[$i+4]) > 0) + { + //re-calculate percentage + $percentage = ($grawdata[$i] / ($results - $grawdata[$i+4])) * 100; + } + else + { + $percentage = 0; + } - break; - case 'pdf': + } + elseif($itemcounter == 4 && $label[$i+2] == $statlang->gT("No answer")) + { + //prevent division by zero + if(($results - $grawdata[$i+2]) > 0) + { + //re-calculate percentage + $percentage = ($grawdata[$i] / ($results - $grawdata[$i+2])) * 100; + } + else + { + $percentage = 0; + } + } + else + { + $percentage = $gdata[$i]; + } + switch($outputType) + { + case 'xls': - $tablePDF[] = array(FlattenText($label[$i]),$grawdata[$i],sprintf("%01.2f", $gdata[$i]). "%", ""); + $label[$i]=FlattenText($label[$i]); + $tableXLS[]= array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%"); - break; - case 'html': - //output when having no data - $statisticsoutput .= "\t\t"; - } - elseif ($qtype == "S" || $qtype == "U" || $qtype == "T" || $qtype == "Q") - { - $statisticsoutput .= "\n\t\n"; - } - break; - default: + break; + case 'html': + //output + $statisticsoutput .= "\t\t"; + break; + default: - } - //data available - else - { - //check if data should be aggregated - if(isset($showaggregateddata) && $showaggregateddata == 1 && ($qtype == "5" || $qtype == "A")) - { - //mark that we have done soemthing special here - $aggregated = true; + break; + } - //just calculate everything once. the data is there in the array - if($itemcounter == 1) - { - //there are always 5 answers - for($x = 0; $x < 5; $x++) - { - //put 5 items into array for further calculations - array_push($stddevarray, $grawdata[$x]); } - } - //"no answer" & items 2 / 4 - nothing special to do here, just adjust output - if($gdata[$i] <= 100) - { - if($itemcounter == 2 && $label[$i+4] == $statlang->gT("No answer")) + //item 3 - just show results twice + //old: if($gdata[$i] >= 400) + //trying to fix bug #2583: + if($gdata[$i] >= 400 && $i != 0) { - //prevent division by zero - if(($results - $grawdata[$i+4]) > 0) + //remove "400" which was added before + $gdata[$i] -= 400; + + if($itemcounter == 3 && $label[$i+3] == $statlang->gT("No answer")) { - //re-calculate percentage - $percentage = ($grawdata[$i] / ($results - $grawdata[$i+4])) * 100; + //prevent division by zero + if(($results - $grawdata[$i+3]) > 0) + { + //re-calculate percentage + $percentage = ($grawdata[$i] / ($results - $grawdata[$i+3])) * 100; + } + else + { + $percentage = 0; + } } else { - $percentage = 0; + //get the original percentage + $percentage = $gdata[$i]; + } + switch($outputType) + { + case 'xls': + + $label[$i]=FlattenText($label[$i]); + $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $percentage)."%"); + + ++$xlsRow; + $sheet->write($xlsRow,0,$label[$i]); + $sheet->write($xlsRow,1,$grawdata[$i]); + $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); + $sheet->write($xlsRow,3,sprintf("%01.2f", $percentage)."%"); + + break; + case 'pdf': + $label[$i]=FlattenText($label[$i]); + $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $percentage)."%"); + + break; + case 'html': + //output percentage + $statisticsoutput .= "\t\t"; + + //output again (no real aggregation here) + $statisticsoutput .= "\t\t\t\t"; + break; + default: + + + break; } } - elseif($itemcounter == 4 && $label[$i+2] == $statlang->gT("No answer")) + + //FIRST value -> add percentage of item 1 + item 2 + //old: if($gdata[$i] >= 300 && $gdata[$i] < 400) + //trying to fix bug #2583: + if(($gdata[$i] >= 300 && $gdata[$i] < 400) || ($i == 0 && $gdata[$i] <= 400)) { - //prevent division by zero - if(($results - $grawdata[$i+2]) > 0) + //remove "300" which was added before + $gdata[$i] -= 300; + + if($itemcounter == 1 && $label[$i+5] == $statlang->gT("No answer")) { - //re-calculate percentage - $percentage = ($grawdata[$i] / ($results - $grawdata[$i+2])) * 100; + //prevent division by zero + if(($results - $grawdata[$i+5]) > 0) + { + //re-calculate percentage + $percentage = ($grawdata[$i] / ($results - $grawdata[$i+5])) * 100; + $percentage2 = ($grawdata[$i + 1] / ($results - $grawdata[$i+5])) * 100; + } + else + { + $percentage = 0; + $percentage2 = 0; + + } } else { - $percentage = 0; + $percentage = $gdata[$i]; + $percentage2 = $gdata[$i+1]; } - } - else - { - $percentage = $gdata[$i]; - } - switch($outputType) - { - case 'xls': + //percentage of item 1 + item 2 + $aggregatedgdata = $percentage + $percentage2; - $label[$i]=FlattenText($label[$i]); - $tableXLS[]= array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%"); - ++$xlsRow; - $sheet->write($xlsRow,0,$label[$i]); - $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); + switch($outputType) + { + case 'xls': - break; - case 'pdf': - $label[$i]=FlattenText($label[$i]); - $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%", ""); + $label[$i]=FlattenText($label[$i]); + $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); - break; - case 'html': - //output - $statisticsoutput .= "\t\t"; - break; - default: + break; + case 'html': + //output percentage + $statisticsoutput .= "\t\t"; + + //output aggregated data + $statisticsoutput .= "\t\t\t\t"; + break; + default: - break; + break; + } } - } - - //item 3 - just show results twice - //old: if($gdata[$i] >= 400) - //trying to fix bug #2583: - if($gdata[$i] >= 400 && $i != 0) - { - //remove "400" which was added before - $gdata[$i] -= 400; - - if($itemcounter == 3 && $label[$i+3] == $statlang->gT("No answer")) + //LAST value -> add item 4 + item 5 + if($gdata[$i] > 100 && $gdata[$i] < 300) { - //prevent division by zero - if(($results - $grawdata[$i+3]) > 0) + //remove "200" which was added before + $gdata[$i] -= 200; + + if($itemcounter == 5 && $label[$i+1] == $statlang->gT("No answer")) { - //re-calculate percentage - $percentage = ($grawdata[$i] / ($results - $grawdata[$i+3])) * 100; + //prevent division by zero + if(($results - $grawdata[$i+1]) > 0) + { + //re-calculate percentage + $percentage = ($grawdata[$i] / ($results - $grawdata[$i+1])) * 100; + $percentage2 = ($grawdata[$i - 1] / ($results - $grawdata[$i+1])) * 100; + } + else + { + $percentage = 0; + $percentage2 = 0; + } } else { - $percentage = 0; + $percentage = $gdata[$i]; + $percentage2 = $gdata[$i-1]; } - } - else - { - //get the original percentage - $percentage = $gdata[$i]; - } - switch($outputType) - { - case 'xls': - $label[$i]=FlattenText($label[$i]); - $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $percentage)."%"); - - ++$xlsRow; - $sheet->write($xlsRow,0,$label[$i]); - $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); - $sheet->write($xlsRow,3,sprintf("%01.2f", $percentage)."%"); + //item 4 + item 5 + $aggregatedgdata = $percentage + $percentage2; + switch($outputType) + { + case 'xls': - break; - case 'pdf': - $label[$i]=FlattenText($label[$i]); - $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $percentage)."%"); + $label[$i]=FlattenText($label[$i]); + $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); - break; - case 'html': - //output percentage - $statisticsoutput .= "\t\t"; + ++$xlsRow; + $sheet->write($xlsRow,0,$label[$i]); + $sheet->write($xlsRow,1,$grawdata[$i]); + $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); + $sheet->write($xlsRow,3,sprintf("%01.2f", $aggregatedgdata)."%"); - //output again (no real aggregation here) - $statisticsoutput .= "\t\t\t\t"; - break; - default: + break; + case 'pdf': + $label[$i]=FlattenText($label[$i]); + $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); + break; + case 'html': + //output percentage + $statisticsoutput .= "\t\t"; + + //output aggregated data + $statisticsoutput .= "\t\t\t\t"; + break; + default: - break; - } - } + break; + } - //FIRST value -> add percentage of item 1 + item 2 - //old: if($gdata[$i] >= 300 && $gdata[$i] < 400) - //trying to fix bug #2583: - if(($gdata[$i] >= 300 && $gdata[$i] < 400) || ($i == 0 && $gdata[$i] <= 400)) - { - //remove "300" which was added before - $gdata[$i] -= 300; + // create new row "sum" + //calculate sum of items 1-5 + $sumitems = $grawdata[$i] + + $grawdata[$i-1] + + $grawdata[$i-2] + + $grawdata[$i-3] + + $grawdata[$i-4]; - if($itemcounter == 1 && $label[$i+5] == $statlang->gT("No answer")) - { - //prevent division by zero - if(($results - $grawdata[$i+5]) > 0) + //special treatment for zero values + if($sumitems > 0) { - //re-calculate percentage - $percentage = ($grawdata[$i] / ($results - $grawdata[$i+5])) * 100; - $percentage2 = ($grawdata[$i + 1] / ($results - $grawdata[$i+5])) * 100; + $sumpercentage = "100.00"; } else { - $percentage = 0; - $percentage2 = 0; - + $sumpercentage = "0"; } - } - else - { - $percentage = $gdata[$i]; - $percentage2 = $gdata[$i+1]; - } - //percentage of item 1 + item 2 - $aggregatedgdata = $percentage + $percentage2; - - - switch($outputType) - { - case 'xls': - - $label[$i]=FlattenText($label[$i]); - $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); + //special treatment for zero values + if($TotalCompleted > 0) + { + $casepercentage = "100.00"; + } + else + { + $casepercentage = "0"; + } + switch($outputType) + { + case 'xls': - ++$xlsRow; - $sheet->write($xlsRow,0,$label[$i]); - $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); - $sheet->write($xlsRow,3,sprintf("%01.2f", $aggregatedgdata)."%"); - break; - case 'pdf': - $label[$i]=FlattenText($label[$i]); - $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); + $footXLS[] = array($statlang->gT("Sum")." (".$statlang->gT("Answers").")",$sumitems,$sumpercentage."%",$sumpercentage."%"); + $footXLS[] = array($statlang->gT("Number of cases"),$TotalCompleted,$casepercentage."%",""); - break; - case 'html': - //output percentage - $statisticsoutput .= "\t\t"; + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Sum")." (".$statlang->gT("Answers").")"); + $sheet->write($xlsRow,1,$sumitems); + $sheet->write($xlsRow,2,$sumpercentage."%"); + $sheet->write($xlsRow,3,$sumpercentage."%"); + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Number of cases")); + $sheet->write($xlsRow,1,$TotalCompleted); + $sheet->write($xlsRow,2,$casepercentage."%"); - //output aggregated data - $statisticsoutput .= "\t\t\t\t"; - break; - default: + break; + case 'pdf': + $footPDF[] = array($statlang->gT("Sum")." (".$statlang->gT("Answers").")",$sumitems,$sumpercentage."%",$sumpercentage."%"); + $footPDF[] = array($statlang->gT("Number of cases"),$TotalCompleted,$casepercentage."%",""); - break; - } - } + break; + case 'html': + $statisticsoutput .= "\t\t \n\t\n"; + $statisticsoutput .= ""; + $statisticsoutput .= ""; + $statisticsoutput .= ""; + $statisticsoutput .= ""; + $statisticsoutput .= "\t\t \n\t\n"; + + $statisticsoutput .= ""; //German: "Fallzahl" + $statisticsoutput .= ""; + $statisticsoutput .= ""; + //there has to be a whitespace within the table cell to display correctly + $statisticsoutput .= ""; + break; + default: - //LAST value -> add item 4 + item 5 - if($gdata[$i] > 100 && $gdata[$i] < 300) - { - //remove "200" which was added before - $gdata[$i] -= 200; - if($itemcounter == 5 && $label[$i+1] == $statlang->gT("No answer")) - { - //prevent division by zero - if(($results - $grawdata[$i+1]) > 0) - { - //re-calculate percentage - $percentage = ($grawdata[$i] / ($results - $grawdata[$i+1])) * 100; - $percentage2 = ($grawdata[$i - 1] / ($results - $grawdata[$i+1])) * 100; - } - else - { - $percentage = 0; - $percentage2 = 0; + break; } + } - else - { - $percentage = $gdata[$i]; - $percentage2 = $gdata[$i-1]; - } - //item 4 + item 5 - $aggregatedgdata = $percentage + $percentage2; + } //end if -> show aggregated data + + //don't show aggregated data + else + { switch($outputType) { case 'xls': - $label[$i]=FlattenText($label[$i]); - $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); + $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i])."%", ""); ++$xlsRow; $sheet->write($xlsRow,0,$label[$i]); $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); - $sheet->write($xlsRow,3,sprintf("%01.2f", $aggregatedgdata)."%"); + $sheet->write($xlsRow,2,sprintf("%01.2f", $gdata[$i])."%"); + //$sheet->write($xlsRow,3,$sumpercentage."%"); break; case 'pdf': $label[$i]=FlattenText($label[$i]); - $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); + $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i])."%", ""); break; case 'html': //output percentage $statisticsoutput .= "\t\t"; - - //output aggregated data - $statisticsoutput .= "\t\t\t\t"; + $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; + $statisticsoutput .= "\t\t"; + //end output per line. there has to be a whitespace within the table cell to display correctly + $statisticsoutput .= "\t\t \n\t\n"; break; default: @@ -2822,241 +2916,375 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, break; } - // create new row "sum" - //calculate sum of items 1-5 - $sumitems = $grawdata[$i] - + $grawdata[$i-1] - + $grawdata[$i-2] - + $grawdata[$i-3] - + $grawdata[$i-4]; + } + + } //end else -> $gdata[$i] != "N/A" - //special treatment for zero values - if($sumitems > 0) - { - $sumpercentage = "100.00"; - } - else + + + //increase counter + $i++; + + $itemcounter++; + + } //end while + if(isset($fnamelast)) { + $statisticsoutput.= "\n"; + unset($fnamelast); + } + //only show additional values when this setting is enabled + if(isset($showaggregateddata) && $showaggregateddata == 1 ) + { + //it's only useful to calculate standard deviation and arithmetic means for question types + //5 = 5 Point Scale + //A = Array (5 Point Choice) + if($qtype == "5" || $qtype == "A") + { + $stddev = 0; + $am = 0; + + //calculate arithmetic mean + if(isset($sumitems) && $sumitems > 0) + { + + + //calculate and round results + //there are always 5 items + for($x = 0; $x < 5; $x++) { - $sumpercentage = "0"; + //create product of item * value + $am += (($x+1) * $stddevarray[$x]); } - //special treatment for zero values - if($TotalCompleted > 0) + + //prevent division by zero + if(isset($stddevarray) && array_sum($stddevarray) > 0) { - $casepercentage = "100.00"; + $am = round($am / array_sum($stddevarray),2); } else { - $casepercentage = "0"; + $am = 0; } - switch($outputType) - { - case 'xls': - - $footXLS[] = array($statlang->gT("Sum")." (".$statlang->gT("Answers").")",$sumitems,$sumpercentage."%",$sumpercentage."%"); - $footXLS[] = array($statlang->gT("Number of cases"),$TotalCompleted,$casepercentage."%",""); + //calculate standard deviation -> loop through all data + /* + * four steps to calculate the standard deviation + * 1 = calculate difference between item and arithmetic mean and multiply with the number of elements + * 2 = create sqaure value of difference + * 3 = sum up square values + * 4 = multiply result with 1 / (number of items) + * 5 = get root + */ - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Sum")." (".$statlang->gT("Answers").")"); - $sheet->write($xlsRow,1,$sumitems); - $sheet->write($xlsRow,2,$sumpercentage."%"); - $sheet->write($xlsRow,3,$sumpercentage."%"); - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Number of cases")); - $sheet->write($xlsRow,1,$TotalCompleted); - $sheet->write($xlsRow,2,$casepercentage."%"); - break; - case 'pdf': - $footPDF[] = array($statlang->gT("Sum")." (".$statlang->gT("Answers").")",$sumitems,$sumpercentage."%",$sumpercentage."%"); - $footPDF[] = array($statlang->gT("Number of cases"),$TotalCompleted,$casepercentage."%",""); + for($j = 0; $j < 5; $j++) + { + //1 = calculate difference between item and arithmetic mean + $diff = (($j+1) - $am); - break; - case 'html': - $statisticsoutput .= "\t\t \n\t\n"; - $statisticsoutput .= ""; - $statisticsoutput .= ""; - $statisticsoutput .= ""; - $statisticsoutput .= ""; - $statisticsoutput .= "\t\t \n\t\n"; - - $statisticsoutput .= ""; //German: "Fallzahl" - $statisticsoutput .= ""; - $statisticsoutput .= ""; - //there has to be a whitespace within the table cell to display correctly - $statisticsoutput .= ""; - break; - default: + //2 = create square value of difference + $squarevalue = square($diff); + //3 = sum up square values and multiply them with the occurence + //prevent divison by zero + if($squarevalue != 0 && $stddevarray[$j] != 0) + { + $stddev += $squarevalue * $stddevarray[$j]; + } - break; } - } + //4 = multiply result with 1 / (number of items (=5)) + //There are two different formulas to calculate standard derivation + //$stddev = $stddev / array_sum($stddevarray); //formula source: http://de.wikipedia.org/wiki/Standardabweichung - } //end if -> show aggregated data + //prevent division by zero + if((array_sum($stddevarray)-1) != 0 && $stddev != 0) + { + $stddev = $stddev / (array_sum($stddevarray)-1); //formula source: http://de.wikipedia.org/wiki/Empirische_Varianz + } + else + { + $stddev = 0; + } - //don't show aggregated data - else - { + //5 = get root + $stddev = sqrt($stddev); + $stddev = round($stddev,2); + } switch($outputType) { case 'xls': - $label[$i]=FlattenText($label[$i]); - $tableXLS[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i])."%", ""); + + $tableXLS[] = array($statlang->gT("Arithmetic mean"),$am,'',''); + $tableXLS[] = array($statlang->gT("Standard deviation"),$stddev,'',''); ++$xlsRow; - $sheet->write($xlsRow,0,$label[$i]); - $sheet->write($xlsRow,1,$grawdata[$i]); - $sheet->write($xlsRow,2,sprintf("%01.2f", $gdata[$i])."%"); - //$sheet->write($xlsRow,3,$sumpercentage."%"); + $sheet->write($xlsRow,0,$statlang->gT("Arithmetic mean")); + $sheet->write($xlsRow,1,$am); + + ++$xlsRow; + $sheet->write($xlsRow,0,$statlang->gT("Standard deviation")); + $sheet->write($xlsRow,1,$stddev); break; case 'pdf': - $label[$i]=FlattenText($label[$i]); - $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $gdata[$i])."%", ""); + + $tablePDF[] = array($statlang->gT("Arithmetic mean"),$am,'',''); + $tablePDF[] = array($statlang->gT("Standard deviation"),$stddev,'',''); break; case 'html': - //output percentage - $statisticsoutput .= "\t\t\n\t\n"; + //calculate standard deviation + $statisticsoutput .= ""; //German: "Fallzahl" + $statisticsoutput .= ""; + $statisticsoutput .= ""; //German: "Fallzahl" + $statisticsoutput .= ""; + break; default: break; } - } + } - } //end else -> $gdata[$i] != "N/A" + if($outputType=='pdf') //XXX TODO PDF + { + //$tablePDF = array(); + $tablePDF = array_merge_recursive($tablePDF, $footPDF); + $pdf->headTable($headPDF,$tablePDF); + if(isset($headPDF2)) { + $tablePDF = array_merge_recursive($headPDF2, $tablePDF2); + $pdf->headTable($headPDF2, $tablePDF2); + unset($headPDF2, $tablePDF2); + } + //$pdf->tableintopdf($tablePDF); + + // if(isset($footPDF)) + // foreach($footPDF as $foot) + // { + // $footA = array($foot); + // $pdf->tablehead($footA); + // } + } - //increase counter - $i++; - $itemcounter++; + //-------------------------- PCHART OUTPUT ---------------------------- - } //end while - if(isset($fnamelast)) { - $statisticsoutput.= "\n"; - unset($fnamelast); - } - //only show additional values when this setting is enabled - if(isset($showaggregateddata) && $showaggregateddata == 1 ) - { - //it's only useful to calculate standard deviation and arithmetic means for question types - //5 = 5 Point Scale - //A = Array (5 Point Choice) - if($qtype == "5" || $qtype == "A") + //PCHART has to be enabled and we need some data + if ($usegraph==1 && array_sum($gdata)>0) { - $stddev = 0; - $am = 0; + $graph = ""; + $p1 = ""; + // $statisticsoutput .= "
";
+                        //                  $statisticsoutput .= "GDATA:\n";
+                        //                  print_r($gdata);
+                        //                  $statisticsoutput .= "GRAWDATA\n";
+                        //                  print_r($grawdata);
+                        //                  $statisticsoutput .= "LABEL\n";
+                        //                  print_r($label);
+                        //                  $statisticsoutput .= "JUSTCODE\n";
+                        //                  print_r($justcode);
+                        //                  $statisticsoutput .= "LBL\n";
+                        //                  print_r($lbl);
+                        //                  $statisticsoutput .= "
"; + //First, lets delete any earlier graphs from the tmp directory + //$gdata and $lbl are arrays built at the end of the last section + //that contain the values, and labels for the data we are about + //to send to pchart. - //calculate arithmetic mean - if(isset($sumitems) && $sumitems > 0) + $i = 0; + foreach ($gdata as $data) + { + if ($data != 0){$i++;} + } + $totallines=$i; + if ($totallines>15) + { + $gheight=320+(6.7*($totallines-15)); + $fontsize=7; + $legendtop=0.01; + $setcentrey=0.5/(($gheight/320)); + } + else { + $gheight=320; + $fontsize=8; + $legendtop=0.07; + $setcentrey=0.5; + } + // Create bar chart for Multiple choice + if ($qtype == "M" || $qtype == "P") + { + //new bar chart using data from array $grawdata which contains percentage - //calculate and round results - //there are always 5 items - for($x = 0; $x < 5; $x++) + $DataSet = new pData; + $counter=0; + $maxyvalue=0; + foreach ($grawdata as $datapoint) { - //create product of item * value - $am += (($x+1) * $stddevarray[$x]); + $DataSet->AddPoint(array($datapoint),"Serie$counter"); + $DataSet->AddSerie("Serie$counter"); + + $counter++; + if ($datapoint>$maxyvalue) $maxyvalue=$datapoint; } - //prevent division by zero - if(isset($stddevarray) && array_sum($stddevarray) > 0) + if ($maxyvalue<10) {++$maxyvalue;} + $counter=0; + foreach ($lbl as $label) { - $am = round($am / array_sum($stddevarray),2); + $DataSet->SetSerieName($label,"Serie$counter"); + $counter++; } - else + + if ($MyCache->IsInCache("graph".$surveyid,$DataSet->GetData())) { - $am = 0; + $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); } + else + { + $graph = new pChart(1,1); - //calculate standard deviation -> loop through all data - /* - * four steps to calculate the standard deviation - * 1 = calculate difference between item and arithmetic mean and multiply with the number of elements - * 2 = create sqaure value of difference - * 3 = sum up square values - * 4 = multiply result with 1 / (number of items) - * 5 = get root - */ - + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); + $legendsize=$graph->getLegendBoxSize($DataSet->GetDataDescription()); + if ($legendsize[1]<320) $gheight=420; else $gheight=$legendsize[1]+100; + $graph = new pChart(690+$legendsize[0],$gheight); + $graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal'); + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); + $graph->setGraphArea(50,30,500,$gheight-60); + $graph->drawFilledRoundedRectangle(7,7,523+$legendsize[0],$gheight-7,5,254,255,254); + $graph->drawRoundedRectangle(5,5,525+$legendsize[0],$gheight-5,5,230,230,230); + $graph->drawGraphArea(255,255,255,TRUE); + $graph->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_START0,150,150,150,TRUE,90,0,TRUE,5,false); + $graph->drawGrid(4,TRUE,230,230,230,50); + // Draw the 0 line + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); + $graph->drawTreshold(0,143,55,72,TRUE,TRUE); - for($j = 0; $j < 5; $j++) - { - //1 = calculate difference between item and arithmetic mean - $diff = (($j+1) - $am); + // Draw the bar graph + $graph->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),FALSE); + //$Test->setLabel($DataSet->GetData(),$DataSet->GetDataDescription(),"Serie4","1","Important point!"); + // Finish the graph + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); + $graph->drawLegend(510,30,$DataSet->GetDataDescription(),255,255,255); - //2 = create square value of difference - $squarevalue = square($diff); + $MyCache->WriteToCache("graph".$surveyid,$DataSet->GetData(),$graph); + $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); + unset($graph); + } + } //end if (bar chart) - //3 = sum up square values and multiply them with the occurence - //prevent divison by zero - if($squarevalue != 0 && $stddevarray[$j] != 0) + //Pie Chart + else + { + // this block is to remove the items with value == 0 + $i = 0; + while (isset ($gdata[$i])) + { + if ($gdata[$i] == 0) { - $stddev += $squarevalue * $stddevarray[$j]; + array_splice ($gdata, $i, 1); + array_splice ($lbl, $i, 1); } - + else + {$i++;} } - //4 = multiply result with 1 / (number of items (=5)) - //There are two different formulas to calculate standard derivation - //$stddev = $stddev / array_sum($stddevarray); //formula source: http://de.wikipedia.org/wiki/Standardabweichung - - //prevent division by zero - if((array_sum($stddevarray)-1) != 0 && $stddev != 0) + $lblout=array(); + if ($language=='ar') + { + $lblout=$lbl; //reset text order to original + include_once($rootdir.'/classes/core/Arabic.php'); + $Arabic = new Arabic('ArGlyphs'); + foreach($lblout as $kkey => $kval){ + if (preg_match("^[A-Za-z]^", $kval)) { //auto detect if english + //eng + //no reversing + } + else{ + $kval = $Arabic->utf8Glyphs($kval,50,false); + $lblout[$kkey] = $kval; + } + } + } + elseif (getLanguageRTL($language)) { - $stddev = $stddev / (array_sum($stddevarray)-1); //formula source: http://de.wikipedia.org/wiki/Empirische_Varianz + $lblout=$lblrtl; } else { - $stddev = 0; + $lblout=$lbl; } - //5 = get root - $stddev = sqrt($stddev); - $stddev = round($stddev,2); - } + + //create new 3D pie chart + if ($usegraph==1) + { + $DataSet = new pData; + $DataSet->AddPoint($gdata,"Serie1"); + $DataSet->AddPoint($lblout,"Serie2"); + $DataSet->AddAllSeries(); + $DataSet->SetAbsciseLabelSerie("Serie2"); + + if ($MyCache->IsInCache("graph".$surveyid,$DataSet->GetData())) + { + $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); + } + else + { + + $gheight=ceil($gheight); + $graph = new pChart(690,$gheight); + $graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal'); + $graph->drawFilledRoundedRectangle(7,7,687,$gheight-3,5,254,255,254); + $graph->drawRoundedRectangle(5,5,689,$gheight-1,5,230,230,230); + + // Draw the pie chart + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); + $graph->drawPieGraph($DataSet->GetData(),$DataSet->GetDataDescription(),225,round($gheight/2),170,PIE_PERCENTAGE,TRUE,50,20,5); + $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); + $graph->drawPieLegend(430,12,$DataSet->GetData(),$DataSet->GetDataDescription(),250,250,250); + $MyCache->WriteToCache("graph".$surveyid,$DataSet->GetData(),$graph); + $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); + unset($graph); + } + //print_r($DataSet->GetData()); echo "

"; + } + + } //end else -> pie charts + + //introduce new counter + if (!isset($ci)) {$ci=0;} + + //increase counter, start value -> 1 + $ci++; switch($outputType) { case 'xls': - $tableXLS[] = array($statlang->gT("Arithmetic mean"),$am,'',''); - $tableXLS[] = array($statlang->gT("Standard deviation"),$stddev,'',''); - - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Arithmetic mean")); - $sheet->write($xlsRow,1,$am); - - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Standard deviation")); - $sheet->write($xlsRow,1,$stddev); + /** + * No Image for Excel... + */ break; case 'pdf': - $tablePDF[] = array($statlang->gT("Arithmetic mean"),$am,'',''); - $tablePDF[] = array($statlang->gT("Standard deviation"),$stddev,'',''); + $pdf->AddPage('P','A4'); + + $pdf->titleintopdf($pdfTitle,$titleDesc); + $pdf->Image($tempdir."/".$cachefilename, 0, 70, 180, 0, '', $homeurl."/admin.php?sid=$surveyid", 'B', true, 150,'C',false,false,0,true); break; case 'html': - //calculate standard deviation - $statisticsoutput .= ""; //German: "Fallzahl" - $statisticsoutput .= ""; - $statisticsoutput .= ""; //German: "Fallzahl" - $statisticsoutput .= ""; + $statisticsoutput .= ""; break; default: @@ -3064,331 +3292,87 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, break; } - } - } - if($outputType=='pdf') //XXX TODO PDF - { - //$tablePDF = array(); - $tablePDF = array_merge_recursive($tablePDF, $footPDF); - $pdf->headTable($headPDF,$tablePDF); - if(isset($headPDF2)) { - $tablePDF = array_merge_recursive($headPDF2, $tablePDF2); - $pdf->headTable($headPDF2, $tablePDF2); - unset($headPDF2, $tablePDF2); - } - //$pdf->tableintopdf($tablePDF); - - // if(isset($footPDF)) - // foreach($footPDF as $foot) - // { - // $footA = array($foot); - // $pdf->tablehead($footA); - // } - } - - - - - //-------------------------- PCHART OUTPUT ---------------------------- - - //PCHART has to be enabled and we need some data - if ($usegraph==1 && array_sum($gdata)>0) - { - $graph = ""; - $p1 = ""; - // $statisticsoutput .= "
";
-                    //                  $statisticsoutput .= "GDATA:\n";
-                    //                  print_r($gdata);
-                    //                  $statisticsoutput .= "GRAWDATA\n";
-                    //                  print_r($grawdata);
-                    //                  $statisticsoutput .= "LABEL\n";
-                    //                  print_r($label);
-                    //                  $statisticsoutput .= "JUSTCODE\n";
-                    //                  print_r($justcode);
-                    //                  $statisticsoutput .= "LBL\n";
-                    //                  print_r($lbl);
-                    //                  $statisticsoutput .= "
"; - //First, lets delete any earlier graphs from the tmp directory - //$gdata and $lbl are arrays built at the end of the last section - //that contain the values, and labels for the data we are about - //to send to pchart. - - $i = 0; - foreach ($gdata as $data) - { - if ($data != 0){$i++;} - } - $totallines=$i; - if ($totallines>15) - { - $gheight=320+(6.7*($totallines-15)); - $fontsize=7; - $legendtop=0.01; - $setcentrey=0.5/(($gheight/320)); - } - else - { - $gheight=320; - $fontsize=8; - $legendtop=0.07; - $setcentrey=0.5; } - // Create bar chart for Multiple choice - if ($qtype == "M" || $qtype == "P") - { - //new bar chart using data from array $grawdata which contains percentage - - $DataSet = new pData; - $counter=0; - $maxyvalue=0; - foreach ($grawdata as $datapoint) - { - $DataSet->AddPoint(array($datapoint),"Serie$counter"); - $DataSet->AddSerie("Serie$counter"); - - $counter++; - if ($datapoint>$maxyvalue) $maxyvalue=$datapoint; - } - - if ($maxyvalue<10) {++$maxyvalue;} - $counter=0; - foreach ($lbl as $label) - { - $DataSet->SetSerieName($label,"Serie$counter"); - $counter++; - } - - if ($MyCache->IsInCache("graph".$surveyid,$DataSet->GetData())) - { - $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); - } - else - { - $graph = new pChart(1,1); - - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); - $legendsize=$graph->getLegendBoxSize($DataSet->GetDataDescription()); - - if ($legendsize[1]<320) $gheight=420; else $gheight=$legendsize[1]+100; - $graph = new pChart(690+$legendsize[0],$gheight); - $graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal'); - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); - $graph->setGraphArea(50,30,500,$gheight-60); - $graph->drawFilledRoundedRectangle(7,7,523+$legendsize[0],$gheight-7,5,254,255,254); - $graph->drawRoundedRectangle(5,5,525+$legendsize[0],$gheight-5,5,230,230,230); - $graph->drawGraphArea(255,255,255,TRUE); - $graph->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_START0,150,150,150,TRUE,90,0,TRUE,5,false); - $graph->drawGrid(4,TRUE,230,230,230,50); - // Draw the 0 line - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); - $graph->drawTreshold(0,143,55,72,TRUE,TRUE); - - // Draw the bar graph - $graph->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),FALSE); - //$Test->setLabel($DataSet->GetData(),$DataSet->GetDataDescription(),"Serie4","1","Important point!"); - // Finish the graph - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); - $graph->drawLegend(510,30,$DataSet->GetDataDescription(),255,255,255); - - $MyCache->WriteToCache("graph".$surveyid,$DataSet->GetData(),$graph); - $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); - unset($graph); - } - } //end if (bar chart) - - //Pie Chart - else - { - // this block is to remove the items with value == 0 - $i = 0; - while (isset ($gdata[$i])) - { - if ($gdata[$i] == 0) - { - array_splice ($gdata, $i, 1); - array_splice ($lbl, $i, 1); - } - else - {$i++;} - } - - $lblout=array(); - if ($language=='ar') - { - $lblout=$lbl; //reset text order to original - include_once($rootdir.'/classes/core/Arabic.php'); - $Arabic = new Arabic('ArGlyphs'); - foreach($lblout as $kkey => $kval){ - if (preg_match("^[A-Za-z]^", $kval)) { //auto detect if english - //eng - //no reversing - } - else{ - $kval = $Arabic->utf8Glyphs($kval,50,false); - $lblout[$kkey] = $kval; - } - } - } - elseif (getLanguageRTL($language)) - { - $lblout=$lblrtl; - } - else - { - $lblout=$lbl; - } - - - //create new 3D pie chart - if ($usegraph==1) - { - $DataSet = new pData; - $DataSet->AddPoint($gdata,"Serie1"); - $DataSet->AddPoint($lblout,"Serie2"); - $DataSet->AddAllSeries(); - $DataSet->SetAbsciseLabelSerie("Serie2"); - - if ($MyCache->IsInCache("graph".$surveyid,$DataSet->GetData())) - { - $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); - } - else - { - - $gheight=ceil($gheight); - $graph = new pChart(690,$gheight); - $graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal'); - $graph->drawFilledRoundedRectangle(7,7,687,$gheight-3,5,254,255,254); - $graph->drawRoundedRectangle(5,5,689,$gheight-1,5,230,230,230); - - // Draw the pie chart - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile, $chartfontsize); - $graph->drawPieGraph($DataSet->GetData(),$DataSet->GetDataDescription(),225,round($gheight/2),170,PIE_PERCENTAGE,TRUE,50,20,5); - $graph->setFontProperties($rootdir."/fonts/".$chartfontfile,$chartfontsize); - $graph->drawPieLegend(430,12,$DataSet->GetData(),$DataSet->GetDataDescription(),250,250,250); - $MyCache->WriteToCache("graph".$surveyid,$DataSet->GetData(),$graph); - $cachefilename=basename($MyCache->GetFileFromCache("graph".$surveyid,$DataSet->GetData())); - unset($graph); - } - //print_r($DataSet->GetData()); echo "

"; - } - - } //end else -> pie charts - - //introduce new counter - if (!isset($ci)) {$ci=0;} - - //increase counter, start value -> 1 - $ci++; - switch($outputType) - { - case 'xls': - - /** - * No Image for Excel... - */ + //close table/output + if($outputType=='html') + $statisticsoutput .= "
" - //headline - .sprintf($statlang->gT("Field summary for %s"),$qtitle)."" - ."
" + //headline + .sprintf($statlang->gT("Field summary for %s"),$qtitle)."" + ."
" - //question title - .$qquestion."
"; - break; - default: + //question title + .$qquestion."
"; + break; + default: - break; - } - echo ''; - //loop thorugh the array which contains all answer data - foreach ($alist as $al) - { - //picks out alist that come from the multiple list above - if (isset($al[2]) && $al[2]) + break; + } + echo ''; + //loop thorugh the array which contains all answer data + foreach ($alist as $al) { - //handling for "other" option - - if ($al[0] == $statlang->gT("Other")) + //picks out alist that come from the multiple list above + if (isset($al[2]) && $al[2]) { - if($qtype=='!' || $qtype=='L') + //handling for "other" option + + if ($al[0] == $statlang->gT("Other")) { - // It is better for single choice question types to filter on the number of '-oth-' entries, than to - // just count the number of 'other' values - that way with failing Javascript the statistics don't get messed up - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id(substr($al[2],0,strlen($al[2])-5))."='-oth-'"; + if($qtype=='!' || $qtype=='L') + { + // It is better for single choice question types to filter on the number of '-oth-' entries, than to + // just count the number of 'other' values - that way with failing Javascript the statistics don't get messed up + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id(substr($al[2],0,strlen($al[2])-5))."='-oth-'"; + } + else + { + //get data + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE "; + $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; + } } - else - { - //get data - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE "; - $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; - } - } - /* - * text questions: - * - * U = huge free text - * T = long free text - * S = short free text - * Q = multiple short text - */ - - elseif ($qtype == "U" || $qtype == "T" || $qtype == "S" || $qtype == "Q" || $qtype == ";") - { - //free text answers - if($al[0]=="Answers") + /* + * text questions: + * + * U = huge free text + * T = long free text + * S = short free text + * Q = multiple short text + */ + + elseif ($qtype == "U" || $qtype == "T" || $qtype == "S" || $qtype == "Q" || $qtype == ";") { - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE "; - $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; + //free text answers + if($al[0]=="Answers") + { + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE "; + $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; + } + //"no answer" handling + elseif($al[0]=="NoAnswer") + { + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( "; + $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." = '')" : " (".db_quote_id($al[2])." LIKE ''))"; + } } - //"no answer" handling - elseif($al[0]=="NoAnswer") + elseif ($qtype == "O") { $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( "; - $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." = '')" : " (".db_quote_id($al[2])." LIKE ''))"; - } - } - elseif ($qtype == "O") - { - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( "; - $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." <> '')" : " (".db_quote_id($al[2])." NOT LIKE ''))"; - // all other question types - } - else - { - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($al[2])." ="; - - //ranking question? - if (substr($rt, 0, 1) == "R") - { - $query .= " '$al[0]'"; + $query .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." <> '')" : " (".db_quote_id($al[2])." NOT LIKE ''))"; + // all other question types } else { - $query .= " 'Y'"; + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($al[2])." ="; + + //ranking question? + if (substr($rt, 0, 1) == "R") + { + $query .= " '$al[0]'"; + } + else + { + $query .= " 'Y'"; + } } - } - } //end if -> alist set + } //end if -> alist set - else - { - if ($al[0] != "") + else { - //get more data - - if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') + if ($al[0] != "") { - // mssql cannot compare text blobs so we have to cast here - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE cast(".db_quote_id($rt)." as varchar)= '$al[0]'"; + //get more data + + if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') + { + // mssql cannot compare text blobs so we have to cast here + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE cast(".db_quote_id($rt)." as varchar)= '$al[0]'"; + } + else + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($rt)." = '$al[0]'"; } else - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ".db_quote_id($rt)." = '$al[0]'"; - } - else - { // This is for the 'NoAnswer' case - // We need to take into account several possibilities - // * NoAnswer cause the participant clicked the NoAnswer radio - // ==> in this case value is '' or ' ' - // * NoAnswer in text field - // ==> value is '' - // * NoAnswer due to conditions, or a page not displayed - // ==> value is NULL - if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') - { - // mssql cannot compare text blobs so we have to cast here - //$query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE (".db_quote_id($rt)." IS NULL " - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( " - // . "OR cast(".db_quote_id($rt)." as varchar) = '' " - . "cast(".db_quote_id($rt)." as varchar) = '' " - . "OR cast(".db_quote_id($rt)." as varchar) = ' ' )"; + { // This is for the 'NoAnswer' case + // We need to take into account several possibilities + // * NoAnswer cause the participant clicked the NoAnswer radio + // ==> in this case value is '' or ' ' + // * NoAnswer in text field + // ==> value is '' + // * NoAnswer due to conditions, or a page not displayed + // ==> value is NULL + if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType == 'mssqlnative') + { + // mssql cannot compare text blobs so we have to cast here + //$query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE (".db_quote_id($rt)." IS NULL " + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( " + // . "OR cast(".db_quote_id($rt)." as varchar) = '' " + . "cast(".db_quote_id($rt)." as varchar) = '' " + . "OR cast(".db_quote_id($rt)." as varchar) = ' ' )"; + } + else + // $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE (".db_quote_id($rt)." IS NULL " + $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( " + // . "OR ".db_quote_id($rt)." = '' " + . " ".db_quote_id($rt)." = '' " + . "OR ".db_quote_id($rt)." = ' ') "; } - else - // $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE (".db_quote_id($rt)." IS NULL " - $query = "SELECT count(*) FROM ".db_table_name("survey_$surveyid")." WHERE ( " - // . "OR ".db_quote_id($rt)." = '' " - . " ".db_quote_id($rt)." = '' " - . "OR ".db_quote_id($rt)." = ' ') "; + } - } + //check filter option + if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} + elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} - //check filter option - if (incompleteAnsFilterstate() == "inc") {$query .= " AND submitdate is null";} - elseif (incompleteAnsFilterstate() == "filter") {$query .= " AND submitdate is not null";} + //check for any "sql" that has been passed from another script + if ($sql != "NULL") {$query .= " AND $sql";} - //check for any "sql" that has been passed from another script - if ($sql != "NULL") {$query .= " AND $sql";} + //get data + $result=db_execute_num($query) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); - //get data - $result=db_execute_num($query) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); + // $statisticsoutput .= "\n\n\n"; - // $statisticsoutput .= "\n\n\n"; + // this just extracts the data, after we present + while ($row=$result->FetchRow()) + { + //increase counter + $TotalCompleted += $row[0]; - // this just extracts the data, after we present - while ($row=$result->FetchRow()) - { - //increase counter - $TotalCompleted += $row[0]; + //"no answer" handling + if ($al[0] === "") + {$fname=$statlang->gT("No answer");} + + //"other" handling + //"Answers" means that we show an option to list answer to "other" text field + elseif ($al[0] === $statlang->gT("Other") || $al[0] === "Answers" || ($qtype === "O" && $al[0] === $statlang->gT("Comments")) || $qtype === "P") + { + if ($qtype == "P" ) $ColumnName_RM = $al[2]."comment"; + else $ColumnName_RM = $al[2]; + if ($qtype=='O') { + $TotalCompleted -=$row[0]; + } + $fname="$al[1]"; + if (!isset($_POST['showtextinline']) && $browse===true) $fname .= " "; + if(isset($_POST['showtextinline']) && ($qtype != "S" && $qtype != "U" && $qtype != "T" && $qtype != "Q")) { + //Generate list of 'other' text entries for display + $headPDF2=array(); + $headPDF2[]=array($statlang->gt("'Other' Responses")); + $tablePDF2=array(); + $query2 = "SELECT ".db_quote_id($al[2])." FROM ".db_table_name("survey_$surveyid")." WHERE "; + $query2 .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; + $result2=db_execute_num($query2) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); + $fnamelast = "
\n"; + $fnamelast .= "".$clang->gT("'Other' Responses")."
\n"; + //$fname .= $query2; + while ($row2=$result2->FetchRow()) + { + $fnamelast .= $row2[0]."
\n"; + $tablePDF2[]=array($row2[0]); + } + $fnamelast .= "
\n"; + } + } - //"no answer" handling - if ($al[0] === "") - {$fname=$statlang->gT("No answer");} + /* + * text questions: + * + * U = huge free text + * T = long free text + * S = short free text + * Q = multiple short text + */ + elseif ($qtype == "S" || $qtype == "U" || $qtype == "T" || $qtype == "Q") + { + $headPDF = array(); + $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); - //"other" handling - //"Answers" means that we show an option to list answer to "other" text field - elseif ($al[0] === $statlang->gT("Other") || $al[0] === "Answers" || ($qtype === "O" && $al[0] === $statlang->gT("Comments")) || $qtype === "P") - { - if ($qtype == "P" ) $ColumnName_RM = $al[2]."comment"; - else $ColumnName_RM = $al[2]; - if ($qtype=='O') { - $TotalCompleted -=$row[0]; - } - $fname="$al[1]"; - if (!isset($_POST['showtextinline']) && $browse===true) $fname .= " "; - if(isset($_POST['showtextinline']) && ($qtype != "S" && $qtype != "U" && $qtype != "T" && $qtype != "Q")) { - //Generate list of 'other' text entries for display - $headPDF2=array(); - $headPDF2[]=array($statlang->gt("'Other' Responses")); - $tablePDF2=array(); - $query2 = "SELECT ".db_quote_id($al[2])." FROM ".db_table_name("survey_$surveyid")." WHERE "; - $query2 .= ($connect->databaseType == "mysql")? db_quote_id($al[2])." != ''" : "NOT (".db_quote_id($al[2])." LIKE '')"; - $result2=db_execute_num($query2) or safe_die ("Couldn't do count of values
$query
".$connect->ErrorMsg()); - $fnamelast = "
\n"; - $fnamelast .= "".$clang->gT("'Other' Responses")."
\n"; - //$fname .= $query2; - while ($row2=$result2->FetchRow()) - { - $fnamelast .= $row2[0]."
\n"; - $tablePDF2[]=array($row2[0]); - } - $fnamelast .= "
\n"; - } - } + //show free text answers + if ($al[0] == "Answers") + { + $fname= "$al[1]"; + if (!isset($_POST['showtextinline']) && $browse===true) $fname .= " "; + } + elseif ($al[0] == "NoAnswer") + { + $fname= "$al[1]"; + } - /* - * text questions: - * - * U = huge free text - * T = long free text - * S = short free text - * Q = multiple short text - */ - elseif ($qtype == "S" || $qtype == "U" || $qtype == "T" || $qtype == "Q") - { - $headPDF = array(); - $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); - - //show free text answers - if ($al[0] == "Answers") - { - $fname= "$al[1]"; - if (!isset($_POST['showtextinline']) && $browse===true) $fname .= " "; - } - elseif ($al[0] == "NoAnswer") - { - $fname= "$al[1]"; - } - - $statisticsoutput .= "
" - ."".$statlang->gT("Count")."" - ."".$statlang->gT("Percentage")."
" + ."".$statlang->gT("Count")."" + ."".$statlang->gT("Percentage")."
" - ."".$statlang->gT("Count")."" - ."".$statlang->gT("Percentage")."" - ."".$statlang->gT("Sum")."
" + ."".$statlang->gT("Count")."" + ."".$statlang->gT("Percentage")."" + ."".$statlang->gT("Sum")."
" + ."".$statlang->gT("Count")."" + ."".$statlang->gT("Percentage")."
" ."".$statlang->gT("Count")."" @@ -2225,596 +2309,606 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, } $showheadline = false; - } + } + //answer text + $fname="$al[1] ($al[0])"; } - //text for answer column is always needed - $fname="$al[1] ($al[0])"; + //are there some results to play with? + if ($results > 0) + { + //calculate percentage + $gdata[] = ($row[0]/$results)*100; + } + //no results + else + { + //no data! + $gdata[] = "N/A"; + } - //these question types get special treatment by $showaggregateddata - if($qtype == "5" || $qtype == "A") + //only add this if we don't handle question type "5"/"A" + if(!isset($justadded)) { - //put non-edited data in here because $row will be edited later + //put absolute data into array $grawdata[]=$row[0]; - $showaggregated_indice=count($grawdata) - 1; - $showaggregated_indice_table[$showaggregated_indice]="aggregated"; - $showaggregated_indice=-1; - - //keep in mind that we already added data (will be checked later) - $justadded = true; - - //we need a counter because we want to sum up certain values - //reset counter if 5 items have passed - if(!isset($testcounter) || $testcounter >= 4) - { - $testcounter = 0; - } - else - { - $testcounter++; - } - - //beside the known percentage value a new aggregated value should be shown - //therefore this item is marked in a certain way + } + else + { + //unset to handle "no answer" data correctly + unset($justadded); + } - if($testcounter == 0 ) //add 300 to original value - { - //HACK: add three times the total number of results to the value - //This way we get a 300 + X percentage which can be checked later - $row[0] += (3*$results); - } + //put question title and code into array + $label[]=$fname; - //the third value should be shown twice later -> mark it - if($testcounter == 2) //add 400 to original value - { - //HACK: add four times the total number of results to the value - //This way there should be a 400 + X percentage which can be checked later - $row[0] += (4*$results); - } + //put only the code into the array + $justcode[]=$al[0]; - //the last value aggregates the data of item 4 + item 5 later - if($testcounter == 4 ) //add 200 to original value - { - //HACK: add two times the total number of results to the value - //This way there should be a 200 + X percentage which can be checked later - $row[0] += (2*$results); - } + //edit labels and put them into antoher array + $lbl[] = wordwrap(FlattenText("$al[1] ($row[0])"), 25, "\n"); // NMO 2009-03-24 + $lblrtl[] = utf8_strrev(wordwrap(FlattenText("$al[1] )$row[0]("), 25, "\n")); // NMO 2009-03-24 - } //end if -> question type = "5"/"A" + } //end while -> loop through results - } //end if -> show aggregated data + } //end foreach -> loop through answer data - //handling what's left - else + //no filtering of incomplete answers and NO multiple option questions + //if ((incompleteAnsFilterstate() != "filter") and ($qtype != "M") and ($qtype != "P")) + //error_log("TIBO ".print_r($showaggregated_indice_table,true)); + if (($qtype != "M") and ($qtype != "P")) + { + //is the checkbox "Don't consider NON completed responses (only works when Filter incomplete answers is Disable)" checked? + //if (isset($_POST["noncompleted"]) and ($_POST["noncompleted"] == "on") && (isset($showaggregateddata) && $showaggregateddata == 0)) + // TIBO: TODO WE MUST SKIP THE FOLLOWING SECTION FOR TYPE A and 5 when + // showaggreagated data is set and set to 1 + if (isset($_POST["noncompleted"]) and ($_POST["noncompleted"] == "on") ) { - if(!isset($showheadline) || $showheadline != false) + //counter + $i=0; + + while (isset($gdata[$i])) { - switch($outputType) + if (isset($showaggregated_indice_table[$i]) && $showaggregated_indice_table[$i]=="aggregated") + { // do nothing, we don't rewrite aggregated results + // or at least I don't know how !!! (lemeur) + } + else { - case 'xls': - - $headXLS = array(); - $headXLS[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); - - ++$xlsRow; - $sheet->write($xlsRow,0,$statlang->gT("Answer")); - $sheet->write($xlsRow,1,$statlang->gT("Count")); - $sheet->write($xlsRow,2,$statlang->gT("Percentage")); - - break; - case 'pdf': - - $headPDF = array(); - $headPDF[] = array($statlang->gT("Answer"),$statlang->gT("Count"),$statlang->gT("Percentage")); - - break; - case 'html': - //three columns - $statisticsoutput .= "".$statlang->gT("Answer")."" - ."".$statlang->gT("Count")."" - ."".$statlang->gT("Percentage")."
" . $label[$i] ."\n" + ."\t\t" . $grawdata[$i] . "\n"; - //loop through all available answers - while (isset($gdata[$i])) - { - //repeat header (answer, count, ...) for each new question - unset($showheadline); + //percentage = 0 + $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; + $gdata[$i] = 0; + //check if we have to adjust ouput due to $showaggregateddata setting + if(isset($showaggregateddata) && $showaggregateddata == 1 && ($qtype == "5" || $qtype == "A")) + { + $statisticsoutput .= "\t\t
" . $label[$i] ."\n" - ."\t\t" . $grawdata[$i] . "\n"; + ++$xlsRow; + $sheet->write($xlsRow,0,$label[$i]); + $sheet->write($xlsRow,1,$grawdata[$i]); + $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); - //percentage = 0 - $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; - $gdata[$i] = 0; + break; + case 'pdf': + $label[$i]=FlattenText($label[$i]); + $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%", ""); - //check if we have to adjust ouput due to $showaggregateddata setting - if(isset($showaggregateddata) && $showaggregateddata == 1 && ($qtype == "5" || $qtype == "A")) - { - $statisticsoutput .= "\t\t
"; + //output percentage + $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; - break; - } + //adjust output + $statisticsoutput .= "\t\t"; + $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; + $statisticsoutput .= sprintf("%01.2f", $percentage)."%"; + $statisticsoutput .= ""; + ++$xlsRow; + $sheet->write($xlsRow,0,$label[$i]); + $sheet->write($xlsRow,1,$grawdata[$i]); + $sheet->write($xlsRow,2,sprintf("%01.2f", $percentage)."%"); + $sheet->write($xlsRow,3,sprintf("%01.2f", $aggregatedgdata)."%"); - //output percentage - $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; + break; + case 'pdf': + $label[$i]=FlattenText($label[$i]); + $tablePDF[] = array($label[$i],$grawdata[$i],sprintf("%01.2f", $percentage)."%",sprintf("%01.2f", $aggregatedgdata)."%"); - //adjust output - $statisticsoutput .= "\t\t"; + $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; + $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; + $statisticsoutput .= ""; - $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; - $statisticsoutput .= sprintf("%01.2f", $percentage)."%"; - $statisticsoutput .= ""; + $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; + $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; + $statisticsoutput .= ""; - $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; - $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; - $statisticsoutput .= "
".$statlang->gT("Sum")." (".$statlang->gT("Answers").")".$sumitems."$sumpercentage%$sumpercentage%
".$statlang->gT("Number of cases")."".$TotalCompleted."$casepercentage% 
"; - $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; - $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; - $statisticsoutput .= "
".$fnamelast."
".$statlang->gT("Sum")." (".$statlang->gT("Answers").")".$sumitems."$sumpercentage%$sumpercentage%
".$statlang->gT("Number of cases")."".$TotalCompleted."$casepercentage% 
"; - $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; - $statisticsoutput .= "\t\t"; - //end output per line. there has to be a whitespace within the table cell to display correctly - $statisticsoutput .= "\t\t 
".$statlang->gT("Arithmetic mean")."  $am 
".$statlang->gT("Standard deviation")." $stddev 
".$fnamelast."
".$statlang->gT("Arithmetic mean")."  $am 
".$statlang->gT("Standard deviation")." $stddev 

\n"; - break; - case 'pdf': + } //end if -> collect and display results - $pdf->AddPage('P','A4'); + //delete data + unset($gdata); + unset($grawdata); + unset($label); + unset($lbl); + unset($lblrtl); + unset($lblout); + unset($justcode); + unset ($alist); - $pdf->titleintopdf($pdfTitle,$titleDesc); - $pdf->Image($tempdir."/".$cachefilename, 0, 70, 180, 0, '', $homeurl."/admin.php?sid=$surveyid", 'B', true, 150,'C',false,false,0,true); - - break; - case 'html': - $statisticsoutput .= "

\n"; - - } //end if -> collect and display results - - //delete data - unset($gdata); - unset($grawdata); - unset($label); - unset($lbl); - unset($lblrtl); - unset($lblout); - unset($justcode); - unset ($alist); - - } // end foreach -> loop through all questions - - //output - if($outputType=='html') - $statisticsoutput .= "
 \n"; - - } //end if -> show summary results - - switch($outputType) - { - case 'xls': - - //$workbook-> - $workbook->close(); - if($pdfOutput=='F') - { - return $sFileName; - } - else - { - return; - } - break; + case 'pdf': + $pdf->lastPage(); + if($pdfOutput=='F') + { // This is only used by lsrc to send an E-Mail attachment, so it gives back the filename to send and delete afterwards + $pdf->Output($tempdir."/".$statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf', $pdfOutput); + return $tempdir."/".$statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf'; + } + else + return $pdf->Output($statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf', $pdfOutput); - case 'pdf': - $pdf->lastPage(); - if($pdfOutput=='F') - { // This is only used by lsrc to send an E-Mail attachment, so it gives back the filename to send and delete afterwards - $pdf->Output($tempdir."/".$statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf', $pdfOutput); - return $tempdir."/".$statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf'; - } - else - return $pdf->Output($statlang->gT('Survey').'_'.$surveyid."_".$surveyInfo['surveyls_title'].'.pdf', $pdfOutput); + break; + case 'html': + return $statisticsoutput; - break; - case 'html': - return $statisticsoutput; + break; + default: + return $statisticsoutput; - break; - default: - return $statisticsoutput; + break; + } - break; } -} + ////XXXXXX***// -////XXXXXX***// - -//simple function to square a value -function square($number) -{ - if($number == 0) - { - $squarenumber = 0; - } - else + //simple function to square a value + function square($number) { - $squarenumber = $number * $number; - } + if($number == 0) + { + $squarenumber = 0; + } + else + { + $squarenumber = $number * $number; + } - return $squarenumber; -} + return $squarenumber; + } ?> diff --git a/common_functions.php b/common_functions.php index e08c80d7a03..1b460cca6cd 100644 --- a/common_functions.php +++ b/common_functions.php @@ -1,7127 +1,7126 @@ -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'=>0, - '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'=>0, - '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'=>0, - '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'=>0, - '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'=>0, - 'assessable'=>0, - 'answerscales'=>0), - "T"=>array('description'=>$clang->gT("Long Free Text"), - 'group'=>$group['TextQuestions'], - 'subquestions'=>0, - 'hasdefaultvalues'=>0, - 'assessable'=>0, - 'answerscales'=>0), - "U"=>array('description'=>$clang->gT("Huge Free Text"), - 'group'=>$group['TextQuestions'], - 'subquestions'=>0, - 'hasdefaultvalues'=>0, - '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 .= ''; - foreach($members as $TypeCode=>$TypeProperties){ - $qtypeselecter .= " formatted list of existing surveys -* -*/ -function getsurveylist($returnarray=false,$returnwithouturl=false) -{ - global $surveyid, $dbprefix, $scriptname, $connect, $clang, $timeadjust; - static $cached = null; - - if(is_null($cached)) { - $surveyidquery = " SELECT a.*, surveyls_title, surveyls_description, surveyls_welcometext, surveyls_url " - ." FROM ".db_table_name('surveys')." AS a " - . "INNER JOIN ".db_table_name('surveys_languagesettings')." on (surveyls_survey_id=a.sid and surveyls_language=a.language) "; - - if (!bHasGlobalPermission('USER_RIGHT_SUPERADMIN')) - { - $surveyidquery .= "WHERE a.sid in (select sid from ".db_table_name('survey_permissions')." where uid={$_SESSION['loginID']} and permission='survey' and read_p=1) "; - } - - $surveyidquery .= " order by active DESC, surveyls_title"; - $surveyidresult = db_execute_assoc($surveyidquery); //Checked - if (!$surveyidresult) {return "Database Error";} - $surveynames = $surveyidresult->GetRows(); - $cached=$surveynames; - } else { - $surveynames = $cached; - } - $surveyselecter = ""; - if ($returnarray===true) return $surveynames; - $activesurveys=''; - $inactivesurveys=''; - $expiredsurveys=''; - if ($surveynames) - { - foreach($surveynames as $sv) - { - - $surveylstitle=FlattenText($sv['surveyls_title']); - if (strlen($surveylstitle)>45) - { - $surveylstitle = htmlspecialchars(mb_strcut(html_entity_decode($surveylstitle,ENT_QUOTES,'UTF-8'), 0, 45, 'UTF-8'))."..."; - } - - if($sv['active']!='Y') - { - $inactivesurveys .= ""; - } - if ($expiredsurveys!='') - { - $surveyselecter .= "\n"; - $surveyselecter .= $expiredsurveys . ""; - } - if ($inactivesurveys!='') - { - $surveyselecter .= "\n"; - $surveyselecter .= $inactivesurveys . ""; - } - 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 - }; -}; - -if(!defined('COLSTYLE')) -{ - /** - * The following prepares and defines the 'COLSTYLE' constant which - * dictates how columns are to be marked up for list type questions. - * - * $column_style is initialised at the end of config-defaults.php or from within config.php - */ - if( !isset($column_style) || - $column_style != 'css' || - $column_style != 'ul' || - $column_style != 'table' || - $column_style != null ) - { - $column_style = 'ul'; - }; - define('COLSTYLE' ,strtolower($column_style), true); -}; - - -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 constant COLSTYLE which sets how columns should - * be rendered. - * - * COLSTYLE is defined 30 lines above. - * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 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. - */ - - - $colstyle = COLSTYLE; - - /* - if(defined('PRINT_TEMPLATE')) // This forces tables based columns for printablesurvey - { - $colstyle = 'table'; - }; - */ - if($columns < 2) - { - $colstyle = 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 && $colstyle != null) - { - if($colstyle == '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" - ,'whole-end' => "\n" - ,'col-devide' => '' - ,'col-devide-last' => '' - ,'item-start' => "\t
  • \n" - ,'item-start-other' => "\t
  • \n" - ,'item-end' => "\t
  • \n" - ,'maxrows' => ceil($answer_count/$columns) //Always rounds up to nearest whole number - ,'cols' => $columns - ); - - switch($colstyle) - { - case 'ul': if($columns > 1) - { - $wrapper['col-devide'] = "\n\n\n\n"; - $wrapper['col-devide-last'] = "\n\n\n\n"; - } - break; - - case 'table': $table_cols = ''; - for($cols = $columns ; $cols > 0 ; --$cols) - { - switch($cols) - { - case $columns: $table_cols .= "\t\n"; - break; - case 1: $table_cols .= "\t\n"; - break; - default: $table_cols .= "\t\n"; - }; - }; - - if($columns > 1) - { - $wrapper['col-devide'] = "\t\n\n\n\n\t
      \n"; - $wrapper['col-devide-last'] = "\t
    \n\n\n\n\t
      \n"; - }; - $wrapper['whole-start'] = "\n\n$table_cols\n\t\n\n\n\t
        \n"; - $wrapper['whole-end'] = "\t
      \n\n\n\t\n\n"; - $wrapper['item-start'] = "
    • \n"; - $wrapper['item-end'] = "
    • \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"; - } - if ($groupselecter) - { - if (!isset($gvexist)) {$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"; - } - if ($groupselecter) - { - if (!$gvexist) {$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"; - } - return $groupselecter; -} - -/** -* Gives back the name of a group for a certaing group id -* -* @param integer $gid Group ID -*/ -function getgroupname($gid) -{ - global $surveyid; - if (!$surveyid) {$surveyid=returnglobal('sid');} - $s_lang = GetBaseLanguageFromSurveyID($surveyid); - $gidquery = "SELECT group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' and gid=$gid"; - - $gidresult = db_execute_num($gidquery) or safe_die("Group name could not be fetched (getgroupname)."); //Checked - while ($gv = $gidresult->FetchRow()) - { - $groupname = htmlspecialchars($gv[0]); - } - return $groupname; -} - -/** -* put your comment there... -* -* @param mixed $gid -* @param mixed $language -*/ -function getgrouplistlang($gid, $language) -{ - global $surveyid, $scriptname, $connect, $clang; - - $groupselecter=""; - if (!$surveyid) {$surveyid=returnglobal('sid');} - $gidquery = "SELECT gid, group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='".$language."' 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 .= "gT("Please choose...")."\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") - { - 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."'"; - $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; - 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, $standardtemplaterootdir, $defaulttemplate; - if (is_dir("$usertemplaterootdir/{$templatename}/")) - { - return $templatename; - } - elseif (is_dir("$standardtemplaterootdir/{$templatename}/")) - { - return $templatename; - } - 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, $globalfieldmap, $clang, $aDuplicateQIDs; - $surveyid=sanitize_int($surveyid); - - //Get list of questions - if (is_null($sQuestionLanguage)) - { - if (isset($_SESSION['s_lang'])) { - $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($globalfieldmap[$surveyid][$style][$s_lang]) && $force_refresh==false) { - return $globalfieldmap[$surveyid][$style][$s_lang]; - } - if (isset($_SESSION['fieldmap-' . $surveyid . $s_lang]) && !$force_refresh) { - 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 - - while ($arow=$aresult->FetchRow()) //With each question, create the appropriate field(s) - { - ++$questionSeq; - - // 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']=$arow['group_order']; - 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']=$arow['group_order']; - $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']=$arow['group_order']; - } - 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']=$arow['group_order']; - $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']=$arow['group_order']; - } - - $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']=$arow['group_order']; - } - } - } - - 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']=$arow['group_order']; - } - } - } - 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(); - - for ($i = 1; $i <= $abrow['value']; $i++) - { - $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']=$arow['group_order']; - } - $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']=$arow['group_order']; - } - } - } - 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']=$arow['group_order']; - $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']=$arow['group_order']; - } - } - } - 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']=$arow['group_order']; - $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']=$arow['group_order']; - $fieldmap[$fieldname]['other']=$arow['other']; - } - } - } - } - $fieldmap[$fieldname]['relevance']=$arow['relevance']; - $fieldmap[$fieldname]['grelevance']=$arow['grelevance']; - $fieldmap[$fieldname]['questionSeq']=$questionSeq; - $fieldmap[$fieldname]['groupSeq']=$arow['group_order']; - $fieldmap[$fieldname]['preg']=$arow['preg']; - $fieldmap[$fieldname]['other']=$arow['other']; - $fieldmap[$fieldname]['help']=$arow['help']; - } - if (isset($fieldmap)) { - $globalfieldmap[$surveyid][$style][$clang->langcode] = $fieldmap; - $_SESSION['fieldmap-' . $surveyid . $clang->langcode]=$fieldmap; - 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, $globalfieldmap, $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; - $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='en'; - } - $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']; - } - - if (!isset($language) || ($language=='') || (isset($additional_languages) && strpos($additional_languages, $language) === false) - or (isset($default_language) && $default_language == $language) - ) { - // Language not supported, or default language for survey, fall back to survey's default language - $_SESSION['s_lang'] = $default_language; - //echo "Language not supported, resorting to ".$_SESSION['s_lang']."
      "; - } else { - $_SESSION['s_lang'] = $language; - //echo "Language will be set to ".$_SESSION['s_lang']."
      "; - } - $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"=>"!LOWZ", - '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 of a Multiple choice question 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 of a Multiple choice question to exclude the matching answer options in this question."), - "caption"=>$clang->gT('Array filter exclusion')); - - $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')); -// Question types 'W' (list-dropdown-flexible) and 'Z'(list-radio-flexible) are no longer supported, so neither is code_filter -// $qattributes["code_filter"]=array( -// "types"=>"WZ", -// 'category'=>$clang->gT('Logic'), -// 'sortorder'=>100, -// 'inputtype'=>'text', -// "help"=>$clang->gT('Filter the available answers by this value'), -// "caption"=>$clang->gT('Code filter')); - - $qattributes["display_columns"]=array( - "types"=>"GLMZ", - '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"=>";:STUNKQ", - '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"=>";:STUNKQ", - '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"=>";:KQ", - '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"=>";:KQ", - '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"=>"MP", - '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"=>"M", - '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"=>"!KLMNOPRSWZ", - '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'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', - '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["max_num_value_sgqa"]=array( -// "types"=>"K", -// 'category'=>$clang->gT('Logic'), -// 'sortorder'=>100, -// 'inputtype'=>'text', -// "help"=>$clang->gT('Enter the SGQA identifier to use the total of a previous question as the maximum for this question'), -// "caption"=>$clang->gT('Max value from SGQA')); - - $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["min_num_value_sgqa"]=array( -// "types"=>"K", -// 'category'=>$clang->gT('Logic'), -// 'sortorder'=>100, -// 'inputtype'=>'text', -// "help"=>$clang->gT('Enter the SGQA identifier to use the total of a previous question as the minimum for this question'), -// "caption"=>$clang->gT('Minimum value from SGQA')); - - $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_equals_sgqa"]=array( -// "types"=>"K", -// 'category'=>$clang->gT('Logic'), -// 'sortorder'=>100, -// 'inputtype'=>'text', -// "help"=>$clang->gT('SGQA identifier to use total of previous question as total for this question'), -// "caption"=>$clang->gT('Value equals SGQA')); - - $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"=>"PLW!Z", - '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"=>"LMPWZ!", - '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"=>"15ABCDEFGHKLMNOPQRSTUWXYZ!:;|*", - '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"=>"15ABCEFGHKLMNOPRWYZ!:*", - '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"=>"!ABCEFHKLMOPQRWZ1:;", - '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['relevance']=array( -// 'types'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', -// 'category'=>$clang->gT('Display'), -// 'sortorder'=>1, -// 'inputtype'=>'text', -// 'default'=>'1', -// 'help'=>$clang->gT('The Relevance Equation determines whether a question should be shown (if true) or hiddden and marked as Not Applicable (if false).' -// . ' The Relevance equation can be as complex as you like, using any combination of mathematical operators, nested parentheses,' -// . ' any variable or token that has already been set, and any of more than 50 functions. It is parsed by the ExpressionManager.'), -// 'caption'=>$clang->gT('Relevance Equation')); - - $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 - like 3)'), - ), - 'default'=>0, - "help"=>$clang->gT('Accelerator keys for list items'), - "caption"=>$clang->gT('Prefix for list items')); - - $qattributes["scale_export"]=array( - "types"=>"CEFGHLMOPWYZ1!:*", - '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"=>"integer", - '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"=>"integer", - '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"=>"15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|", - '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 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; -} - -if (!function_exists('get_magic_quotes_gpc')) { - /** - * Gets the current configuration setting of magic_quotes_gpc - * NOTE: Compat variant for PHP 6+ versions - * - * @link http://www.php.net/manual/en/function.get-magic-quotes-gpc.php - * @return int 0 if magic_quotes_gpc is off, 1 otherwise. - */ - function get_magic_quotes_gpc() { - return 0; - } -} - -// 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; - if (!get_magic_quotes_gpc()) { - return $connect->escape($str); - } - return $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;}; - if (!get_magic_quotes_gpc()) { - return $str; - } - return stripslashes($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); - - 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"; - } - - - if ( !$embedded ) - { - $header= "\n" - . "\n" - . "\n" - . "" - . "" - . $js_header; - - if ($meta) - $header .= $meta; - - return $header; - } - else - { - global $embedded_headerfunc; - if ( function_exists( $embedded_headerfunc ) ) - return $embedded_headerfunc(); - } -} - -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\n\n"; - } - else - { - global $embedded_footerfunc; - if ( function_exists( $embedded_footerfunc ) ) - return $embedded_footerfunc(); - } -} - - -function doFooter() -{ - echo getFooter(); -} - - - -// This function replaces field names in a text with the related values -// (e.g. for email and template functions) -function ReplaceFields ($text,$fieldsarray, $bReplaceInsertans=true) -{ - - if ($bReplaceInsertans) - { - $replacements = array(); - foreach ( $fieldsarray as $key => $value ) - { - $replacements[substr($key,1,-1)] = $value; - } - $text = LimeExpressionManager::ProcessString($text, NULL, $replacements, false, 2, 1); - } - else - { - foreach ( $fieldsarray as $key => $value ) - { - $text=str_replace($key, $value, $text); - } - } - return $text; -} - - -/** -* This function mails a text $body to the recipient $to. -* You can use more than one recipient when using a semikolon separated string with recipients. -* If you send several emails at once please supply an email object so that it can be re-used over and over. Especially with SMTP connections this speeds up things by 200%. -* If you supply an email object Do not forget to close the mail connection by calling $mail->SMTPClose(); -* -* @param mixed $mail This is an PHPMailer object. If null, one will be created automatically and unset afterwards. If supplied it won't be unset. -* @param string $body Body text of the email in plain text or HTML -* @param mixed $subject Email subject -* @param mixed $to Array with several email addresses or single string with one email address -* @param mixed $from -* @param mixed $sitename -* @param mixed $ishtml -* @param mixed $bouncemail -* @param mixed $attachment -* @return bool If successful returns true -*/ -function SendEmailMessage($mail, $body, $subject, $to, $from, $sitename, $ishtml=false, $bouncemail=null, $attachment=null, $customheaders="") -{ - - global $emailmethod, $emailsmtphost, $emailsmtpuser, $emailsmtppassword, $defaultlang, $emailsmtpdebug; - global $rootdir, $maildebug, $maildebugbody, $emailsmtpssl, $clang, $demoModeOnly, $emailcharset; - if (!is_array($to)){ - $to=array($to); - } - if (!is_array($customheaders) && $customheaders == '') - { - $customheaders=array(); - } - if ($demoModeOnly==true) - { - $maildebug=$clang->gT('Email was not sent because demo-mode is activated.'); - $maildebugbody=''; - return false; - } - - if (is_null($bouncemail) ) - { - $sender=$from; - } - else - { - $sender=$bouncemail; - } - $bUnsetEmail=false; - if (is_null($mail)) - { - $bUnsetEmail=true; - $mail = new PHPMailer; - } - else - { - $mail->SMTPKeepAlive=true; - } - - if (!$mail->SetLanguage($defaultlang,$rootdir.'/classes/phpmailer/language/')) - { - $mail->SetLanguage('en',$rootdir.'/classes/phpmailer/language/'); - } - $mail->CharSet = $emailcharset; - if (isset($emailsmtpssl) && trim($emailsmtpssl)!=='' && $emailsmtpssl!==0) { - if ($emailsmtpssl===1) {$mail->SMTPSecure = "ssl";} - else {$mail->SMTPSecure = $emailsmtpssl;} - } - - $fromname=''; - $fromemail=$from; - if (strpos($from,'<')) - { - $fromemail=substr($from,strpos($from,'<')+1,strpos($from,'>')-1-strpos($from,'<')); - $fromname=trim(substr($from,0, strpos($from,'<')-1)); - } - - $sendername=''; - $senderemail=$sender; - if (strpos($sender,'<')) - { - $senderemail=substr($sender,strpos($sender,'<')+1,strpos($sender,'>')-1-strpos($sender,'<')); - $sendername=trim(substr($sender,0, strpos($sender,'<')-1)); - } - - switch ($emailmethod) { - case "qmail": - $mail->IsQmail(); - break; - case "smtp": - $mail->IsSMTP(); - if ($emailsmtpdebug>0) - { - $mail->SMTPDebug = $emailsmtpdebug; - } - if (strpos($emailsmtphost,':')>0) - { - $mail->Host = substr($emailsmtphost,0,strpos($emailsmtphost,':')); - $mail->Port = substr($emailsmtphost,strpos($emailsmtphost,':')+1); - } - else { - $mail->Host = $emailsmtphost; - } - $mail->Username =$emailsmtpuser; - $mail->Password =$emailsmtppassword; - if (trim($emailsmtpuser)!="") - { - $mail->SMTPAuth = true; - } - break; - case "sendmail": - $mail->IsSendmail(); - break; - default: - //Set to the default value to rule out incorrect settings. - $emailmethod="mail"; - $mail->IsMail(); - } - - $mail->SetFrom($fromemail, $fromname); - $mail->Sender = $senderemail; // Sets Return-Path for error notifications - foreach ($to as $singletoemail) - { - if (strpos($singletoemail, '<') ) - { - $toemail=substr($singletoemail,strpos($singletoemail,'<')+1,strpos($singletoemail,'>')-1-strpos($singletoemail,'<')); - $toname=trim(substr($singletoemail,0, strpos($singletoemail,'<')-1)); - $mail->AddAddress($toemail,$toname); - } - else - { - $mail->AddAddress($singletoemail); - } - } - if (is_array($customheaders)) - { - foreach ($customheaders as $key=>$val) { - $mail->AddCustomHeader($val); - } - } - $mail->AddCustomHeader("X-Surveymailer: $sitename Emailer (LimeSurvey.sourceforge.net)"); - if (get_magic_quotes_gpc() != "0") {$body = stripcslashes($body);} - if ($ishtml) { - $mail->IsHTML(true); - $mail->Body = $body; - $mail->AltBody = trim(strip_tags(html_entity_decode($body,ENT_QUOTES,'UTF-8'))); - } else - { - $mail->IsHTML(false); - $mail->Body = $body; - } - - // add the attachment if there is one - if(!is_null($attachment)) - $mail->AddAttachment($attachment); - - if (trim($subject)!='') {$mail->Subject = "=?$emailcharset?B?" . base64_encode($subject) . "?=";} - if ($emailsmtpdebug>0) { - ob_start(); - } - $sent=$mail->Send(); - $maildebug=$mail->ErrorInfo; - if ($emailsmtpdebug>0) { - $maildebug .= '
    • '.$clang->gT('SMTP debug output:').'
    • '.strip_tags(ob_get_contents()).'
      '; - ob_end_clean(); - } - $maildebugbody=$mail->Body; - $mail->ClearAddresses(); - $mail->ClearCustomHeaders(); - if ($bUnsetEmail) - { - unset($mail); - } - return $sent; -} - - - -/** -* This functions removes all HTML tags, Javascript, CRs, linefeeds and other strange chars from a given text. CRs, linefeeds are not removed for .csv files -* -* @param string $sTextToFlatten Text you want to clean -* @param boolan $bDecodeHTMLEntities If set to true then all HTML entities will be decoded to the specified charset. Default: false -* @param string $sCharset Charset to decode to if $decodeHTMLEntities is set to true -* -* @return string Cleaned text -*/ -function FlattenText($sTextToFlatten, $bDecodeHTMLEntities=false, $sCharset='UTF-8', $bStripNewLines=true) -{ - $sNicetext = strip_javascript($sTextToFlatten); - $sNicetext = strip_tags($sNicetext); - - if ($bStripNewLines ){ - $sNicetext = preg_replace('~\Ru~', '', $sNicetext); - } - else // unify newlines - { - $sNicetext = preg_replace('~\Ru~', "\r\n", $sNicetext); - } - if ($bDecodeHTMLEntities==true) - { - $sNicetext = str_replace(' ',' ', $sNicetext); // html_entity_decode does not convert   to spaces - $sNicetext = html_entity_decode($sNicetext, ENT_QUOTES, $sCharset); - } - return trim($sNicetext); ; -} - -/** -* getGroupsByQuestion($surveyid) -* @global string $surveyid -* @return returns a keyed array of groups to questions ie: array([1]=>[2]) question qid 1, is in group gid 2. -*/ -function getGroupsByQuestion($surveyid) { - global $surveyid, $dbprefix; - - $output=array(); - - $surveyid=sanitize_int($surveyid); - $query="SELECT qid, gid FROM ".db_table_name('questions')." WHERE sid='$surveyid'"; - $result = db_execute_assoc($query); - while ($val = $result->FetchRow()) - { - $output[$val['qid']]=$val['gid']; - } - return $output; -} - -/** -* Run an arbitrary sequence of semicolon-delimited SQL commands -* -* Assumes that the input text (file or string) consists of -* a number of SQL statements ENDING WITH SEMICOLONS. The -* semicolons MUST be the last character in a line. -* Lines that are blank or that start with "#" or "--" (postgres) are ignored. -* Only tested with mysql dump files (mysqldump -p -d limesurvey) -* Function kindly borrowed by Moodle -* @uses $dbprefix -* @param string $sqlfile The path where a file with sql commands can be found on the server. -* @param string $sqlstring If no path is supplied then a string with semicolon delimited sql -* commands can be supplied in this argument. -* @return bool Returns true if database was modified successfully. -*/ -function modify_database($sqlfile='', $sqlstring='') -{ - global $dbprefix; - global $defaultuser; - global $defaultpass; - global $siteadminemail; - global $siteadminname; - global $defaultlang; - global $codeString; - global $rootdir, $homedir; - global $connect; - global $clang; - global $modifyoutput; - global $databasetabletype; - - require_once($homedir."/classes/core/sha256.php"); - - $success = true; // Let's be optimistic - $modifyoutput=''; - - if (!empty($sqlfile)) { - if (!is_readable($sqlfile)) { - $success = false; - echo '

      Tried to modify database, but "'. $sqlfile .'" doesn\'t exist!

      '; - return $success; - } else { - $lines = file($sqlfile); - } - } else { - $sqlstring = trim($sqlstring); - if ($sqlstring{strlen($sqlstring)-1} != ";") { - $sqlstring .= ";"; // add it in if it's not there. - } - $lines[] = $sqlstring; - } - - $command = ''; - - foreach ($lines as $line) { - $line = rtrim($line); - $length = strlen($line); - - if ($length and $line[0] <> '#' and substr($line,0,2) <> '--') { - if (substr($line, $length-1, 1) == ';') { - $line = substr($line, 0, $length-1); // strip ; - $command .= $line; - $command = str_replace('prefix_', $dbprefix, $command); // Table prefixes - $command = str_replace('$defaultuser', $defaultuser, $command); - $command = str_replace('$defaultpass', SHA256::hashing($defaultpass), $command); - $command = str_replace('$siteadminname', $siteadminname, $command); - $command = str_replace('$siteadminemail', $siteadminemail, $command); - $command = str_replace('$defaultlang', $defaultlang, $command); - $command = str_replace('$sessionname', 'ls'.sRandomChars(20,'123456789'), $command); - $command = str_replace('$databasetabletype', $databasetabletype, $command); - - if (! db_execute_num($command)) { //Checked - $command=htmlspecialchars($command); - $modifyoutput .="
      ".sprintf($clang->gT("SQL command failed: %s Reason: %s"),"".$command."","".$connect->ErrorMsg()."
      "); - $success = false; - } - else - { - $command=htmlspecialchars($command); - $modifyoutput .=". "; - } - - $command = ''; - } else { - $command .= $line; - } - } - } - - return $success; - -} - - - -// unsets all Session variables to kill session -function killSession() //added by Dennis -{ - // Delete the Session Cookie - $CookieInfo = session_get_cookie_params(); - if ( (empty($CookieInfo['domain'])) && (empty($CookieInfo['secure'])) ) { - setcookie(session_name(), '', time()-3600, $CookieInfo['path']); - } elseif (empty($CookieInfo['secure'])) { - setcookie(session_name(), '', time()-3600, $CookieInfo['path'], $CookieInfo['domain']); - } else { - setcookie(session_name(), '', time()-3600, $CookieInfo['path'], $CookieInfo['domain'], $CookieInfo['secure']); - } - unset($_COOKIE[session_name()]); - foreach ($_SESSION as $key =>$value) - { - //echo $key." = ".$value."
      "; - unset($_SESSION[$key]); - } - $_SESSION = array(); // redundant with previous lines - session_unset(); - @session_destroy(); -} - - - - - - - -// set the rights of a user and his children -function setuserrights($uid, $rights) -{ - global $connect; - $uid=sanitize_int($uid); - $updates = "create_survey=".$rights['create_survey'] - . ", create_user=".$rights['create_user'] - . ", delete_user=".$rights['delete_user'] - . ", superadmin=".$rights['superadmin'] - . ", configurator=".$rights['configurator'] - . ", manage_template=".$rights['manage_template'] - . ", manage_label=".$rights['manage_label']; - $uquery = "UPDATE ".db_table_name('users')." SET ".$updates." WHERE uid = ".$uid; - return $connect->Execute($uquery); //Checked -} - - -function createPassword() -{ - $pwchars = "abcdefhjmnpqrstuvwxyz23456789"; - $password_length = 8; - $passwd = ''; - - for ($i=0; $i<$password_length; $i++) - { - $passwd .= $pwchars[floor(rand(0,strlen($pwchars)-1))]; - } - return $passwd; -} - -function getgroupuserlist() -{ - global $ugid, $dbprefix, $scriptname, $connect, $clang; - - $ugid=sanitize_int($ugid); - $surveyidquery = "SELECT a.uid, a.users_name FROM ".db_table_name('users')." AS a LEFT JOIN (SELECT uid AS id FROM ".db_table_name('user_in_groups')." WHERE ugid = {$ugid}) AS b ON a.uid = b.id WHERE id IS NULL ORDER BY a.users_name"; - - $surveyidresult = db_execute_assoc($surveyidquery); //Checked - if (!$surveyidresult) {return "Database Error";} - $surveyselecter = ""; - $surveynames = $surveyidresult->GetRows(); - if ($surveynames) - { - foreach($surveynames as $sv) - { - $surveyselecter .= "gT("Please choose...")."\n".$surveyselecter; - return $surveyselecter; -} - -/** -* Retrieve a HTML \n".$surveyselecter;} - else {$surveyselecter = "\n".$surveyselecter;} - return $surveyselecter; -} - -function getsurveyusergrouplist($outputformat='htmloptions') -{ - global $surveyid, $dbprefix, $scriptname, $connect, $clang, $usercontrolSameGroupPolicy; - $surveyid=sanitize_int($surveyid); - - $surveyidquery = "SELECT a.ugid, a.name, MAX(d.ugid) AS da FROM ".db_table_name('user_groups')." AS a LEFT JOIN (SELECT b.ugid FROM ".db_table_name('user_in_groups')." AS b LEFT JOIN (SELECT * FROM ".db_table_name('survey_permissions')." WHERE sid = {$surveyid}) AS c ON b.uid = c.uid WHERE c.uid IS NULL) AS d ON a.ugid = d.ugid GROUP BY a.ugid, a.name HAVING MAX(d.ugid) IS NOT NULL"; - $surveyidresult = db_execute_assoc($surveyidquery); //Checked - if (!$surveyidresult) {return "Database Error";} - $surveyselecter = ""; - $surveynames = $surveyidresult->GetRows(); - - if (isset($usercontrolSameGroupPolicy) && - $usercontrolSameGroupPolicy == true) - { - $authorizedGroupsList=getusergrouplist('simplegidarray'); - } - - if ($surveynames) - { - foreach($surveynames as $sv) - { - if (!isset($usercontrolSameGroupPolicy) || - $usercontrolSameGroupPolicy == false || - in_array($sv['ugid'],$authorizedGroupsList)) - { - $surveyselecter .= "gT("Please choose...")."\n".$surveyselecter;} - else {$surveyselecter = "\n".$surveyselecter;} - - if ($outputformat == 'simpleugidarray') - { - return $simpleugidarray; - } - else - { - return $surveyselecter; - } -} - -function getusergrouplist($outputformat='optionlist') -{ - global $dbprefix, $scriptname, $connect, $clang; - - //$squery = "SELECT ugid, name FROM ".db_table_name('user_groups') ." WHERE owner_id = {$_SESSION['loginID']} ORDER BY name"; - $squery = "SELECT a.ugid, a.name, a.owner_id, b.uid FROM ".db_table_name('user_groups') ." AS a LEFT JOIN ".db_table_name('user_in_groups') ." AS b ON a.ugid = b.ugid WHERE uid = {$_SESSION['loginID']} ORDER BY name"; - - $sresult = db_execute_assoc($squery); //Checked - if (!$sresult) {return "Database Error";} - $selecter = ""; - $groupnames = $sresult->GetRows(); - $simplegidarray=array(); - if ($groupnames) - { - foreach($groupnames as $gn) - { - $selecter .= "\n".$selecter;} - //else {$selecter = "\n".$selecter;} - - if ($outputformat == 'simplegidarray') - { - return $simplegidarray; - } - else - { - return $selecter; - } -} - - -function languageDropdown($surveyid,$selected) -{ - global $homeurl; - $slangs = GetAdditionalLanguagesFromSurveyID($surveyid); - $baselang = GetBaseLanguageFromSurveyID($surveyid); - array_unshift($slangs,$baselang); - $html = ""; - return $html; -} - -function languageDropdownClean($surveyid,$selected) -{ - $slangs = GetAdditionalLanguagesFromSurveyID($surveyid); - $baselang = GetBaseLanguageFromSurveyID($surveyid); - array_unshift($slangs,$baselang); - $html = ""; - return $html; -} - -function BuildCSVFromQuery($Query) -{ - global $dbprefix, $connect; - $QueryResult = db_execute_assoc($Query) or safe_die ("ERROR: $QueryResult
      ".$connect->ErrorMsg()); //safe - preg_match('/FROM (\w+)( |,)/i', $Query, $MatchResults); - $TableName = $MatchResults[1];; - if ($dbprefix) - { - $TableName = substr($TableName, strlen($dbprefix), strlen($TableName)); - } - $Output = "\n#\n# " . strtoupper($TableName) . " TABLE\n#\n"; - $HeaderDone = false; $ColumnNames = ""; - while ($Row = $QueryResult->FetchRow()) - { - - if (!$HeaderDone) - { - foreach ($Row as $Key=>$Value) - { - $ColumnNames .= CSVEscape($Key).","; //Add all the column names together - } - $ColumnNames = substr($ColumnNames, 0, -1); //strip off last comma space - $Output .= "$ColumnNames\n"; - $HeaderDone=true; - } - $ColumnValues = ""; - foreach ($Row as $Key=>$Value) - { - $Value=str_replace("\r\n", "\n", $Value); - $Value=str_replace("\r", "\n", $Value); - $ColumnValues .= CSVEscape($Value) . ","; - } - $ColumnValues = substr($ColumnValues, 0, -1); //strip off last comma space - $Output .= str_replace("\n","\\n","$ColumnValues")."\n"; - } - return $Output; -} - -function CSVEscape($str) -{ - $str= str_replace('\n','\%n',$str); - return '"' . str_replace('"','""', $str) . '"'; -} - -function convertCSVRowToArray($string, $seperator, $quotechar) -{ - $fields=preg_split('/' . $seperator . '(?=([^"]*"[^"]*")*(?![^"]*"))/',trim($string)); - $fields=array_map('CSVUnquote',$fields); - return $fields; -} - - -/** -* This function removes surrounding and masking quotes from the CSV field -* -* @param mixed $field -* @return mixed -*/ -function CSVUnquote($field) -{ - //print $field.":"; - $field = preg_replace ("/^\040*\"/", "", $field); - $field = preg_replace ("/\"\040*$/", "", $field); - $field= str_replace('""','"',$field); - //print $field."\n"; - return $field; -} - -/** -* CleanLanguagesFromSurvey() removes any languages from survey tables that are not in the passed list -* @param string $sid - the currently selected survey -* @param string $availlangs - space seperated list of additional languages in survey -* @return bool - always returns true -*/ -function CleanLanguagesFromSurvey($sid, $availlangs) -{ - global $connect; - $sid=sanitize_int($sid); - $baselang = GetBaseLanguageFromSurveyID($sid); - - if (!empty($availlangs) && $availlangs != " ") - { - $availlangs=sanitize_languagecodeS($availlangs); - $langs = explode(" ",$availlangs); - if($langs[count($langs)-1] == "") array_pop($langs); - } - - $sqllang = "language <> '".$baselang."' ";; - - if (!empty($availlangs) && $availlangs != " ") - { - foreach ($langs as $lang) - { - $sqllang .= "and language <> '".$lang."' "; - } - } - - // Remove From Answers Table - $query = "SELECT qid FROM ".db_table_name('questions')." WHERE sid='{$sid}' and ($sqllang)"; - $qidresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - while ($qrow = $qidresult->FetchRow()) - { - $myqid = $qrow['qid']; - $query = "DELETE FROM ".db_table_name('answers')." WHERE qid='$myqid' and ($sqllang)"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - } - - // Remove From Questions Table - $query = "DELETE FROM ".db_table_name('questions')." WHERE sid='{$sid}' and ($sqllang)"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - - // Remove From Groups Table - $query = "DELETE FROM ".db_table_name('groups')." WHERE sid='{$sid}' and ($sqllang)"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - - return true; -} - -/** -* FixLanguageConsistency() fixes missing groups,questions,answers & assessments for languages on a survey -* @param string $sid - the currently selected survey -* @param string $availlangs - space seperated list of additional languages in survey - if empty all additional languages of a survey are checked against the base language -* @return bool - always returns true -*/ -function FixLanguageConsistency($sid, $availlangs='') -{ - global $connect, $databasetype; - - if (trim($availlangs)!='') - { - $availlangs=sanitize_languagecodeS($availlangs); - $langs = explode(" ",$availlangs); - if($langs[count($langs)-1] == "") array_pop($langs); - } else { - $langs=GetAdditionalLanguagesFromSurveyID($sid); - } - - $baselang = GetBaseLanguageFromSurveyID($sid); - $sid=sanitize_int($sid); - $query = "SELECT * FROM ".db_table_name('groups')." WHERE sid='{$sid}' AND language='{$baselang}' ORDER BY group_order"; - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($result->RecordCount() > 0) - { - while($group = $result->FetchRow()) - { - foreach ($langs as $lang) - { - $query = "SELECT gid FROM ".db_table_name('groups')." WHERE sid='{$sid}' AND gid='{$group['gid']}' AND language='{$lang}'"; - $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($gresult->RecordCount() < 1) - { - db_switchIDInsert('groups',true); - $query = "INSERT INTO ".db_table_name('groups')." (gid,sid,group_name,group_order,description,grelevance,language) VALUES('{$group['gid']}','{$group['sid']}',".db_quoteall($group['group_name']).",'{$group['group_order']}',".db_quoteall($group['description']).",'".db_quote($group['grelevance'])."','{$lang}')"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - db_switchIDInsert('groups',false); - } - } - reset($langs); - } - } - - $quests = array(); - $query = "SELECT * FROM ".db_table_name('questions')." WHERE sid='{$sid}' AND language='{$baselang}' ORDER BY question_order"; - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($result->RecordCount() > 0) - { - while($question = $result->FetchRow()) - { - array_push($quests,$question['qid']); - foreach ($langs as $lang) - { - $query = "SELECT qid FROM ".db_table_name('questions')." WHERE sid='{$sid}' AND qid='{$question['qid']}' AND language='{$lang}' AND scale_id={$question['scale_id']}"; - $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($gresult->RecordCount() < 1) - { - db_switchIDInsert('questions',true); - $query = "INSERT INTO ".db_table_name('questions')." (qid,sid,gid,type,title,question,preg,help,other,mandatory,question_order,language, scale_id,parent_qid, relevance) VALUES('{$question['qid']}','{$question['sid']}','{$question['gid']}','{$question['type']}',".db_quoteall($question['title']).",".db_quoteall($question['question']).",".db_quoteall($question['preg']).",".db_quoteall($question['help']).",'{$question['other']}','{$question['mandatory']}','{$question['question_order']}','{$lang}',{$question['scale_id']},{$question['parent_qid']}, '{$question['relevance']}')"; - $connect->Execute($query) or safe_die($query."
      ".$connect->ErrorMsg()); //Checked - db_switchIDInsert('questions',false); - } - } - reset($langs); - } - - $sqlans = ""; - foreach ($quests as $quest) - { - $sqlans .= " OR qid = '".$quest."' "; - } - - $query = "SELECT * FROM ".db_table_name('answers')." WHERE language='{$baselang}' and (".trim($sqlans,' OR').") ORDER BY qid, code"; - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($result->RecordCount() > 0) - { - while($answer = $result->FetchRow()) - { - foreach ($langs as $lang) - { - $query = "SELECT qid FROM ".db_table_name('answers')." WHERE code='{$answer['code']}' AND qid='{$answer['qid']}' AND language='{$lang}' AND scale_id={$answer['scale_id']}"; - $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($gresult->RecordCount() < 1) - { - db_switchIDInsert('answers',true); - $query = "INSERT INTO ".db_table_name('answers')." (qid,code,answer,scale_id,sortorder,language,assessment_value) VALUES('{$answer['qid']}',".db_quoteall($answer['code']).",".db_quoteall($answer['answer']).",{$answer['scale_id']},'{$answer['sortorder']}','{$lang}',{$answer['assessment_value']})"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - db_switchIDInsert('answers',false); - } - } - reset($langs); - } - } - } - - - $query = "SELECT * FROM ".db_table_name('assessments')." WHERE sid='{$sid}' AND language='{$baselang}'"; - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($result->RecordCount() > 0) - { - while($assessment = $result->FetchRow()) - { - foreach ($langs as $lang) - { - $query = "SELECT id FROM ".db_table_name('assessments')." WHERE sid='{$sid}' AND id='{$assessment['id']}' AND language='{$lang}'"; - $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - if ($gresult->RecordCount() < 1) - { - db_switchIDInsert('assessments',true); - $query = "INSERT INTO ".db_table_name('assessments')." (id,sid,scope,gid,name,minimum,maximum,message,language) " - ."VALUES('{$assessment['id']}','{$assessment['sid']}',".db_quoteall($assessment['scope']).",".db_quoteall($assessment['gid']).",".db_quoteall($assessment['name']).",".db_quoteall($assessment['minimum']).",".db_quoteall($assessment['maximum']).",".db_quoteall($assessment['message']).",'{$lang}')"; - $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked - db_switchIDInsert('assessments',false); - } - } - reset($langs); - } - } - - - - return true; -} - -///** -//* GetGroupDepsForConditions() get Dependencies between groups caused by conditions -//* @param string $sid - the currently selected survey -//* @param string $depgid - (optionnal) get only the dependencies applying to the group with gid depgid -//* @param string $targgid - (optionnal) get only the dependencies for groups dependents on group targgid -//* @param string $index-by - (optionnal) "by-depgid" for result indexed with $res[$depgid][$targgid] -//* "by-targgid" for result indexed with $res[$targgid][$depgid] -//* @return array - returns an array describing the conditions or NULL if no dependecy is found -//* -//* Example outupt assumin $index-by="by-depgid": -//*Array -//*( -//* [125] => Array // Group Id 125 is dependent on -//* ( -//* [123] => Array // Group Id 123 -//* ( -//* [depgpname] => G3 // GID-125 has name G3 -//* [targetgpname] => G1 // GID-123 has name G1 -//* [conditions] => Array -//* ( -//* [189] => Array // Because Question Id 189 -//* ( -//* [0] => 9 // Have condition 9 set -//* [1] => 10 // and condition 10 set -//* [2] => 14 // and condition 14 set -//* ) -//* -//* ) -//* -//* ) -//* -//* [124] => Array // GID 125 is also dependent on GID 124 -//* ( -//* [depgpname] => G3 -//* [targetgpname] => G2 -//* [conditions] => Array -//* ( -//* [189] => Array // Because Question Id 189 have conditions set -//* ( -//* [0] => 11 -//* ) -//* -//* [215] => Array // And because Question Id 215 have conditions set -//* ( -//* [0] => 12 -//* ) -//* -//* ) -//* -//* ) -//* -//* ) -//* -//*) -//* -//* Usage example: -//* * Get all group dependencies for SID $sid indexed by depgid: -//* $result=GetGroupDepsForConditions($sid); -//* * Get all group dependencies for GID $gid in survey $sid indexed by depgid: -//* $result=GetGroupDepsForConditions($sid,$gid); -//* * Get all group dependents on group $gid in survey $sid indexed by targgid: -//* $result=GetGroupDepsForConditions($sid,"all",$gid,"by-targgid"); -//*/ -//function GetGroupDepsForConditions($sid,$depgid="all",$targgid="all",$indexby="by-depgid") -//{ -// global $connect, $clang; -// $sid=sanitize_int($sid); -// $condarray = Array(); -// -// $sqldepgid=""; -// $sqltarggid=""; -// if ($depgid != "all") { $depgid = sanitize_int($depgid); $sqldepgid="AND tq.gid=$depgid";} -// if ($targgid != "all") {$targgid = sanitize_int($targgid); $sqltarggid="AND tq2.gid=$targgid";} -// -// $baselang = GetBaseLanguageFromSurveyID($sid); -// $condquery = "SELECT tg.gid as depgid, tg.group_name as depgpname, " -// . "tg2.gid as targgid, tg2.group_name as targgpname, tq.qid as depqid, tc.cid FROM " -// . db_table_name('conditions')." AS tc, " -// . db_table_name('questions')." AS tq, " -// . db_table_name('questions')." AS tq2, " -// . db_table_name('groups')." AS tg ," -// . db_table_name('groups')." AS tg2 " -// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tg.language='{$baselang}' AND tg2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " -// . "AND tq.gid = tg.gid AND tg2.gid = tq2.gid " -// . "AND tq2.qid=tc.cqid AND tq.gid != tg2.gid $sqldepgid $sqltarggid"; -// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked -// -// if ($condresult->RecordCount() > 0) { -// while ($condrow = $condresult->FetchRow()) -// { -// -// switch ($indexby) -// { -// case "by-depgid": -// $depgid=$condrow['depgid']; -// $targetgid=$condrow['targgid']; -// $depqid=$condrow['depqid']; -// $cid=$condrow['cid']; -// $condarray[$depgid][$targetgid]['depgpname'] = $condrow['depgpname']; -// $condarray[$depgid][$targetgid]['targetgpname'] = $condrow['targgpname']; -// $condarray[$depgid][$targetgid]['conditions'][$depqid][]=$cid; -// break; -// -// case "by-targgid": -// $depgid=$condrow['depgid']; -// $targetgid=$condrow['targgid']; -// $depqid=$condrow['depqid']; -// $cid=$condrow['cid']; -// $condarray[$targetgid][$depgid]['depgpname'] = $condrow['depgpname']; -// $condarray[$targetgid][$depgid]['targetgpname'] = $condrow['targgpname']; -// $condarray[$targetgid][$depgid]['conditions'][$depqid][] = $cid; -// break; -// } -// } -// return $condarray; -// } -// return null; -//} - -///** -//* GetQuestDepsForConditions() get Dependencies between groups caused by conditions -//* @param string $sid - the currently selected survey -//* @param string $gid - (optionnal) only search dependecies inside the Group Id $gid -//* @param string $depqid - (optionnal) get only the dependencies applying to the question with qid depqid -//* @param string $targqid - (optionnal) get only the dependencies for questions dependents on question Id targqid -//* @param string $index-by - (optionnal) "by-depqid" for result indexed with $res[$depqid][$targqid] -//* "by-targqid" for result indexed with $res[$targqid][$depqid] -//* @return array - returns an array describing the conditions or NULL if no dependecy is found -//* -//* Example outupt assumin $index-by="by-depqid": -//*Array -//*( -//* [184] => Array // Question Id 184 -//* ( -//* [183] => Array // Depends on Question Id 183 -//* ( -//* [0] => 5 // Because of condition Id 5 -//* ) -//* -//* ) -//* -//*) -//* -//* Usage example: -//* * Get all questions dependencies for Survey $sid and group $gid indexed by depqid: -//* $result=GetQuestDepsForConditions($sid,$gid); -//* * Get all questions dependencies for question $qid in survey/group $sid/$gid indexed by depqid: -//* $result=GetGroupDepsForConditions($sid,$gid,$qid); -//* * Get all questions dependents on question $qid in survey/group $sid/$gid indexed by targqid: -//* $result=GetGroupDepsForConditions($sid,$gid,"all",$qid,"by-targgid"); -//*/ -//function GetQuestDepsForConditions($sid,$gid="all",$depqid="all",$targqid="all",$indexby="by-depqid", $searchscope="samegroup") -//{ -// global $connect, $clang; -// $condarray = Array(); -// -// $baselang = GetBaseLanguageFromSurveyID($sid); -// $sqlgid=""; -// $sqldepqid=""; -// $sqltargqid=""; -// $sqlsearchscope=""; -// if ($gid != "all") {$gid = sanitize_int($gid); $sqlgid="AND tq.gid=$gid";} -// if ($depqid != "all") {$depqid = sanitize_int($depqid); $sqldepqid="AND tq.qid=$depqid";} -// if ($targqid != "all") {$targqid = sanitize_int($targqid); $sqltargqid="AND tq2.qid=$targqid";} -// if ($searchscope == "samegroup") {$sqlsearchscope="AND tq2.gid=tq.gid";} -// -// $condquery = "SELECT tq.qid as depqid, tq2.qid as targqid, tc.cid FROM " -// . db_table_name('conditions')." AS tc, " -// . db_table_name('questions')." AS tq, " -// . db_table_name('questions')." AS tq2 " -// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " -// . "AND tq2.qid=tc.cqid $sqlsearchscope $sqlgid $sqldepqid $sqltargqid"; -// -// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked -// -// if ($condresult->RecordCount() > 0) { -// while ($condrow = $condresult->FetchRow()) -// { -// $depqid=$condrow['depqid']; -// $targetqid=$condrow['targqid']; -// $condid=$condrow['cid']; -// switch ($indexby) -// { -// case "by-depqid": -// $condarray[$depqid][$targetqid][] = $condid; -// break; -// -// case "by-targqid": -// $condarray[$targetqid][$depqid][] = $condid; -// break; -// } -// } -// return $condarray; -// } -// return null; -//} - - -///** -//* checkMovequestionConstraintsForConditions() -//* @param string $sid - the currently selected survey -//* @param string $qid - qid of the question you want to check possible moves -//* @param string $newgid - (optionnal) get only constraints when trying to move to this particular GroupId -//* otherwise, get all moves constraints for this question -//* -//* @return array - returns an array describing the conditions -//* Array -//* ( -//* ['notAbove'] = null | Array -//* ( -//* Array ( gid1, group_order1, qid1, cid1 ) -//* ) -//* ['notBelow'] = null | Array -//* ( -//* Array ( gid2, group_order2, qid2, cid2 ) -//* ) -//* ) -//* -//* This should be read as: -//* - this question can't be move above group gid1 in position group_order1 because of the condition cid1 on question qid1 -//* - this question can't be move below group gid2 in position group_order2 because of the condition cid2 on question qid2 -//* -//*/ -//function checkMovequestionConstraintsForConditions($sid,$qid,$newgid="all") -//{ -// global $connect; -// $resarray=Array(); -// $resarray['notAbove']=null; // defaults to no constraint -// $resarray['notBelow']=null; // defaults to no constraint -// $sid=sanitize_int($sid); -// $qid=sanitize_int($qid); -// -// if ($newgid != "all") -// { -// $newgid=sanitize_int($newgid); -// $newgorder=getGroupOrder($sid,$newgid); -// } -// else -// { -// $neworder=""; // Not used in this case -// } -// -// $baselang = GetBaseLanguageFromSurveyID($sid); -// -// // First look for 'my dependencies': questions on which I have set conditions -// $condquery = "SELECT tq.qid as depqid, tq.gid as depgid, tg.group_order as depgorder, " -// . "tq2.qid as targqid, tq2.gid as targgid, tg2.group_order as targgorder, " -// . "tc.cid FROM " -// . db_table_name('conditions')." AS tc, " -// . db_table_name('questions')." AS tq, " -// . db_table_name('questions')." AS tq2, " -// . db_table_name('groups')." AS tg, " -// . db_table_name('groups')." AS tg2 " -// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " -// . "AND tq2.qid=tc.cqid AND tg.gid=tq.gid AND tg2.gid=tq2.gid AND tq.qid=$qid ORDER BY tg2.group_order DESC"; -// -// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked -// -// if ($condresult->RecordCount() > 0) { -// -// while ($condrow = $condresult->FetchRow() ) -// { -// // This Question can go up to the minimum GID on the 1st row -// $depqid=$condrow['depqid']; -// $depgid=$condrow['depgid']; -// $depgorder=$condrow['depgorder']; -// $targetqid=$condrow['targqid']; -// $targetgid=$condrow['targgid']; -// $targetgorder=$condrow['targgorder']; -// $condid=$condrow['cid']; -// //echo "This question can't go above to GID=$targetgid/order=$targetgorder because of CID=$condid"; -// if ($newgid != "all") -// { // Get only constraints when trying to move to this group -// if ($newgorder < $targetgorder) -// { -// $resarray['notAbove'][]=Array($targetgid,$targetgorder,$depqid,$condid); -// } -// } -// else -// { // get all moves constraints -// $resarray['notAbove'][]=Array($targetgid,$targetgorder,$depqid,$condid); -// } -// } -// } -// -// // Secondly look for 'questions dependent on me': questions that have conditions on my answers -// $condquery = "SELECT tq.qid as depqid, tq.gid as depgid, tg.group_order as depgorder, " -// . "tq2.qid as targqid, tq2.gid as targgid, tg2.group_order as targgorder, " -// . "tc.cid FROM " -// . db_table_name('conditions')." AS tc, " -// . db_table_name('questions')." AS tq, " -// . db_table_name('questions')." AS tq2, " -// . db_table_name('groups')." AS tg, " -// . db_table_name('groups')." AS tg2 " -// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " -// . "AND tq2.qid=tc.cqid AND tg.gid=tq.gid AND tg2.gid=tq2.gid AND tq2.qid=$qid ORDER BY tg.group_order"; -// -// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked -// -// if ($condresult->RecordCount() > 0) { -// -// while ($condrow = $condresult->FetchRow()) -// { -// // This Question can go down to the maximum GID on the 1st row -// $depqid=$condrow['depqid']; -// $depgid=$condrow['depgid']; -// $depgorder=$condrow['depgorder']; -// $targetqid=$condrow['targqid']; -// $targetgid=$condrow['targgid']; -// $targetgorder=$condrow['targgorder']; -// $condid=$condrow['cid']; -// //echo "This question can't go below to GID=$depgid/order=$depgorder because of CID=$condid"; -// if ($newgid != "all") -// { // Get only constraints when trying to move to this group -// if ($newgorder > $depgorder) -// { -// $resarray['notBelow'][]=Array($depgid,$depgorder,$depqid,$condid); -// } -// } -// else -// { // get all moves constraints -// $resarray['notBelow'][]=Array($depgid,$depgorder,$depqid,$condid); -// } -// } -// } -// return $resarray; -//} - -function incompleteAnsFilterstate() -{ - global $filterout_incomplete_answers; - $letsfilter=''; - $letsfilter = returnglobal('filterinc'); //read get/post filterinc - - // first let's initialize the incompleteanswers session variable - if ($letsfilter != '') - { // use the read value if not empty - $_SESSION['incompleteanswers']=$letsfilter; - } - elseif (!isset($_SESSION['incompleteanswers'])) - { // sets default variable value from config file - $_SESSION['incompleteanswers'] = $filterout_incomplete_answers; - } - - if ($_SESSION['incompleteanswers']=='filter') { - return "filter"; //COMPLETE ANSWERS ONLY - } - elseif ($_SESSION['incompleteanswers']=='show') { - return false; //ALL ANSWERS - } - elseif ($_SESSION['incompleteanswers']=='incomplete') { - return "inc"; //INCOMPLETE ANSWERS ONLY - } - else - { // last resort is to prevent filtering - return false; - } -} - -/** -* captcha_enabled($screen, $usecaptchamode) -* @param string $screen - the screen name for which to test captcha activation -* -* @return boolean - returns true if captcha must be enabled -**/ -function captcha_enabled($screen, $captchamode='') -{ - switch($screen) - { - case 'registrationscreen': - if ($captchamode == 'A' || - $captchamode == 'B' || - $captchamode == 'D' || - $captchamode == 'R') - { - return true; - } - else - { - return false; - } - break; - case 'surveyaccessscreen': - if ($captchamode == 'A' || - $captchamode == 'B' || - $captchamode == 'C' || - $captchamode == 'X') - { - return true; - } - else - { - return false; - } - break; - case 'saveandloadscreen': - if ($captchamode == 'A' || - $captchamode == 'C' || - $captchamode == 'D' || - $captchamode == 'S') - { - return true; - } - else - { - return false; - } - return true; - break; - default: - return true; - break; - } -} - - -/** -* used for import[survey|questions|groups] -* -* @param mixed $string -* @return mixed -*/ -function convertCsvreturn2return($string) -{ - $string= str_replace('\n', "\n", $string); - return str_replace('\%n', '\n', $string); -} - - - -/** -* Checks that each object from an array of CSV data [question-rows,answer-rows,labelsets-row] supports at least a given language -* -* @param mixed $csvarray array with a line of csv data per row -* @param mixed $idkeysarray array of integers giving the csv-row numbers of the object keys -* @param mixed $langfieldnum integer giving the csv-row number of the language(s) filed -* ==> the language field can be a single language code or a -* space separated language code list -* @param mixed $langcode the language code to be tested -* @param mixed $hasheader if we should strip off the first line (if it contains headers) -*/ -function bDoesImportarraySupportsLanguage($csvarray,$idkeysarray,$langfieldnum,$langcode, $hasheader = false) -{ - // An array with one row per object id and langsupport status as value - $objlangsupportarray=Array(); - if ($hasheader === true) - { // stripping first row to skip headers if any - array_shift($csvarray); - } - - foreach ($csvarray as $csvrow) - { - $rowcontents = convertCSVRowToArray($csvrow,',','"'); - $rowid = ""; - foreach ($idkeysarray as $idfieldnum) - { - $rowid .= $rowcontents[$idfieldnum]."-"; - } - $rowlangarray = explode (" ", $rowcontents[$langfieldnum]); - if (!isset($objlangsupportarray[$rowid])) - { - if (array_search($langcode,$rowlangarray)!== false) - { - $objlangsupportarray[$rowid] = "true"; - } - else - { - $objlangsupportarray[$rowid] = "false"; - } - } - else - { - if ($objlangsupportarray[$rowid] == "false" && - array_search($langcode,$rowlangarray) !== false) - { - $objlangsupportarray[$rowid] = "true"; - } - } - } // end foreach rown - - // If any of the object doesn't support the given language, return false - if (array_search("false",$objlangsupportarray) === false) - { - return true; - } - else - { - return false; - } -} - -/** This function checks to see if there is an answer saved in the survey session -* data that matches the $code. If it does, it returns that data. -* It is used when building a questions text to allow incorporating the answer -* to an earlier question into the text of a later question. -* IE: Q1: What is your name? [Jason] -* Q2: Hi [Jason] how are you ? -* This function is called from the retriveAnswers function. -* -* @param mixed $code -* @param mixed $phpdateformat The date format in which any dates are shown -* @return mixed returns the answerText from session variable corresponding to a question code -*/ -function retrieve_Answer($code, $phpdateformat=null) -{ - //This function checks to see if there is an answer saved in the survey session - //data that matches the $code. If it does, it returns that data. - //It is used when building a questions text to allow incorporating the answer - //to an earlier question into the text of a later question. - //IE: Q1: What is your name? [Jason] - // Q2: Hi [Jason] how are you ? - //This function is called from the retriveAnswers function. - global $dbprefix, $connect, $clang; - //Find question details - if (isset($_SESSION[$code])) - { - $questiondetails=getsidgidqidaidtype($code); - //the getsidgidqidaidtype function is in common.php and returns - //a SurveyID, GroupID, QuestionID and an Answer code - //extracted from a "fieldname" - ie: 1X2X3a - // also returns question type - - if ($questiondetails['type'] == "M" || $questiondetails['type'] == "P") - { - if ((strpos($code,'comment')>0 || strpos($code,'other')>0) && isset($_SESSION[$code])) - { - return $_SESSION[$code]; - } - $query="SELECT * FROM {$dbprefix}questions WHERE parent_qid='".$questiondetails['qid']."' AND language='".$_SESSION['s_lang']."'"; - $result=db_execute_assoc($query) or safe_die("Error getting answer
      $query
      ".$connect->ErrorMsg()); //Checked - while($row=$result->FetchRow()) - { - if (isset($_SESSION[$code.$row['title']]) && $_SESSION[$code.$row['title']] == "Y") - { - $returns[] = $row['question']; - } - elseif (isset($_SESSION[$code]) && $_SESSION[$code] == "Y" && $questiondetails['aid']==$row['title']) - { - return $row['question']; - } - } - if (isset($_SESSION[$code."other"]) && $_SESSION[$code."other"]) - { - $returns[]=$_SESSION[$code."other"]; - } - if (isset($returns)) - { - $return=implode(", ", $returns); - if (strpos($return, ",")) - { - $return=substr_replace($return, " &", strrpos($return, ","), 1); - } - } - else - { - $return=$clang->gT("No answer"); - } - } - elseif (!$_SESSION[$code] && $_SESSION[$code] !=0) - { - $return=$clang->gT("No answer"); - } - else - { - $return=getextendedanswer($code, $_SESSION[$code], 'INSERTANS',$phpdateformat); - } - } - else - { - $return=$clang->gT("Error") . "($code)"; - } - return html_escape($return); -} - -/** -* Check if a table does exist in the database -* -* @param mixed $sid Table name to check for (without dbprefix!)) -* @return boolean True or false if table exists or not -*/ -function tableExists($tablename) -{ - global $connect; - static $tablelist; - - if (!isset($tablelist)) $tablelist = $connect->MetaTables(); - if ($tablelist==false) - { - return false; - } - foreach ($tablelist as $tbl) - { - if (db_quote_id($tbl) == db_table_name($tablename)) - { - return true; - } - } - return false; -} - -// Returns false if the survey is anonymous, -// and a token table exists: in this case the completed field of a token -// will contain 'Y' instead of the submitted date to ensure privacy -// Returns true otherwise -function bIsTokenCompletedDatestamped($thesurvey) -{ - if ($thesurvey['anonymized'] == 'Y' && tableExists('tokens_'.$thesurvey['sid'])) - { - return false; - } - else - { - return true; - } -} - -/** -* example usage -* $date = "2006-12-31 21:00"; -* $shift "+6 hours"; // could be days, weeks... see function strtotime() for usage -* -* echo sql_date_shift($date, "Y-m-d H:i:s", $shift); -* -* will output: 2007-01-01 03:00:00 -* -* @param mixed $date -* @param mixed $dformat -* @param mixed $shift -* @return string -*/ -function date_shift($date, $dformat, $shift) -{ - return date($dformat, strtotime($shift, strtotime($date))); -} - - -// getBounceEmail: returns email used to receive error notifications -function getBounceEmail($surveyid) -{ - $surveyInfo=getSurveyInfo($surveyid); - - if ($surveyInfo['bounceprocessing'] == 'G') - { - return getGlobalSetting('siteadminbounce'); - } - else if ($surveyInfo['bounce_email'] == '') - { - return null; // will be converted to from in MailText - } - else - { - return $surveyInfo['bounce_email']; - } -} - -// getEmailFormat: returns email format for the survey -// returns 'text' or 'html' -function getEmailFormat($surveyid) -{ - - $surveyInfo=getSurveyInfo($surveyid); - if ($surveyInfo['htmlemail'] == 'Y') - { - return 'html'; - } - else - { - return 'text'; - } - -} - -// Check if user has manage rights for a template -function hasTemplateManageRights($userid, $templatefolder) { - global $connect; - global $dbprefix; - $userid=sanitize_int($userid); - $templatefolder=sanitize_paranoid_string($templatefolder); - $query = "SELECT ".db_quote_id('use')." FROM {$dbprefix}templates_rights WHERE uid=".$userid." AND folder LIKE '".$templatefolder."'"; - - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Safe - - if ($result->RecordCount() == 0) return false; - - $row = $result->FetchRow(); - - return $row["use"]; -} - -/** -* This function creates an incrementing answer code based on the previous source-code -* -* @param mixed $sourcecode The previous answer code -*/ -function getNextCode($sourcecode) -{ - $i=1; - $found=true; - $foundnumber=-1; - while ($i<=strlen($sourcecode) && $found) - { - $found=is_numeric(substr($sourcecode,-$i)); - if ($found) - { - $foundnumber=substr($sourcecode,-$i); - $i++; - } - } - if ($foundnumber==-1) - { - return($sourcecode); - } - else - { - $foundnumber++; - $result=substr($sourcecode,0,strlen($sourcecode)-strlen($foundnumber)).$foundnumber; - return($result); - } - -} - -/** -* Translink -* -* @param mixed $type -* @param mixed $oldid -* @param mixed $newid -* @param mixed $text -* @return mixed -*/ -function translink($type, $oldid, $newid, $text) -{ - global $relativeurl; - if (!isset($_POST['translinksfields'])) - { - return $text; - } - - if ($type == 'survey') - { - $pattern = "([^'\"]*)/upload/surveys/$oldid/"; - $replace = "$relativeurl/upload/surveys/$newid/"; - return preg_replace('#'.$pattern.'#', $replace, $text); - } - elseif ($type == 'label') - { - $pattern = "([^'\"]*)/upload/labels/$oldid/"; - $replace = "$relativeurl/upload/labels/$newid/"; - return preg_replace('#'.$pattern.'#', $replace, $text); - } - else - { - return $text; - } -} - -/** -* This function creates the old fieldnames for survey import -* -* @param mixed $iOldSID The old survey id -* @param mixed $iNewSID The new survey id -* @param array $aGIDReplacements An array with group ids (oldgid=>newgid) -* @param array $aQIDReplacements An array with question ids (oldqid=>newqid) -*/ -function aReverseTranslateFieldnames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements) -{ - $aGIDReplacements=array_flip($aGIDReplacements); - $aQIDReplacements=array_flip($aQIDReplacements); - $aFieldMap=createFieldMap($iNewSID); - $aFieldMappings=array(); - foreach ($aFieldMap as $sFieldname=>$aFieldinfo) - { - if ($aFieldinfo['qid']!=null) - { - $aFieldMappings[$sFieldname]=$iOldSID.'X'.$aGIDReplacements[$aFieldinfo['gid']].'X'.$aQIDReplacements[$aFieldinfo['qid']].$aFieldinfo['aid']; - // now also add a shortened field mapping which is needed for certain kind of condition mappings - $aFieldMappings[$iNewSID.'X'.$aFieldinfo['gid'].'X'.$aFieldinfo['qid']]=$iOldSID.'X'.$aGIDReplacements[$aFieldinfo['gid']].'X'.$aQIDReplacements[$aFieldinfo['qid']]; - } - } - return array_flip($aFieldMappings); -} - - -/** -* This function replaces the old insertans tags with new ones across a survey -* -* @param string $newsid Old SID -* @param string $oldsid New SID -* @param mixed $fieldnames Array array('oldfieldname'=>'newfieldname') -*/ -function TranslateInsertansTags($newsid,$oldsid,$fieldnames) -{ - global $connect, $dbprefix; - - $newsid=sanitize_int($newsid); - $oldsid=sanitize_int($oldsid); - - - # translate 'surveyls_urldescription' and 'surveyls_url' INSERTANS tags in surveyls - $sql = "SELECT surveyls_survey_id, surveyls_language, surveyls_urldescription, surveyls_url from {$dbprefix}surveys_languagesettings WHERE surveyls_survey_id=".$newsid." AND (surveyls_urldescription LIKE '%{INSERTANS:".$oldsid."X%' OR surveyls_url LIKE '%{INSERTANS:".$oldsid."X%')"; - $res = db_execute_assoc($sql) or safe_die("Can't read groups table in transInsertAns ".$connect->ErrorMsg()); // Checked - - while ($qentry = $res->FetchRow()) - { - $urldescription = $qentry['surveyls_urldescription']; - $endurl = $qentry['surveyls_url']; - $language = $qentry['surveyls_language']; - - foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) - { - $pattern = $sOldFieldname; - $replacement = $sNewFieldname; - $urldescription=preg_replace('/'.$pattern.'/', $replacement, $urldescription); - $endurl=preg_replace('/'.$pattern.'/', $replacement, $endurl); - } - - if (strcmp($urldescription,$qentry['surveyls_urldescription']) !=0 || - (strcmp($endurl,$qentry['surveyls_url']) !=0)) - { - // Update Field - $sqlupdate = "UPDATE {$dbprefix}surveys_languagesettings SET surveyls_urldescription='".db_quote($urldescription)."', surveyls_url='".db_quote($endurl)."' WHERE surveyls_survey_id=$newsid AND surveyls_language='$language'"; - $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in surveys_languagesettings
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked - } // Enf if modified - } // end while qentry - - # translate 'quotals_urldescrip' and 'quotals_url' INSERTANS tags in quota_languagesettings - $sql = "SELECT quotals_id, quotals_urldescrip, quotals_url from {$dbprefix}quota_languagesettings qls,{$dbprefix}quota q WHERE sid=".$newsid." AND q.id=qls.quotals_quota_id AND (quotals_urldescrip LIKE '%{INSERTANS:".$oldsid."X%' OR quotals_url LIKE '%{INSERTANS:".$oldsid."X%')"; - $res = db_execute_assoc($sql) or safe_die("Can't read quota table in transInsertAns ".$connect->ErrorMsg()); // Checked - - while ($qentry = $res->FetchRow()) - { - $urldescription = $qentry['quotals_urldescrip']; - $endurl = $qentry['quotals_url']; - - foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) - { - $pattern = $sOldFieldname; - $replacement = $sNewFieldname; - $urldescription=preg_replace('/'.$pattern.'/', $replacement, $urldescription); - $endurl=preg_replace('/'.$pattern.'/', $replacement, $endurl); - } - - if (strcmp($urldescription,$qentry['quotals_urldescrip']) !=0 || - (strcmp($endurl,$qentry['quotals_url']) !=0)) - { - // Update Field - $sqlupdate = "UPDATE {$dbprefix}quota_languagesettings SET quotals_urldescrip='".db_quote($urldescription)."', quotals_url='".db_quote($endurl)."' WHERE quotals_id={$qentry['quotals_id']}"; - $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in quota_languagesettings
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked - } // Enf if modified - } // end while qentry - - - # translate 'description' INSERTANS tags in groups - $sql = "SELECT gid, language, group_name, description from {$dbprefix}groups WHERE sid=".$newsid." AND description LIKE '%{INSERTANS:".$oldsid."X%' OR group_name LIKE '%{INSERTANS:".$oldsid."X%'"; - $res = db_execute_assoc($sql) or safe_die("Can't read groups table in transInsertAns ".$connect->ErrorMsg()); // Checked - - while ($qentry = $res->FetchRow()) - { - $gpname = $qentry['group_name']; - $description = $qentry['description']; - $gid = $qentry['gid']; - $language = $qentry['language']; - - foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) - { - $pattern = $sOldFieldname; - $replacement = $sNewFieldname; - $gpname = preg_replace('/'.$pattern.'/', $replacement, $gpname); - $description=preg_replace('/'.$pattern.'/', $replacement, $description); - } - - if (strcmp($description,$qentry['description']) !=0 || - strcmp($gpname,$qentry['group_name']) !=0) - { - // Update Fields - $sqlupdate = "UPDATE {$dbprefix}groups SET description='".db_quote($description)."', group_name='".db_quote($gpname)."' WHERE gid=$gid AND language='$language'"; - $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in groups
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked - } // Enf if modified - } // end while qentry - - # translate 'question' and 'help' INSERTANS tags in questions - $sql = "SELECT qid, language, question, help from {$dbprefix}questions WHERE sid=".$newsid." AND (question LIKE '%{INSERTANS:".$oldsid."X%' OR help LIKE '%{INSERTANS:".$oldsid."X%')"; - $res = db_execute_assoc($sql) or safe_die("Can't read question table in transInsertAns ".$connect->ErrorMsg()); // Checked - - while ($qentry = $res->FetchRow()) - { - $question = $qentry['question']; - $help = $qentry['help']; - $qid = $qentry['qid']; - $language = $qentry['language']; - - foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) - { - $pattern = $sOldFieldname; - $replacement = $sNewFieldname; - $question=preg_replace('/'.$pattern.'/', $replacement, $question); - $help=preg_replace('/'.$pattern.'/', $replacement, $help); - } - - if (strcmp($question,$qentry['question']) !=0 || - strcmp($help,$qentry['help']) !=0) - { - // Update Field - $sqlupdate = "UPDATE {$dbprefix}questions SET question='".db_quote($question)."', help='".db_quote($help)."' WHERE qid=$qid AND language='$language'"; - $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in question
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked - } // Enf if modified - } // end while qentry - - - # translate 'answer' INSERTANS tags in answers - $sql = "SELECT a.qid, a.language, a.code, a.answer from {$dbprefix}answers as a INNER JOIN {$dbprefix}questions as b ON a.qid=b.qid WHERE b.sid=".$newsid." AND a.answer LIKE '%{INSERTANS:".$oldsid."X%'"; - $res = db_execute_assoc($sql) or safe_die("Can't read answers table in transInsertAns ".$connect->ErrorMsg()); // Checked - - while ($qentry = $res->FetchRow()) - { - $answer = $qentry['answer']; - $code = $qentry['code']; - $qid = $qentry['qid']; - $language = $qentry['language']; - - foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) - { - $pattern = $sOldFieldname; - $replacement = $sNewFieldname; - $answer=preg_replace('/'.$pattern.'/', $replacement, $answer); - } - - if (strcmp($answer,$qentry['answer']) !=0) - { - // Update Field - $sqlupdate = "UPDATE {$dbprefix}answers SET answer='".db_quote($answer)."' WHERE qid=$qid AND code='$code' AND language='$language'"; - $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in answers
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked - } // Enf if modified - } // end while qentry -} - - -/** -* put your comment there... -* -* @param mixed $id -* @param mixed $type -*/ -function hasResources($id,$type='survey') -{ - global $publicdir,$uploaddir; - $dirname = $uploaddir; - - if ($type == 'survey') - { - $dirname .= "/surveys/$id"; - } - elseif ($type == 'label') - { - $dirname .= "/labels/$id"; - } - else - { - return false; - } - - if (is_dir($dirname) && $dh=opendir($dirname)) - { - while(($entry = readdir($dh)) !== false) - { - if($entry !== '.' && $entry !== '..') - { - return true; - break; - } - } - closedir($dh); - } - else - { - return false; - } - - return false; -} - -/** -* Creates a random sequence of characters -* -* @param mixed $length Length of resulting string -* @param string $pattern To define which characters should be in the resulting string -*/ -function sRandomChars($length,$pattern="23456789abcdefghijkmnpqrstuvwxyz") -{ - $patternlength = strlen($pattern)-1; - for($i=0;$i<$length;$i++) - { - if(isset($key)) - $key .= $pattern{rand(0,$patternlength)}; - else - $key = $pattern{rand(0,$patternlength)}; - } - return $key; -} - - - -/** -* used to translate simple text to html (replacing \n with
      -* -* @param mixed $mytext -* @param mixed $ishtml -* @return mixed -*/ -function conditional_nl2br($mytext,$ishtml,$encoded='') -{ - if ($ishtml === true) - { - // $mytext has been processed by clang->gT with html mode - // and thus \n has already been translated to - if ($encoded == '') - { - $mytext=str_replace(' ', '
      ',$mytext); - } - return str_replace("\n", '
      ',$mytext); - } - else - { - return $mytext; - } -} - -function conditional2_nl2br($mytext,$ishtml) -{ - if ($ishtml === true) - { - return str_replace("\n", '
      ',$mytext); - } - else - { - return $mytext; - } -} - -function br2nl( $data ) { - return preg_replace( '!!iU', "\n", $data ); -} - - -function safe_die($text) -{ - //Only allowed tag:
      - $textarray=explode('
      ',$text); - $textarray=array_map('htmlspecialchars',$textarray); - die(implode( '
      ',$textarray)); -} - -/** -* getQuotaInformation() returns quota information for the current survey -* @param string $surveyid - Survey identification number -* @param string $quotaid - Optional quotaid that restricts the result to a given quota -* @return array - nested array, Quotas->Members->Fields -*/ -function getQuotaInformation($surveyid,$language,$quotaid='all') -{ - global $clang, $clienttoken; - $baselang = GetBaseLanguageFromSurveyID($surveyid); - - $query = "SELECT * FROM ".db_table_name('quota').", ".db_table_name('quota_languagesettings')." - WHERE ".db_table_name('quota').".id = ".db_table_name('quota_languagesettings').".quotals_quota_id - AND sid='{$surveyid}' - AND quotals_language='".$language."'"; - if ($quotaid != 'all') - { - $query .= " AND id=$quotaid"; - } - - $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - $quota_info = array(); - $x=0; - - $surveyinfo=getSurveyInfo($surveyid); - - // Check all quotas for the current survey - if ($result->RecordCount() > 0) - { - while ($survey_quotas = $result->FetchRow()) - { - //Modify the URL - thanks janokary - $survey_quotas['quotals_url']=str_replace("{SAVEDID}",isset($_SESSION['srid']) ? $_SESSION['srid'] : '', $survey_quotas['quotals_url']); - $survey_quotas['quotals_url']=str_replace("{SID}", $surveyid, $survey_quotas['quotals_url']); - $survey_quotas['quotals_url']=str_replace("{LANG}", $clang->getlangcode(), $survey_quotas['quotals_url']); - $survey_quotas['quotals_url']=str_replace("{TOKEN}",$clienttoken, $survey_quotas['quotals_url']); - - array_push($quota_info,array('Name' => $survey_quotas['name'], - 'Limit' => $survey_quotas['qlimit'], - 'Action' => $survey_quotas['action'], - 'Message' => $survey_quotas['quotals_message'], - 'Url' => passthruReplace(insertansReplace($survey_quotas['quotals_url']), $surveyinfo), - 'UrlDescrip' => $survey_quotas['quotals_urldescrip'], - 'AutoloadUrl' => $survey_quotas['autoload_url'])); - $query = "SELECT * FROM ".db_table_name('quota_members')." WHERE quota_id='{$survey_quotas['id']}'"; - $result_qe = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - $quota_info[$x]['members'] = array(); - if ($result_qe->RecordCount() > 0) - { - while ($quota_entry = $result_qe->FetchRow()) - { - $query = "SELECT type, title,gid FROM ".db_table_name('questions')." WHERE qid='{$quota_entry['qid']}' AND language='{$baselang}'"; - $result_quest = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked - $qtype = $result_quest->FetchRow(); - - $fieldnames = "0"; - - if ($qtype['type'] == "I" || $qtype['type'] == "G" || $qtype['type'] == "Y") - { - $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); - $value = $quota_entry['code']; - } - - if($qtype['type'] == "L" || $qtype['type'] == "O" || $qtype['type'] =="!") - { - $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); - $value = $quota_entry['code']; - } - - if($qtype['type'] == "M") - { - $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$quota_entry['code']); - $value = "Y"; - } - - if($qtype['type'] == "A" || $qtype['type'] == "B") - { - $temp = explode('-',$quota_entry['code']); - $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$temp[0]); - $value = $temp[1]; - } - - array_push($quota_info[$x]['members'],array('Title' => $qtype['title'], - 'type' => $qtype['type'], - 'code' => $quota_entry['code'], - 'value' => $value, - 'qid' => $quota_entry['qid'], - 'fieldnames' => $fieldnames)); - } - } - $x++; - } - } - return $quota_info; -} - -/** -* get_quotaCompletedCount() returns the number of answers matching the quota -* @param string $surveyid - Survey identification number -* @param string $quotaid - quota id for which you want to compute the completed field -* @return string - number of mathing entries in the result DB or 'N/A' -*/ -function get_quotaCompletedCount($surveyid, $quotaid) -{ - $result ="N/A"; - $quota_info = getQuotaInformation($surveyid,GetBaseLanguageFromSurveyID($surveyid),$quotaid); - $quota = $quota_info[0]; - - if ( db_tables_exist(db_table_name_nq('survey_'.$surveyid)) && - count($quota['members']) > 0) - { - $fields_list = array(); // Keep a list of fields for easy reference - // construct an array of value for each $quota['members']['fieldnames'] - unset($querycond); - $fields_query = array(); - foreach($quota['members'] as $member) - { - foreach($member['fieldnames'] as $fieldname) - { - if (!in_array($fieldname,$fields_list)){ - $fields_list[] = $fieldname; - $fields_query[$fieldname] = array(); - } - $fields_query[$fieldname][]= db_quote_id($fieldname)." = '{$member['value']}'"; - } - } - - foreach($fields_list as $fieldname) - { - $select_query = " ( ".implode(' OR ',$fields_query[$fieldname]).' )'; - $querycond[] = $select_query; - } - - $querysel = "SELECT count(id) as count FROM ".db_table_name('survey_'.$surveyid)." WHERE ".implode(' AND ',$querycond)." "." AND submitdate IS NOT NULL"; - $result = db_execute_assoc($querysel) or safe_die($connect->ErrorMsg()); //Checked - $quota_check = $result->FetchRow(); - $result = $quota_check['count']; - } - - return $result; -} - -function fix_FCKeditor_text($str) -{ - $str = str_replace('
      ','',$str); - if ($str == "
      " || $str == " " || $str == " ") - { - $str = ""; - } - if (preg_match("/^[\s]+$/",$str)) - { - $str=''; - } - if ($str == "\n") - { - $str = ""; - } - if (trim($str) == " " || trim($str)=='') - { // chrome adds a single   element to empty fckeditor fields - $str = ""; - } - - return $str; -} - - -function recursive_stripslashes($array_or_string) -{ - if (is_array($array_or_string)) - { - return array_map('recursive_stripslashes', $array_or_string); - } - else - { - return stripslashes($array_or_string); - } -} - - - - -/** -* This is a helper function for GetAttributeFieldNames -* -* @param mixed $fieldname -*/ -function filterforattributes ($fieldname) -{ - if (strpos($fieldname,'attribute_')===false) return false; else return true; -} - - -/** -* Retrieves the attribute field names from the related token table -* -* @param mixed $surveyid The survey ID -* @return array The fieldnames -*/ -function GetAttributeFieldNames($surveyid) -{ - global $dbprefix, $connect; - if (tableExists('tokens_'.$surveyid) === false) - { - return Array(); - } - $tokenfieldnames = array_values($connect->MetaColumnNames("{$dbprefix}tokens_$surveyid", true)); - return array_filter($tokenfieldnames,'filterforattributes'); -} - -/** -* Retrieves the token field names usable for conditions from the related token table -* -* @param mixed $surveyid The survey ID -* @return array The fieldnames -*/ -function GetTokenConditionsFieldNames($surveyid) -{ - $extra_attrs=GetAttributeFieldNames($surveyid); - $basic_attrs=Array('firstname','lastname','email','token','language','sent','remindersent','remindercount','usesleft'); - return array_merge($basic_attrs,$extra_attrs); -} - -/** -* Retrieves the attribute names from the related token table -* -* @param mixed $surveyid The survey ID -* @param boolean $onlyAttributes Set this to true if you only want the fieldnames of the additional attribue fields - defaults to false -* @return array The fieldnames as key and names as value in an Array -*/ -function GetTokenFieldsAndNames($surveyid, $onlyAttributes=false) -{ - global $dbprefix, $connect, $clang; - if (tableExists('tokens_'.$surveyid) === false) - { - return Array(); - } - $extra_attrs=GetAttributeFieldNames($surveyid); - $basic_attrs=Array('firstname','lastname','email','token','language','sent','remindersent','remindercount','usesleft'); - $basic_attrs_names=Array( - $clang->gT('First name'), - $clang->gT('Last name'), - $clang->gT('Email address'), - $clang->gT('Token code'), - $clang->gT('Language code'), - $clang->gT('Invitation sent date'), - $clang->gT('Last Reminder sent date'), - $clang->gT('Total numbers of sent reminders'), - $clang->gT('Uses left') - ); - - $thissurvey=getSurveyInfo($surveyid); - $attdescriptiondata=!empty($thissurvey['attributedescriptions']) ? $thissurvey['attributedescriptions'] : ""; - $attdescriptiondata=explode("\n",$attdescriptiondata); - $attributedescriptions=array(); - $basic_attrs_and_names=array(); - $extra_attrs_and_names=array(); - foreach ($attdescriptiondata as $attdescription) - { - $attributedescriptions['attribute_'.substr($attdescription,10,strpos($attdescription,'=')-10)] = substr($attdescription,strpos($attdescription,'=')+1); - } - foreach ($extra_attrs as $fieldname) - { - if (isset($attributedescriptions[$fieldname])) - { - $extra_attrs_and_names[$fieldname]=$attributedescriptions[$fieldname]; - } - else - { - $extra_attrs_and_names[$fieldname]=sprintf($clang->gT('Attribute %s'),substr($fieldname,10)); - } - } - if ($onlyAttributes===false) - { - $basic_attrs_and_names=array_combine($basic_attrs,$basic_attrs_names); - return array_merge($basic_attrs_and_names,$extra_attrs_and_names); - } - else - { - return $extra_attrs_and_names; - } -} - -/** -* Retrieves the token attribute value from the related token table -* -* @param mixed $surveyid The survey ID -* @param mixed $attrName The token-attribute field name -* @param mixed $token The token code -* @return string The token attribute value (or null on error) -*/ -function GetAttributeValue($surveyid,$attrName,$token) -{ - global $dbprefix, $connect; - $attrName=strtolower($attrName); - if (!tableExists('tokens_'.$surveyid) || !in_array($attrName,GetTokenConditionsFieldNames($surveyid))) - { - return null; - } - $sanitized_token=$connect->qstr($token,get_magic_quotes_gpc()); - $surveyid=sanitize_int($surveyid); - - $query="SELECT $attrName FROM {$dbprefix}tokens_$surveyid WHERE token=$sanitized_token"; - $result=db_execute_num($query); - $count=$result->RecordCount(); - if ($count != 1) - { - return null; - } - else - { - $row=$result->FetchRow(); - return $row[0]; - } -} - -/** -* This function strips any content between and including @siU' // Strip style tags properly - /* ,'@<[\/\!]*?[^<>]*?>@si', // Strip out HTML tags - '@@' // Strip multi-line comments including CDATA - */ - ); - $text = preg_replace($search, '', $content); - return $text; -} - - -/** -* This function cleans files from the temporary directory being older than 1 day -* @todo Make the days configurable -*/ -function cleanTempDirectory() -{ - global $tempdir; - $dir= $tempdir.'/'; - $dp = opendir($dir) or die ('Could not open temporary directory'); - while ($file = readdir($dp)) { - if (is_file($dir.$file) && (filemtime($dir.$file)) < (strtotime('-1 days')) && $file!='index.html' && $file!='readme.txt' && $file!='..' && $file!='.' && $file!='.svn') { - @unlink($dir.$file); - } - } - $dir= $tempdir.'/upload/'; - $dp = opendir($dir) or die ('Could not open temporary directory'); - while ($file = readdir($dp)) { - if (is_file($dir.$file) && (filemtime($dir.$file)) < (strtotime('-1 days')) && $file!='index.html' && $file!='readme.txt' && $file!='..' && $file!='.' && $file!='.svn') { - @unlink($dir.$file); - } - } - closedir($dp); -} - - -function use_firebug() -{ - if(FIREBUG == true) - { - return ''; - }; -}; - -/** -* This is a convenience function for the coversion of datetime values -* -* @param mixed $value -* @param mixed $fromdateformat -* @param mixed $todateformat -* @return string -*/ -function convertDateTimeFormat($value, $fromdateformat, $todateformat) -{ - $datetimeobj = new Date_Time_Converter($value , $fromdateformat); - return $datetimeobj->convert($todateformat); -} - - -/** -* This function removes the UTF-8 Byte Order Mark from a string -* -* @param string $str -* @return string -*/ -function removeBOM($str=""){ - if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { - $str=substr($str, 3); - } - return $str; -} - -/** -* This function requests the latest update information from the LimeSurvey.org website -* -* @returns array Contains update information or false if the request failed for some reason -*/ -function GetUpdateInfo() -{ - global $homedir, $debug, $buildnumber, $versionnumber; - require_once($homedir."/classes/http/http.php"); - - $http=new http_class; - - /* Connection timeout */ - $http->timeout=0; - /* Data transfer timeout */ - $http->data_timeout=0; - $http->user_agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"; - $http->GetRequestArguments("http://update.limesurvey.org?build=$buildnumber",$arguments); - - $updateinfo=false; - $error=$http->Open($arguments); - $error=$http->SendRequest($arguments); - - $http->ReadReplyHeaders($headers); - - - if($error=="") { - $body=''; $full_body=''; - for(;;){ - $error = $http->ReadReplyBody($body,10000); - if($error != "" || strlen($body)==0) break; - $full_body .= $body; - } - $updateinfo=json_decode($full_body,true); - if ($http->response_status!='200') - { - $updateinfo['errorcode']=$http->response_status; - $updateinfo['errorhtml']=$full_body; - } - } - else - { - $updateinfo['errorcode']=$error; - $updateinfo['errorhtml']=$error; - } - unset( $http ); - return $updateinfo; -} - - - -/** -* This function updates the actual global variables if an update is available after using GetUpdateInfo -* @return Array with update or error information -*/ -function updatecheck() -{ - global $buildnumber; - $updateinfo=GetUpdateInfo(); - if (isset($updateinfo['Targetversion']['build']) && (int)$updateinfo['Targetversion']['build']>(int)$buildnumber && trim($buildnumber)!='') - { - setGlobalSetting('updateavailable',1); - setGlobalSetting('updatebuild',$updateinfo['Targetversion']['build']); - setGlobalSetting('updateversion',$updateinfo['Targetversion']['versionnumber']); - } - else - { - setGlobalSetting('updateavailable',0); - } - setGlobalSetting('updatelastcheck',date('Y-m-d H:i:s')); - return $updateinfo; -} - -/** -* This function removes a directory recursively -* -* @param mixed $dirname -* @return bool -*/ -function rmdirr($dirname) -{ - // Sanity check - if (!file_exists($dirname)) { - return false; - } - - // Simple delete for a file - if (is_file($dirname) || is_link($dirname)) { - return @unlink($dirname); - } - - // Loop through the folder - $dir = dir($dirname); - while (false !== $entry = $dir->read()) { - // Skip pointers - if ($entry == '.' || $entry == '..') { - continue; - } - - // Recurse - rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); - } - - // Clean up - $dir->close(); - return @rmdir($dirname); -} - -function getTokenData($surveyid, $token) -{ - global $dbprefix, $connect; - $query = "SELECT * FROM ".db_table_name('tokens_'.$surveyid)." WHERE token='".db_quote($token)."'"; - $result = db_execute_assoc($query) or safe_die("Couldn't get token info in getTokenData()
      ".$query."
      ".$connect->ErrorMsg()); //Checked - $thistoken=array(); // so has default value - while($row=$result->FetchRow()) - { - $thistoken=array("firstname"=>$row['firstname'], - "lastname"=>$row['lastname'], - "email"=>$row['email'], - "language" =>$row['language'], - "usesleft" =>$row['usesleft'], - ); - $attrfieldnames=GetAttributeFieldnames($surveyid); - foreach ($attrfieldnames as $attr_name) - { - $thistoken[$attr_name]=$row[$attr_name]; - } - } // while - return $thistoken; -} - - -/** -* This function returns the complete directory path to a given template name -* -* @param mixed $sTemplateName -*/ -function sGetTemplatePath($sTemplateName) -{ - global $standardtemplaterootdir, $usertemplaterootdir, $defaulttemplate; - if (isStandardTemplate($sTemplateName)) - { - return $standardtemplaterootdir.'/'.$sTemplateName; - } - else - { - if (file_exists($usertemplaterootdir.'/'.$sTemplateName)) - { - return $usertemplaterootdir.'/'.$sTemplateName; - } - elseif (file_exists($usertemplaterootdir.'/'.$defaulttemplate)) - { - return $usertemplaterootdir.'/'.$defaulttemplate; - } - elseif (file_exists($standardtemplaterootdir.'/'.$defaulttemplate)) - { - return $standardtemplaterootdir.'/'.$defaulttemplate; - } - else - { - return $standardtemplaterootdir.'/default'; - } - } -} - -/** -* This function returns the complete URL path to a given template name -* -* @param mixed $sTemplateName -*/ -function sGetTemplateURL($sTemplateName) -{ - global $standardtemplaterooturl, $standardtemplaterootdir, $usertemplaterooturl, $usertemplaterootdir, $defaulttemplate; - if (isStandardTemplate($sTemplateName)) - { - return $standardtemplaterooturl.'/'.$sTemplateName; - } - else - { - if (file_exists($usertemplaterootdir.'/'.$sTemplateName)) - { - return $usertemplaterooturl.'/'.$sTemplateName; - } - elseif (file_exists($usertemplaterootdir.'/'.$defaulttemplate)) - { - return $usertemplaterooturl.'/'.$defaulttemplate; - } - elseif (file_exists($standardtemplaterootdir.'/'.$defaulttemplate)) - { - return $standardtemplaterooturl.'/'.$defaulttemplate; - } - else - { - return $standardtemplaterooturl.'/default'; - } - } -} - -/** -* Return the goodchars to be used when filtering input for numbers. -* -* @param $lang string language used, for localisation -* @param $integer bool use only integer -* @param $negative bool allow negative values -*/ -function getNumericalFormat($lang = 'en', $integer = false, $negative = true) { - $goodchars = "0123456789"; - if ($integer === false) $goodchars .= "."; //Todo, add localisation - if ($negative === true) $goodchars .= "-"; //Todo, check databases - return $goodchars; -} - -/** -* Return an array of subquestions for a given sid/qid -* -* @param int $sid -* @param int $qid -* @param $sLanguage Language of the subquestion text -*/ -function getSubQuestions($sid, $qid, $sLanguage) { - global $dbprefix, $connect, $clang; - static $subquestions; - - if (!isset($subquestions[$sid])) { - $sid = sanitize_int($sid); - $query = "SELECT sq.*, q.other FROM {$dbprefix}questions as sq, {$dbprefix}questions as q" - ." WHERE sq.parent_qid=q.qid AND q.sid=$sid" - ." AND sq.language='".$sLanguage. "' " - ." AND q.language='".$sLanguage. "' " - ." ORDER BY sq.parent_qid, q.question_order,sq.scale_id , sq.question_order"; - $result=db_execute_assoc($query) or safe_die ("Couldn't get perform answers query
      $query
      ".$connect->ErrorMsg()); //Checked - $resultset=array(); - while ($row=$result->FetchRow()) - { - $resultset[$row['parent_qid']][] = $row; - } - $subquestions[$sid] = $resultset; - } - if (isset($subquestions[$sid][$qid])) return $subquestions[$sid][$qid]; - return array(); -} - -/** -* Wrapper function to retrieve an xmlwriter object and do error handling if it is not compiled -* into PHP -*/ -function getXMLWriter() { - if (!extension_loaded('xmlwriter')) { - safe_die('XMLWriter class not compiled into PHP, please contact your system administrator'); - } else { - $xmlwriter = new XMLWriter(); - } - return $xmlwriter; -} - - - -/* -* Return a sql statement for renaming a table -*/ -function db_rename_table($oldtable, $newtable) -{ - global $connect; - - $dict = NewDataDictionary($connect); - $result=$dict->RenameTableSQL($oldtable, $newtable); - return $result[0]; -} - -/** -* Returns true when a token can not be used (either doesn't exist or has less then one usage left -* -* @param mixed $tid Token -*/ -function usedTokens($token) -{ - global $dbprefix, $surveyid; - - $utresult = true; - $query = "SELECT tid, usesleft from {$dbprefix}tokens_$surveyid WHERE token=".db_quoteall($token); - - $result=db_execute_assoc($query,null,true); - if ($result !== false) { - $row=$result->FetchRow(); - if ($row['usesleft']>0) $utresult = false; - } - return $utresult; -} - - - -/** -* redirect() generates a redirect URL for the apporpriate SSL mode then applies it. -* -* @param $ssl_mode string 's' or '' (empty). -*/ -function redirect($ssl_mode) -{ - $url = 'http'.$ssl_mode.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; - if (!headers_sent()) - { // If headers not sent yet... then do php redirect - ob_clean(); - header('Location: '.$url); - ob_flush(); - exit; - }; -}; - -/** -* SSL_mode() $force_ssl is on or off, it checks if the current -* request is to HTTPS (or not). If $force_ssl is on, and the -* request is not to HTTPS, it redirects the request to the HTTPS -* version of the URL, if the request is to HTTPS, it rewrites all -* the URL variables so they also point to HTTPS. -*/ -function SSL_mode() -{ - global $rooturl , $homeurl , $publicurl , $tempurl , $imageurl , $uploadurl; - global $usertemplaterooturl , $standardtemplaterooturl; - global $parsedurl , $relativeurl , $fckeditordir , $ssl_emergency_override; - - $https = isset($_SERVER['HTTPS'])?$_SERVER['HTTPS']:''; - if($ssl_emergency_override !== true ) - { - $force_ssl = strtolower(getGlobalSetting('force_ssl')); - } - else - { - $force_ssl = 'off'; - }; - if( $force_ssl == 'on' && $https == '' ) - { - redirect('s'); - } - if( $force_ssl == 'off' && $https != '') - { - redirect(''); - }; -}; - - -/** -* Creates an array with details on a particular response for display purposes -* Used in Print answers (done), Detailed response view (Todo:)and Detailed admin notification email (done) -* -* @param mixed $iSurveyID -* @param mixed $iResponseID -* @param mixed $sLanguageCode -* @param boolean $bHonorConditions Apply conditions -*/ -function aGetFullResponseTable($iSurveyID, $iResponseID, $sLanguageCode, $bHonorConditions=false) -{ - global $connect; - $aFieldMap = createFieldMap($iSurveyID,'full',false,false,$sLanguageCode); - //Get response data - $idquery = "SELECT * FROM ".db_table_name('survey_'.$iSurveyID)." WHERE id=".$iResponseID; - $idrow=$connect->GetRow($idquery) or safe_die ("Couldn't get entry
      \n$idquery
      \n".$connect->ErrorMsg()); //Checked - - $aResultTable=array(); - - $oldgid = 0; - $oldqid = 0; - foreach ($aFieldMap as $sKey=>$fname) - { - if (!empty($fname['qid'])) - { - $attributes = getQuestionAttributes($fname['qid']); - if (getQuestionAttributeValue($attributes, 'hidden') == 1) - { - continue; - } - } - $question = $fname['question']; - $subquestion=''; - if (isset($fname['gid']) && !empty($fname['gid'])) { - //Check to see if gid is the same as before. if not show group name - if ($oldgid !== $fname['gid']) - { - $oldgid = $fname['gid']; - $aResultTable['gid_'.$fname['gid']]=array($fname['group_name']); - } - } - if (isset($fname['qid']) && !empty($fname['qid'])) - { - if ($oldqid !== $fname['qid']) - { - $oldqid = $fname['qid']; - if (($bHonorConditions && LimeExpressionManager::QuestionIsRelevant($fname['qid'])) || !$bHonorConditions) - { - if (isset($fname['subquestion']) || isset($fname['subquestion1']) || isset($fname['subquestion2'])) - { - $aResultTable['qid_'.$fname['sid'].'X'.$fname['gid'].'X'.$fname['qid']]=array($fname['question'],'',''); - } - else - { - $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); - $aResultTable[$fname['fieldname']]=array($question,'',$answer); - continue; - } - - } - else - { - continue; - } - - } - } - else - { - $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); - $aResultTable[$fname['fieldname']]=array($question,'',$answer); - continue; - } - if (isset($fname['subquestion'])) - $subquestion = "{$fname['subquestion']}"; - - if (isset($fname['subquestion1'])) - $subquestion = "{$fname['subquestion1']}"; - - if (isset($fname['subquestion2'])) - $subquestion .= "[{$fname['subquestion2']}]"; - - $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); - $aResultTable[$fname['fieldname']]=array('',$subquestion,$answer); - } - return $aResultTable; -} - - - -/** -* Check if $str is an integer, or string representation of an integer -* -* @param mixed $mStr -*/ -function bIsNumericInt($mStr) -{ - if(is_int($mStr)) - return true; - elseif(is_string($mStr)) - return preg_match("/^[0-9]+$/", $mStr); - return false; -} - -/** -* Invert key/values of an associative array, preserving multiple values in -* the source array as a single key with multiple values in the resulting -* array. -* -* This is not the same as array_flip(), which flattens the structure of the -* source array. -* -* @param array $aArr -*/ -function aArrayInvert($aArr) -{ - $aRet = array(); - foreach($aArr as $k => $v) - $aRet[$v][] = $k; - return $aRet; -} - -/** -* Include Keypad headers -*/ -function vIncludeKeypad() -{ - global $js_header_includes, $css_header_includes, $clang; - - $js_header_includes[] = '/scripts/jquery/jquery.keypad.min.js'; - if ($clang->langcode !== 'en') - { - $js_header_includes[] = '/scripts/jquery/locale/jquery.ui.keypad-'.$clang->langcode.'.js'; - } - $css_header_includes[] = '/scripts/jquery/css/jquery.keypad.alt.css'; -} - -/** -* Strips the DB prefix from a string - does not verify just strips the according number of characters -* -* @param mixed $sTableName -* @return string -*/ -function sStripDBPrefix($sTableName) -{ - global $dbprefix; - return substr($sTableName,strlen($dbprefix)); -} - -/* -* Emit the standard (last) onsubmit handler for the survey. -* -* This code in injected in the three questionnaire modes right after the
      element, -* before the individual questions emit their own onsubmit replacement code. -*/ -function sDefaultSubmitHandler() -{ - return << - - -EOS; -} - -/** -* This function fixes the group ID and type on all subquestions -* -*/ -function fixSubquestions() -{ - $surveyidresult=db_select_limit_assoc("select sq.qid, sq.parent_qid, sq.gid as sqgid, q.gid, sq.type as sqtype, q.type - from ".db_table_name('questions')." sq JOIN ".db_table_name('questions')." q on sq.parent_qid=q.qid - where sq.parent_qid>0 and (sq.gid!=q.gid or sq.type!=q.type)",1000); - while ($sv = $surveyidresult->FetchRow()) - { - db_execute_assoc('update '.db_table_name('questions')." set type='{$sv['type']}', gid={$sv['gid']} where qid={$sv['qid']}"); - } - -} - - -// Closing PHP tag intentionally omitted - yes, it is okay +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'=>0, + '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'=>0, + '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'=>0, + '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'=>0, + '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'=>0, + 'assessable'=>0, + 'answerscales'=>0), + "T"=>array('description'=>$clang->gT("Long Free Text"), + 'group'=>$group['TextQuestions'], + 'subquestions'=>0, + 'hasdefaultvalues'=>0, + 'assessable'=>0, + 'answerscales'=>0), + "U"=>array('description'=>$clang->gT("Huge Free Text"), + 'group'=>$group['TextQuestions'], + 'subquestions'=>0, + 'hasdefaultvalues'=>0, + '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 .= ''; + foreach($members as $TypeCode=>$TypeProperties){ + $qtypeselecter .= " formatted list of existing surveys +* +*/ +function getsurveylist($returnarray=false,$returnwithouturl=false) +{ + global $surveyid, $dbprefix, $scriptname, $connect, $clang, $timeadjust; + static $cached = null; + + if(is_null($cached)) { + $surveyidquery = " SELECT a.*, surveyls_title, surveyls_description, surveyls_welcometext, surveyls_url " + ." FROM ".db_table_name('surveys')." AS a " + . "INNER JOIN ".db_table_name('surveys_languagesettings')." on (surveyls_survey_id=a.sid and surveyls_language=a.language) "; + + if (!bHasGlobalPermission('USER_RIGHT_SUPERADMIN')) + { + $surveyidquery .= "WHERE a.sid in (select sid from ".db_table_name('survey_permissions')." where uid={$_SESSION['loginID']} and permission='survey' and read_p=1) "; + } + + $surveyidquery .= " order by active DESC, surveyls_title"; + $surveyidresult = db_execute_assoc($surveyidquery); //Checked + if (!$surveyidresult) {return "Database Error";} + $surveynames = $surveyidresult->GetRows(); + $cached=$surveynames; + } else { + $surveynames = $cached; + } + $surveyselecter = ""; + if ($returnarray===true) return $surveynames; + $activesurveys=''; + $inactivesurveys=''; + $expiredsurveys=''; + if ($surveynames) + { + foreach($surveynames as $sv) + { + + $surveylstitle=FlattenText($sv['surveyls_title']); + if (strlen($surveylstitle)>45) + { + $surveylstitle = htmlspecialchars(mb_strcut(html_entity_decode($surveylstitle,ENT_QUOTES,'UTF-8'), 0, 45, 'UTF-8'))."..."; + } + + if($sv['active']!='Y') + { + $inactivesurveys .= ""; + } + if ($expiredsurveys!='') + { + $surveyselecter .= "\n"; + $surveyselecter .= $expiredsurveys . ""; + } + if ($inactivesurveys!='') + { + $surveyselecter .= "\n"; + $surveyselecter .= $inactivesurveys . ""; + } + 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 + }; +}; + +if(!defined('COLSTYLE')) +{ + /** + * The following prepares and defines the 'COLSTYLE' constant which + * dictates how columns are to be marked up for list type questions. + * + * $column_style is initialised at the end of config-defaults.php or from within config.php + */ + if( !isset($column_style) || + $column_style != 'css' || + $column_style != 'ul' || + $column_style != 'table' || + $column_style != null ) + { + $column_style = 'ul'; + }; + define('COLSTYLE' ,strtolower($column_style), true); +}; + + +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 constant COLSTYLE which sets how columns should + * be rendered. + * + * COLSTYLE is defined 30 lines above. + * + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * 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. + */ + + + $colstyle = COLSTYLE; + + /* + if(defined('PRINT_TEMPLATE')) // This forces tables based columns for printablesurvey + { + $colstyle = 'table'; + }; + */ + if($columns < 2) + { + $colstyle = 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 && $colstyle != null) + { + if($colstyle == '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" + ,'whole-end' => "
    \n" + ,'col-devide' => '' + ,'col-devide-last' => '' + ,'item-start' => "\t
  • \n" + ,'item-start-other' => "\t
  • \n" + ,'item-end' => "\t
  • \n" + ,'maxrows' => ceil($answer_count/$columns) //Always rounds up to nearest whole number + ,'cols' => $columns + ); + + switch($colstyle) + { + case 'ul': if($columns > 1) + { + $wrapper['col-devide'] = "\n\n\n\n"; + $wrapper['col-devide-last'] = "\n\n\n\n"; + } + break; + + case 'table': $table_cols = ''; + for($cols = $columns ; $cols > 0 ; --$cols) + { + switch($cols) + { + case $columns: $table_cols .= "\t\n"; + break; + case 1: $table_cols .= "\t\n"; + break; + default: $table_cols .= "\t\n"; + }; + }; + + if($columns > 1) + { + $wrapper['col-devide'] = "\t\n\n\n\n\t
      \n"; + $wrapper['col-devide-last'] = "\t
    \n\n\n\n\t
      \n"; + }; + $wrapper['whole-start'] = "\n\n$table_cols\n\t\n\n\n\t
        \n"; + $wrapper['whole-end'] = "\t
      \n\n\n\t\n\n"; + $wrapper['item-start'] = "
    • \n"; + $wrapper['item-end'] = "
    • \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"; + } + if ($groupselecter) + { + if (!isset($gvexist)) {$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"; + } + if ($groupselecter) + { + if (!$gvexist) {$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"; + } + return $groupselecter; +} + +/** +* Gives back the name of a group for a certaing group id +* +* @param integer $gid Group ID +*/ +function getgroupname($gid) +{ + global $surveyid; + if (!$surveyid) {$surveyid=returnglobal('sid');} + $s_lang = GetBaseLanguageFromSurveyID($surveyid); + $gidquery = "SELECT group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='{$s_lang}' and gid=$gid"; + + $gidresult = db_execute_num($gidquery) or safe_die("Group name could not be fetched (getgroupname)."); //Checked + while ($gv = $gidresult->FetchRow()) + { + $groupname = htmlspecialchars($gv[0]); + } + return $groupname; +} + +/** +* put your comment there... +* +* @param mixed $gid +* @param mixed $language +*/ +function getgrouplistlang($gid, $language) +{ + global $surveyid, $scriptname, $connect, $clang; + + $groupselecter=""; + if (!$surveyid) {$surveyid=returnglobal('sid');} + $gidquery = "SELECT gid, group_name FROM ".db_table_name('groups')." WHERE sid=$surveyid AND language='".$language."' 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 .= "gT("Please choose...")."\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") + { + 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."'"; + $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; + 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, $standardtemplaterootdir, $defaulttemplate; + if (is_dir("$usertemplaterootdir/{$templatename}/")) + { + return $templatename; + } + elseif (is_dir("$standardtemplaterootdir/{$templatename}/")) + { + return $templatename; + } + 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, $globalfieldmap, $clang, $aDuplicateQIDs; + $surveyid=sanitize_int($surveyid); + + //Get list of questions + if (is_null($sQuestionLanguage)) + { + if (isset($_SESSION['s_lang'])) { + $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($globalfieldmap[$surveyid][$style][$s_lang]) && $force_refresh==false) { + return $globalfieldmap[$surveyid][$style][$s_lang]; + } + if (isset($_SESSION['fieldmap-' . $surveyid . $s_lang]) && !$force_refresh) { + 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 + + while ($arow=$aresult->FetchRow()) //With each question, create the appropriate field(s) + { + ++$questionSeq; + + // 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']=$arow['group_order']; + 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']=$arow['group_order']; + $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']=$arow['group_order']; + } + 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']=$arow['group_order']; + $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']=$arow['group_order']; + } + + $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']=$arow['group_order']; + } + } + } + + 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']=$arow['group_order']; + } + } + } + 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(); + + for ($i = 1; $i <= $abrow['value']; $i++) + { + $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']=$arow['group_order']; + } + $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']=$arow['group_order']; + } + } + } + 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']=$arow['group_order']; + $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']=$arow['group_order']; + } + } + } + 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']=$arow['group_order']; + $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']=$arow['group_order']; + $fieldmap[$fieldname]['other']=$arow['other']; + } + } + } + } + $fieldmap[$fieldname]['relevance']=$arow['relevance']; + $fieldmap[$fieldname]['grelevance']=$arow['grelevance']; + $fieldmap[$fieldname]['questionSeq']=$questionSeq; + $fieldmap[$fieldname]['groupSeq']=$arow['group_order']; + $fieldmap[$fieldname]['preg']=$arow['preg']; + $fieldmap[$fieldname]['other']=$arow['other']; + $fieldmap[$fieldname]['help']=$arow['help']; + } + if (isset($fieldmap)) { + $globalfieldmap[$surveyid][$style][$clang->langcode] = $fieldmap; + $_SESSION['fieldmap-' . $surveyid . $clang->langcode]=$fieldmap; + 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, $globalfieldmap, $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; + $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='en'; + } + $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']; + } + + if (!isset($language) || ($language=='') || (isset($additional_languages) && strpos($additional_languages, $language) === false) + or (isset($default_language) && $default_language == $language) + ) { + // Language not supported, or default language for survey, fall back to survey's default language + $_SESSION['s_lang'] = $default_language; + //echo "Language not supported, resorting to ".$_SESSION['s_lang']."
      "; + } else { + $_SESSION['s_lang'] = $language; + //echo "Language will be set to ".$_SESSION['s_lang']."
      "; + } + $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"=>"!LOWZ", + '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 of a Multiple choice question 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 of a Multiple choice question to exclude the matching answer options in this question."), + "caption"=>$clang->gT('Array filter exclusion')); + + $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')); + // Question types 'W' (list-dropdown-flexible) and 'Z'(list-radio-flexible) are no longer supported, so neither is code_filter + // $qattributes["code_filter"]=array( + // "types"=>"WZ", + // 'category'=>$clang->gT('Logic'), + // 'sortorder'=>100, + // 'inputtype'=>'text', + // "help"=>$clang->gT('Filter the available answers by this value'), + // "caption"=>$clang->gT('Code filter')); + + $qattributes["display_columns"]=array( + "types"=>"GLMZ", + '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"=>";:STUNKQ", + '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"=>";:STUNKQ", + '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"=>";:KQ", + '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"=>";:KQ", + '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"=>"MP", + '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"=>"M", + '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"=>"!KLMNOPRSWZ", + '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'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', + '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["max_num_value_sgqa"]=array( + // "types"=>"K", + // 'category'=>$clang->gT('Logic'), + // 'sortorder'=>100, + // 'inputtype'=>'text', + // "help"=>$clang->gT('Enter the SGQA identifier to use the total of a previous question as the maximum for this question'), + // "caption"=>$clang->gT('Max value from SGQA')); + + $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["min_num_value_sgqa"]=array( + // "types"=>"K", + // 'category'=>$clang->gT('Logic'), + // 'sortorder'=>100, + // 'inputtype'=>'text', + // "help"=>$clang->gT('Enter the SGQA identifier to use the total of a previous question as the minimum for this question'), + // "caption"=>$clang->gT('Minimum value from SGQA')); + + $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_equals_sgqa"]=array( + // "types"=>"K", + // 'category'=>$clang->gT('Logic'), + // 'sortorder'=>100, + // 'inputtype'=>'text', + // "help"=>$clang->gT('SGQA identifier to use total of previous question as total for this question'), + // "caption"=>$clang->gT('Value equals SGQA')); + + $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"=>"PLW!Z", + '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"=>"LMPWZ!", + '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"=>"15ABCDEFGHKLMNOPQRSTUWXYZ!:;|*", + '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"=>"15ABCEFGHKLMNOPRWYZ!:*", + '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"=>"!ABCEFHKLMOPQRWZ1:;", + '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['relevance']=array( + // 'types'=>'15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|*', + // 'category'=>$clang->gT('Display'), + // 'sortorder'=>1, + // 'inputtype'=>'text', + // 'default'=>'1', + // 'help'=>$clang->gT('The Relevance Equation determines whether a question should be shown (if true) or hiddden and marked as Not Applicable (if false).' + // . ' The Relevance equation can be as complex as you like, using any combination of mathematical operators, nested parentheses,' + // . ' any variable or token that has already been set, and any of more than 50 functions. It is parsed by the ExpressionManager.'), + // 'caption'=>$clang->gT('Relevance Equation')); + + $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 - like 3)'), + ), + 'default'=>0, + "help"=>$clang->gT('Accelerator keys for list items'), + "caption"=>$clang->gT('Prefix for list items')); + + $qattributes["scale_export"]=array( + "types"=>"CEFGHLMOPWYZ1!:*", + '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"=>"integer", + '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"=>"integer", + '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"=>"15ABCDEFGHIKLMNOPQRSTUWXYZ!:;|", + '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 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; +} + +if (!function_exists('get_magic_quotes_gpc')) { + /** + * Gets the current configuration setting of magic_quotes_gpc + * NOTE: Compat variant for PHP 6+ versions + * + * @link http://www.php.net/manual/en/function.get-magic-quotes-gpc.php + * @return int 0 if magic_quotes_gpc is off, 1 otherwise. + */ + function get_magic_quotes_gpc() { + return 0; + } +} + +// 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; + if (!get_magic_quotes_gpc()) { + return $connect->escape($str); + } + return $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;}; + if (!get_magic_quotes_gpc()) { + return $str; + } + return stripslashes($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); + + 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"; + } + + + if ( !$embedded ) + { + $header= "\n" + . "\n" + . "\n" + . "" + . "" + . $js_header; + + if ($meta) + $header .= $meta; + + return $header; + } + else + { + global $embedded_headerfunc; + if ( function_exists( $embedded_headerfunc ) ) + return $embedded_headerfunc(); + } +} + +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\n\n"; + } + else + { + global $embedded_footerfunc; + if ( function_exists( $embedded_footerfunc ) ) + return $embedded_footerfunc(); + } +} + + +function doFooter() +{ + echo getFooter(); +} + + + +// This function replaces field names in a text with the related values +// (e.g. for email and template functions) +function ReplaceFields ($text,$fieldsarray, $bReplaceInsertans=true) +{ + + if ($bReplaceInsertans) + { + $replacements = array(); + foreach ( $fieldsarray as $key => $value ) + { + $replacements[substr($key,1,-1)] = $value; + } + $text = LimeExpressionManager::ProcessString($text, NULL, $replacements, false, 2, 1); + } + else + { + foreach ( $fieldsarray as $key => $value ) + { + $text=str_replace($key, $value, $text); + } + } + return $text; +} + + +/** +* This function mails a text $body to the recipient $to. +* You can use more than one recipient when using a semikolon separated string with recipients. +* If you send several emails at once please supply an email object so that it can be re-used over and over. Especially with SMTP connections this speeds up things by 200%. +* If you supply an email object Do not forget to close the mail connection by calling $mail->SMTPClose(); +* +* @param mixed $mail This is an PHPMailer object. If null, one will be created automatically and unset afterwards. If supplied it won't be unset. +* @param string $body Body text of the email in plain text or HTML +* @param mixed $subject Email subject +* @param mixed $to Array with several email addresses or single string with one email address +* @param mixed $from +* @param mixed $sitename +* @param mixed $ishtml +* @param mixed $bouncemail +* @param mixed $attachment +* @return bool If successful returns true +*/ +function SendEmailMessage($mail, $body, $subject, $to, $from, $sitename, $ishtml=false, $bouncemail=null, $attachment=null, $customheaders="") +{ + + global $emailmethod, $emailsmtphost, $emailsmtpuser, $emailsmtppassword, $defaultlang, $emailsmtpdebug; + global $rootdir, $maildebug, $maildebugbody, $emailsmtpssl, $clang, $demoModeOnly, $emailcharset; + if (!is_array($to)){ + $to=array($to); + } + if (!is_array($customheaders) && $customheaders == '') + { + $customheaders=array(); + } + if ($demoModeOnly==true) + { + $maildebug=$clang->gT('Email was not sent because demo-mode is activated.'); + $maildebugbody=''; + return false; + } + + if (is_null($bouncemail) ) + { + $sender=$from; + } + else + { + $sender=$bouncemail; + } + $bUnsetEmail=false; + if (is_null($mail)) + { + $bUnsetEmail=true; + $mail = new PHPMailer; + } + else + { + $mail->SMTPKeepAlive=true; + } + + if (!$mail->SetLanguage($defaultlang,$rootdir.'/classes/phpmailer/language/')) + { + $mail->SetLanguage('en',$rootdir.'/classes/phpmailer/language/'); + } + $mail->CharSet = $emailcharset; + if (isset($emailsmtpssl) && trim($emailsmtpssl)!=='' && $emailsmtpssl!==0) { + if ($emailsmtpssl===1) {$mail->SMTPSecure = "ssl";} + else {$mail->SMTPSecure = $emailsmtpssl;} + } + + $fromname=''; + $fromemail=$from; + if (strpos($from,'<')) + { + $fromemail=substr($from,strpos($from,'<')+1,strpos($from,'>')-1-strpos($from,'<')); + $fromname=trim(substr($from,0, strpos($from,'<')-1)); + } + + $sendername=''; + $senderemail=$sender; + if (strpos($sender,'<')) + { + $senderemail=substr($sender,strpos($sender,'<')+1,strpos($sender,'>')-1-strpos($sender,'<')); + $sendername=trim(substr($sender,0, strpos($sender,'<')-1)); + } + + switch ($emailmethod) { + case "qmail": + $mail->IsQmail(); + break; + case "smtp": + $mail->IsSMTP(); + if ($emailsmtpdebug>0) + { + $mail->SMTPDebug = $emailsmtpdebug; + } + if (strpos($emailsmtphost,':')>0) + { + $mail->Host = substr($emailsmtphost,0,strpos($emailsmtphost,':')); + $mail->Port = substr($emailsmtphost,strpos($emailsmtphost,':')+1); + } + else { + $mail->Host = $emailsmtphost; + } + $mail->Username =$emailsmtpuser; + $mail->Password =$emailsmtppassword; + if (trim($emailsmtpuser)!="") + { + $mail->SMTPAuth = true; + } + break; + case "sendmail": + $mail->IsSendmail(); + break; + default: + //Set to the default value to rule out incorrect settings. + $emailmethod="mail"; + $mail->IsMail(); + } + + $mail->SetFrom($fromemail, $fromname); + $mail->Sender = $senderemail; // Sets Return-Path for error notifications + foreach ($to as $singletoemail) + { + if (strpos($singletoemail, '<') ) + { + $toemail=substr($singletoemail,strpos($singletoemail,'<')+1,strpos($singletoemail,'>')-1-strpos($singletoemail,'<')); + $toname=trim(substr($singletoemail,0, strpos($singletoemail,'<')-1)); + $mail->AddAddress($toemail,$toname); + } + else + { + $mail->AddAddress($singletoemail); + } + } + if (is_array($customheaders)) + { + foreach ($customheaders as $key=>$val) { + $mail->AddCustomHeader($val); + } + } + $mail->AddCustomHeader("X-Surveymailer: $sitename Emailer (LimeSurvey.sourceforge.net)"); + if (get_magic_quotes_gpc() != "0") {$body = stripcslashes($body);} + if ($ishtml) { + $mail->IsHTML(true); + $mail->Body = $body; + $mail->AltBody = trim(strip_tags(html_entity_decode($body,ENT_QUOTES,'UTF-8'))); + } else + { + $mail->IsHTML(false); + $mail->Body = $body; + } + + // add the attachment if there is one + if(!is_null($attachment)) + $mail->AddAttachment($attachment); + + if (trim($subject)!='') {$mail->Subject = "=?$emailcharset?B?" . base64_encode($subject) . "?=";} + if ($emailsmtpdebug>0) { + ob_start(); + } + $sent=$mail->Send(); + $maildebug=$mail->ErrorInfo; + if ($emailsmtpdebug>0) { + $maildebug .= '
    • '.$clang->gT('SMTP debug output:').'
    • '.strip_tags(ob_get_contents()).'
      '; + ob_end_clean(); + } + $maildebugbody=$mail->Body; + $mail->ClearAddresses(); + $mail->ClearCustomHeaders(); + if ($bUnsetEmail) + { + unset($mail); + } + return $sent; +} + + + +/** +* This functions removes all HTML tags, Javascript, CRs, linefeeds and other strange chars from a given text. CRs, linefeeds are not removed for .csv files +* +* @param string $sTextToFlatten Text you want to clean +* @param boolan $bDecodeHTMLEntities If set to true then all HTML entities will be decoded to the specified charset. Default: false +* @param string $sCharset Charset to decode to if $decodeHTMLEntities is set to true +* +* @return string Cleaned text +*/ +function FlattenText($sTextToFlatten, $bDecodeHTMLEntities=false, $sCharset='UTF-8', $bStripNewLines=true) +{ + $sNicetext = strip_javascript($sTextToFlatten); + $sNicetext = strip_tags($sNicetext); + + if ($bStripNewLines ){ + $sNicetext = preg_replace('~\Ru~', '', $sNicetext); + } + else // unify newlines + { + $sNicetext = preg_replace('~\Ru~', "\r\n", $sNicetext); + } + if ($bDecodeHTMLEntities==true) + { + $sNicetext = str_replace(' ',' ', $sNicetext); // html_entity_decode does not convert   to spaces + $sNicetext = html_entity_decode($sNicetext, ENT_QUOTES, $sCharset); + } + return trim($sNicetext); ; +} + +/** +* getGroupsByQuestion($surveyid) +* @global string $surveyid +* @return returns a keyed array of groups to questions ie: array([1]=>[2]) question qid 1, is in group gid 2. +*/ +function getGroupsByQuestion($surveyid) { + global $surveyid, $dbprefix; + + $output=array(); + + $surveyid=sanitize_int($surveyid); + $query="SELECT qid, gid FROM ".db_table_name('questions')." WHERE sid='$surveyid'"; + $result = db_execute_assoc($query); + while ($val = $result->FetchRow()) + { + $output[$val['qid']]=$val['gid']; + } + return $output; +} + +/** +* Run an arbitrary sequence of semicolon-delimited SQL commands +* +* Assumes that the input text (file or string) consists of +* a number of SQL statements ENDING WITH SEMICOLONS. The +* semicolons MUST be the last character in a line. +* Lines that are blank or that start with "#" or "--" (postgres) are ignored. +* Only tested with mysql dump files (mysqldump -p -d limesurvey) +* Function kindly borrowed by Moodle +* @uses $dbprefix +* @param string $sqlfile The path where a file with sql commands can be found on the server. +* @param string $sqlstring If no path is supplied then a string with semicolon delimited sql +* commands can be supplied in this argument. +* @return bool Returns true if database was modified successfully. +*/ +function modify_database($sqlfile='', $sqlstring='') +{ + global $dbprefix; + global $defaultuser; + global $defaultpass; + global $siteadminemail; + global $siteadminname; + global $defaultlang; + global $codeString; + global $rootdir, $homedir; + global $connect; + global $clang; + global $modifyoutput; + global $databasetabletype; + + require_once($homedir."/classes/core/sha256.php"); + + $success = true; // Let's be optimistic + $modifyoutput=''; + + if (!empty($sqlfile)) { + if (!is_readable($sqlfile)) { + $success = false; + echo '

      Tried to modify database, but "'. $sqlfile .'" doesn\'t exist!

      '; + return $success; + } else { + $lines = file($sqlfile); + } + } else { + $sqlstring = trim($sqlstring); + if ($sqlstring{strlen($sqlstring)-1} != ";") { + $sqlstring .= ";"; // add it in if it's not there. + } + $lines[] = $sqlstring; + } + + $command = ''; + + foreach ($lines as $line) { + $line = rtrim($line); + $length = strlen($line); + + if ($length and $line[0] <> '#' and substr($line,0,2) <> '--') { + if (substr($line, $length-1, 1) == ';') { + $line = substr($line, 0, $length-1); // strip ; + $command .= $line; + $command = str_replace('prefix_', $dbprefix, $command); // Table prefixes + $command = str_replace('$defaultuser', $defaultuser, $command); + $command = str_replace('$defaultpass', SHA256::hashing($defaultpass), $command); + $command = str_replace('$siteadminname', $siteadminname, $command); + $command = str_replace('$siteadminemail', $siteadminemail, $command); + $command = str_replace('$defaultlang', $defaultlang, $command); + $command = str_replace('$sessionname', 'ls'.sRandomChars(20,'123456789'), $command); + $command = str_replace('$databasetabletype', $databasetabletype, $command); + + if (! db_execute_num($command)) { //Checked + $command=htmlspecialchars($command); + $modifyoutput .="
      ".sprintf($clang->gT("SQL command failed: %s Reason: %s"),"".$command."","".$connect->ErrorMsg()."
      "); + $success = false; + } + else + { + $command=htmlspecialchars($command); + $modifyoutput .=". "; + } + + $command = ''; + } else { + $command .= $line; + } + } + } + + return $success; + +} + + + +// unsets all Session variables to kill session +function killSession() //added by Dennis +{ + // Delete the Session Cookie + $CookieInfo = session_get_cookie_params(); + if ( (empty($CookieInfo['domain'])) && (empty($CookieInfo['secure'])) ) { + setcookie(session_name(), '', time()-3600, $CookieInfo['path']); + } elseif (empty($CookieInfo['secure'])) { + setcookie(session_name(), '', time()-3600, $CookieInfo['path'], $CookieInfo['domain']); + } else { + setcookie(session_name(), '', time()-3600, $CookieInfo['path'], $CookieInfo['domain'], $CookieInfo['secure']); + } + unset($_COOKIE[session_name()]); + foreach ($_SESSION as $key =>$value) + { + //echo $key." = ".$value."
      "; + unset($_SESSION[$key]); + } + $_SESSION = array(); // redundant with previous lines + session_unset(); + @session_destroy(); +} + + + + + + + +// set the rights of a user and his children +function setuserrights($uid, $rights) +{ + global $connect; + $uid=sanitize_int($uid); + $updates = "create_survey=".$rights['create_survey'] + . ", create_user=".$rights['create_user'] + . ", delete_user=".$rights['delete_user'] + . ", superadmin=".$rights['superadmin'] + . ", configurator=".$rights['configurator'] + . ", manage_template=".$rights['manage_template'] + . ", manage_label=".$rights['manage_label']; + $uquery = "UPDATE ".db_table_name('users')." SET ".$updates." WHERE uid = ".$uid; + return $connect->Execute($uquery); //Checked +} + + +function createPassword() +{ + $pwchars = "abcdefhjmnpqrstuvwxyz23456789"; + $password_length = 8; + $passwd = ''; + + for ($i=0; $i<$password_length; $i++) + { + $passwd .= $pwchars[floor(rand(0,strlen($pwchars)-1))]; + } + return $passwd; +} + +function getgroupuserlist() +{ + global $ugid, $dbprefix, $scriptname, $connect, $clang; + + $ugid=sanitize_int($ugid); + $surveyidquery = "SELECT a.uid, a.users_name FROM ".db_table_name('users')." AS a LEFT JOIN (SELECT uid AS id FROM ".db_table_name('user_in_groups')." WHERE ugid = {$ugid}) AS b ON a.uid = b.id WHERE id IS NULL ORDER BY a.users_name"; + + $surveyidresult = db_execute_assoc($surveyidquery); //Checked + if (!$surveyidresult) {return "Database Error";} + $surveyselecter = ""; + $surveynames = $surveyidresult->GetRows(); + if ($surveynames) + { + foreach($surveynames as $sv) + { + $surveyselecter .= "gT("Please choose...")."\n".$surveyselecter; + return $surveyselecter; +} + +/** +* Retrieve a HTML \n".$surveyselecter;} + else {$surveyselecter = "\n".$surveyselecter;} + return $surveyselecter; +} + +function getsurveyusergrouplist($outputformat='htmloptions') +{ + global $surveyid, $dbprefix, $scriptname, $connect, $clang, $usercontrolSameGroupPolicy; + $surveyid=sanitize_int($surveyid); + + $surveyidquery = "SELECT a.ugid, a.name, MAX(d.ugid) AS da FROM ".db_table_name('user_groups')." AS a LEFT JOIN (SELECT b.ugid FROM ".db_table_name('user_in_groups')." AS b LEFT JOIN (SELECT * FROM ".db_table_name('survey_permissions')." WHERE sid = {$surveyid}) AS c ON b.uid = c.uid WHERE c.uid IS NULL) AS d ON a.ugid = d.ugid GROUP BY a.ugid, a.name HAVING MAX(d.ugid) IS NOT NULL"; + $surveyidresult = db_execute_assoc($surveyidquery); //Checked + if (!$surveyidresult) {return "Database Error";} + $surveyselecter = ""; + $surveynames = $surveyidresult->GetRows(); + + if (isset($usercontrolSameGroupPolicy) && + $usercontrolSameGroupPolicy == true) + { + $authorizedGroupsList=getusergrouplist('simplegidarray'); + } + + if ($surveynames) + { + foreach($surveynames as $sv) + { + if (!isset($usercontrolSameGroupPolicy) || + $usercontrolSameGroupPolicy == false || + in_array($sv['ugid'],$authorizedGroupsList)) + { + $surveyselecter .= "gT("Please choose...")."\n".$surveyselecter;} + else {$surveyselecter = "\n".$surveyselecter;} + + if ($outputformat == 'simpleugidarray') + { + return $simpleugidarray; + } + else + { + return $surveyselecter; + } +} + +function getusergrouplist($outputformat='optionlist') +{ + global $dbprefix, $scriptname, $connect, $clang; + + //$squery = "SELECT ugid, name FROM ".db_table_name('user_groups') ." WHERE owner_id = {$_SESSION['loginID']} ORDER BY name"; + $squery = "SELECT a.ugid, a.name, a.owner_id, b.uid FROM ".db_table_name('user_groups') ." AS a LEFT JOIN ".db_table_name('user_in_groups') ." AS b ON a.ugid = b.ugid WHERE uid = {$_SESSION['loginID']} ORDER BY name"; + + $sresult = db_execute_assoc($squery); //Checked + if (!$sresult) {return "Database Error";} + $selecter = ""; + $groupnames = $sresult->GetRows(); + $simplegidarray=array(); + if ($groupnames) + { + foreach($groupnames as $gn) + { + $selecter .= "\n".$selecter;} + //else {$selecter = "\n".$selecter;} + + if ($outputformat == 'simplegidarray') + { + return $simplegidarray; + } + else + { + return $selecter; + } +} + + +function languageDropdown($surveyid,$selected) +{ + global $homeurl; + $slangs = GetAdditionalLanguagesFromSurveyID($surveyid); + $baselang = GetBaseLanguageFromSurveyID($surveyid); + array_unshift($slangs,$baselang); + $html = ""; + return $html; +} + +function languageDropdownClean($surveyid,$selected) +{ + $slangs = GetAdditionalLanguagesFromSurveyID($surveyid); + $baselang = GetBaseLanguageFromSurveyID($surveyid); + array_unshift($slangs,$baselang); + $html = ""; + return $html; +} + +function BuildCSVFromQuery($Query) +{ + global $dbprefix, $connect; + $QueryResult = db_execute_assoc($Query) or safe_die ("ERROR: $QueryResult
      ".$connect->ErrorMsg()); //safe + preg_match('/FROM (\w+)( |,)/i', $Query, $MatchResults); + $TableName = $MatchResults[1];; + if ($dbprefix) + { + $TableName = substr($TableName, strlen($dbprefix), strlen($TableName)); + } + $Output = "\n#\n# " . strtoupper($TableName) . " TABLE\n#\n"; + $HeaderDone = false; $ColumnNames = ""; + while ($Row = $QueryResult->FetchRow()) + { + + if (!$HeaderDone) + { + foreach ($Row as $Key=>$Value) + { + $ColumnNames .= CSVEscape($Key).","; //Add all the column names together + } + $ColumnNames = substr($ColumnNames, 0, -1); //strip off last comma space + $Output .= "$ColumnNames\n"; + $HeaderDone=true; + } + $ColumnValues = ""; + foreach ($Row as $Key=>$Value) + { + $Value=str_replace("\r\n", "\n", $Value); + $Value=str_replace("\r", "\n", $Value); + $ColumnValues .= CSVEscape($Value) . ","; + } + $ColumnValues = substr($ColumnValues, 0, -1); //strip off last comma space + $Output .= str_replace("\n","\\n","$ColumnValues")."\n"; + } + return $Output; +} + +function CSVEscape($str) +{ + $str= str_replace('\n','\%n',$str); + return '"' . str_replace('"','""', $str) . '"'; +} + +function convertCSVRowToArray($string, $seperator, $quotechar) +{ + $fields=preg_split('/' . $seperator . '(?=([^"]*"[^"]*")*(?![^"]*"))/',trim($string)); + $fields=array_map('CSVUnquote',$fields); + return $fields; +} + + +/** +* This function removes surrounding and masking quotes from the CSV field +* +* @param mixed $field +* @return mixed +*/ +function CSVUnquote($field) +{ + //print $field.":"; + $field = preg_replace ("/^\040*\"/", "", $field); + $field = preg_replace ("/\"\040*$/", "", $field); + $field= str_replace('""','"',$field); + //print $field."\n"; + return $field; +} + +/** +* CleanLanguagesFromSurvey() removes any languages from survey tables that are not in the passed list +* @param string $sid - the currently selected survey +* @param string $availlangs - space seperated list of additional languages in survey +* @return bool - always returns true +*/ +function CleanLanguagesFromSurvey($sid, $availlangs) +{ + global $connect; + $sid=sanitize_int($sid); + $baselang = GetBaseLanguageFromSurveyID($sid); + + if (!empty($availlangs) && $availlangs != " ") + { + $availlangs=sanitize_languagecodeS($availlangs); + $langs = explode(" ",$availlangs); + if($langs[count($langs)-1] == "") array_pop($langs); + } + + $sqllang = "language <> '".$baselang."' ";; + + if (!empty($availlangs) && $availlangs != " ") + { + foreach ($langs as $lang) + { + $sqllang .= "and language <> '".$lang."' "; + } + } + + // Remove From Answers Table + $query = "SELECT qid FROM ".db_table_name('questions')." WHERE sid='{$sid}' and ($sqllang)"; + $qidresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + while ($qrow = $qidresult->FetchRow()) + { + $myqid = $qrow['qid']; + $query = "DELETE FROM ".db_table_name('answers')." WHERE qid='$myqid' and ($sqllang)"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + } + + // Remove From Questions Table + $query = "DELETE FROM ".db_table_name('questions')." WHERE sid='{$sid}' and ($sqllang)"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + + // Remove From Groups Table + $query = "DELETE FROM ".db_table_name('groups')." WHERE sid='{$sid}' and ($sqllang)"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + + return true; +} + +/** +* FixLanguageConsistency() fixes missing groups,questions,answers & assessments for languages on a survey +* @param string $sid - the currently selected survey +* @param string $availlangs - space seperated list of additional languages in survey - if empty all additional languages of a survey are checked against the base language +* @return bool - always returns true +*/ +function FixLanguageConsistency($sid, $availlangs='') +{ + global $connect, $databasetype; + + if (trim($availlangs)!='') + { + $availlangs=sanitize_languagecodeS($availlangs); + $langs = explode(" ",$availlangs); + if($langs[count($langs)-1] == "") array_pop($langs); + } else { + $langs=GetAdditionalLanguagesFromSurveyID($sid); + } + + $baselang = GetBaseLanguageFromSurveyID($sid); + $sid=sanitize_int($sid); + $query = "SELECT * FROM ".db_table_name('groups')." WHERE sid='{$sid}' AND language='{$baselang}' ORDER BY group_order"; + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($result->RecordCount() > 0) + { + while($group = $result->FetchRow()) + { + foreach ($langs as $lang) + { + $query = "SELECT gid FROM ".db_table_name('groups')." WHERE sid='{$sid}' AND gid='{$group['gid']}' AND language='{$lang}'"; + $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($gresult->RecordCount() < 1) + { + db_switchIDInsert('groups',true); + $query = "INSERT INTO ".db_table_name('groups')." (gid,sid,group_name,group_order,description,grelevance,language) VALUES('{$group['gid']}','{$group['sid']}',".db_quoteall($group['group_name']).",'{$group['group_order']}',".db_quoteall($group['description']).",'".db_quote($group['grelevance'])."','{$lang}')"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + db_switchIDInsert('groups',false); + } + } + reset($langs); + } + } + + $quests = array(); + $query = "SELECT * FROM ".db_table_name('questions')." WHERE sid='{$sid}' AND language='{$baselang}' ORDER BY question_order"; + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($result->RecordCount() > 0) + { + while($question = $result->FetchRow()) + { + array_push($quests,$question['qid']); + foreach ($langs as $lang) + { + $query = "SELECT qid FROM ".db_table_name('questions')." WHERE sid='{$sid}' AND qid='{$question['qid']}' AND language='{$lang}' AND scale_id={$question['scale_id']}"; + $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($gresult->RecordCount() < 1) + { + db_switchIDInsert('questions',true); + $query = "INSERT INTO ".db_table_name('questions')." (qid,sid,gid,type,title,question,preg,help,other,mandatory,question_order,language, scale_id,parent_qid, relevance) VALUES('{$question['qid']}','{$question['sid']}','{$question['gid']}','{$question['type']}',".db_quoteall($question['title']).",".db_quoteall($question['question']).",".db_quoteall($question['preg']).",".db_quoteall($question['help']).",'{$question['other']}','{$question['mandatory']}','{$question['question_order']}','{$lang}',{$question['scale_id']},{$question['parent_qid']}, '{$question['relevance']}')"; + $connect->Execute($query) or safe_die($query."
      ".$connect->ErrorMsg()); //Checked + db_switchIDInsert('questions',false); + } + } + reset($langs); + } + + $sqlans = ""; + foreach ($quests as $quest) + { + $sqlans .= " OR qid = '".$quest."' "; + } + + $query = "SELECT * FROM ".db_table_name('answers')." WHERE language='{$baselang}' and (".trim($sqlans,' OR').") ORDER BY qid, code"; + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($result->RecordCount() > 0) + { + while($answer = $result->FetchRow()) + { + foreach ($langs as $lang) + { + $query = "SELECT qid FROM ".db_table_name('answers')." WHERE code='{$answer['code']}' AND qid='{$answer['qid']}' AND language='{$lang}' AND scale_id={$answer['scale_id']}"; + $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($gresult->RecordCount() < 1) + { + db_switchIDInsert('answers',true); + $query = "INSERT INTO ".db_table_name('answers')." (qid,code,answer,scale_id,sortorder,language,assessment_value) VALUES('{$answer['qid']}',".db_quoteall($answer['code']).",".db_quoteall($answer['answer']).",{$answer['scale_id']},'{$answer['sortorder']}','{$lang}',{$answer['assessment_value']})"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + db_switchIDInsert('answers',false); + } + } + reset($langs); + } + } + } + + + $query = "SELECT * FROM ".db_table_name('assessments')." WHERE sid='{$sid}' AND language='{$baselang}'"; + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($result->RecordCount() > 0) + { + while($assessment = $result->FetchRow()) + { + foreach ($langs as $lang) + { + $query = "SELECT id FROM ".db_table_name('assessments')." WHERE sid='{$sid}' AND id='{$assessment['id']}' AND language='{$lang}'"; + $gresult = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + if ($gresult->RecordCount() < 1) + { + db_switchIDInsert('assessments',true); + $query = "INSERT INTO ".db_table_name('assessments')." (id,sid,scope,gid,name,minimum,maximum,message,language) " + ."VALUES('{$assessment['id']}','{$assessment['sid']}',".db_quoteall($assessment['scope']).",".db_quoteall($assessment['gid']).",".db_quoteall($assessment['name']).",".db_quoteall($assessment['minimum']).",".db_quoteall($assessment['maximum']).",".db_quoteall($assessment['message']).",'{$lang}')"; + $connect->Execute($query) or safe_die($connect->ErrorMsg()); //Checked + db_switchIDInsert('assessments',false); + } + } + reset($langs); + } + } + + + + return true; +} + +///** +//* GetGroupDepsForConditions() get Dependencies between groups caused by conditions +//* @param string $sid - the currently selected survey +//* @param string $depgid - (optionnal) get only the dependencies applying to the group with gid depgid +//* @param string $targgid - (optionnal) get only the dependencies for groups dependents on group targgid +//* @param string $index-by - (optionnal) "by-depgid" for result indexed with $res[$depgid][$targgid] +//* "by-targgid" for result indexed with $res[$targgid][$depgid] +//* @return array - returns an array describing the conditions or NULL if no dependecy is found +//* +//* Example outupt assumin $index-by="by-depgid": +//*Array +//*( +//* [125] => Array // Group Id 125 is dependent on +//* ( +//* [123] => Array // Group Id 123 +//* ( +//* [depgpname] => G3 // GID-125 has name G3 +//* [targetgpname] => G1 // GID-123 has name G1 +//* [conditions] => Array +//* ( +//* [189] => Array // Because Question Id 189 +//* ( +//* [0] => 9 // Have condition 9 set +//* [1] => 10 // and condition 10 set +//* [2] => 14 // and condition 14 set +//* ) +//* +//* ) +//* +//* ) +//* +//* [124] => Array // GID 125 is also dependent on GID 124 +//* ( +//* [depgpname] => G3 +//* [targetgpname] => G2 +//* [conditions] => Array +//* ( +//* [189] => Array // Because Question Id 189 have conditions set +//* ( +//* [0] => 11 +//* ) +//* +//* [215] => Array // And because Question Id 215 have conditions set +//* ( +//* [0] => 12 +//* ) +//* +//* ) +//* +//* ) +//* +//* ) +//* +//*) +//* +//* Usage example: +//* * Get all group dependencies for SID $sid indexed by depgid: +//* $result=GetGroupDepsForConditions($sid); +//* * Get all group dependencies for GID $gid in survey $sid indexed by depgid: +//* $result=GetGroupDepsForConditions($sid,$gid); +//* * Get all group dependents on group $gid in survey $sid indexed by targgid: +//* $result=GetGroupDepsForConditions($sid,"all",$gid,"by-targgid"); +//*/ +//function GetGroupDepsForConditions($sid,$depgid="all",$targgid="all",$indexby="by-depgid") +//{ +// global $connect, $clang; +// $sid=sanitize_int($sid); +// $condarray = Array(); +// +// $sqldepgid=""; +// $sqltarggid=""; +// if ($depgid != "all") { $depgid = sanitize_int($depgid); $sqldepgid="AND tq.gid=$depgid";} +// if ($targgid != "all") {$targgid = sanitize_int($targgid); $sqltarggid="AND tq2.gid=$targgid";} +// +// $baselang = GetBaseLanguageFromSurveyID($sid); +// $condquery = "SELECT tg.gid as depgid, tg.group_name as depgpname, " +// . "tg2.gid as targgid, tg2.group_name as targgpname, tq.qid as depqid, tc.cid FROM " +// . db_table_name('conditions')." AS tc, " +// . db_table_name('questions')." AS tq, " +// . db_table_name('questions')." AS tq2, " +// . db_table_name('groups')." AS tg ," +// . db_table_name('groups')." AS tg2 " +// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tg.language='{$baselang}' AND tg2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " +// . "AND tq.gid = tg.gid AND tg2.gid = tq2.gid " +// . "AND tq2.qid=tc.cqid AND tq.gid != tg2.gid $sqldepgid $sqltarggid"; +// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked +// +// if ($condresult->RecordCount() > 0) { +// while ($condrow = $condresult->FetchRow()) +// { +// +// switch ($indexby) +// { +// case "by-depgid": +// $depgid=$condrow['depgid']; +// $targetgid=$condrow['targgid']; +// $depqid=$condrow['depqid']; +// $cid=$condrow['cid']; +// $condarray[$depgid][$targetgid]['depgpname'] = $condrow['depgpname']; +// $condarray[$depgid][$targetgid]['targetgpname'] = $condrow['targgpname']; +// $condarray[$depgid][$targetgid]['conditions'][$depqid][]=$cid; +// break; +// +// case "by-targgid": +// $depgid=$condrow['depgid']; +// $targetgid=$condrow['targgid']; +// $depqid=$condrow['depqid']; +// $cid=$condrow['cid']; +// $condarray[$targetgid][$depgid]['depgpname'] = $condrow['depgpname']; +// $condarray[$targetgid][$depgid]['targetgpname'] = $condrow['targgpname']; +// $condarray[$targetgid][$depgid]['conditions'][$depqid][] = $cid; +// break; +// } +// } +// return $condarray; +// } +// return null; +//} + +///** +//* GetQuestDepsForConditions() get Dependencies between groups caused by conditions +//* @param string $sid - the currently selected survey +//* @param string $gid - (optionnal) only search dependecies inside the Group Id $gid +//* @param string $depqid - (optionnal) get only the dependencies applying to the question with qid depqid +//* @param string $targqid - (optionnal) get only the dependencies for questions dependents on question Id targqid +//* @param string $index-by - (optionnal) "by-depqid" for result indexed with $res[$depqid][$targqid] +//* "by-targqid" for result indexed with $res[$targqid][$depqid] +//* @return array - returns an array describing the conditions or NULL if no dependecy is found +//* +//* Example outupt assumin $index-by="by-depqid": +//*Array +//*( +//* [184] => Array // Question Id 184 +//* ( +//* [183] => Array // Depends on Question Id 183 +//* ( +//* [0] => 5 // Because of condition Id 5 +//* ) +//* +//* ) +//* +//*) +//* +//* Usage example: +//* * Get all questions dependencies for Survey $sid and group $gid indexed by depqid: +//* $result=GetQuestDepsForConditions($sid,$gid); +//* * Get all questions dependencies for question $qid in survey/group $sid/$gid indexed by depqid: +//* $result=GetGroupDepsForConditions($sid,$gid,$qid); +//* * Get all questions dependents on question $qid in survey/group $sid/$gid indexed by targqid: +//* $result=GetGroupDepsForConditions($sid,$gid,"all",$qid,"by-targgid"); +//*/ +//function GetQuestDepsForConditions($sid,$gid="all",$depqid="all",$targqid="all",$indexby="by-depqid", $searchscope="samegroup") +//{ +// global $connect, $clang; +// $condarray = Array(); +// +// $baselang = GetBaseLanguageFromSurveyID($sid); +// $sqlgid=""; +// $sqldepqid=""; +// $sqltargqid=""; +// $sqlsearchscope=""; +// if ($gid != "all") {$gid = sanitize_int($gid); $sqlgid="AND tq.gid=$gid";} +// if ($depqid != "all") {$depqid = sanitize_int($depqid); $sqldepqid="AND tq.qid=$depqid";} +// if ($targqid != "all") {$targqid = sanitize_int($targqid); $sqltargqid="AND tq2.qid=$targqid";} +// if ($searchscope == "samegroup") {$sqlsearchscope="AND tq2.gid=tq.gid";} +// +// $condquery = "SELECT tq.qid as depqid, tq2.qid as targqid, tc.cid FROM " +// . db_table_name('conditions')." AS tc, " +// . db_table_name('questions')." AS tq, " +// . db_table_name('questions')." AS tq2 " +// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " +// . "AND tq2.qid=tc.cqid $sqlsearchscope $sqlgid $sqldepqid $sqltargqid"; +// +// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked +// +// if ($condresult->RecordCount() > 0) { +// while ($condrow = $condresult->FetchRow()) +// { +// $depqid=$condrow['depqid']; +// $targetqid=$condrow['targqid']; +// $condid=$condrow['cid']; +// switch ($indexby) +// { +// case "by-depqid": +// $condarray[$depqid][$targetqid][] = $condid; +// break; +// +// case "by-targqid": +// $condarray[$targetqid][$depqid][] = $condid; +// break; +// } +// } +// return $condarray; +// } +// return null; +//} + + +///** +//* checkMovequestionConstraintsForConditions() +//* @param string $sid - the currently selected survey +//* @param string $qid - qid of the question you want to check possible moves +//* @param string $newgid - (optionnal) get only constraints when trying to move to this particular GroupId +//* otherwise, get all moves constraints for this question +//* +//* @return array - returns an array describing the conditions +//* Array +//* ( +//* ['notAbove'] = null | Array +//* ( +//* Array ( gid1, group_order1, qid1, cid1 ) +//* ) +//* ['notBelow'] = null | Array +//* ( +//* Array ( gid2, group_order2, qid2, cid2 ) +//* ) +//* ) +//* +//* This should be read as: +//* - this question can't be move above group gid1 in position group_order1 because of the condition cid1 on question qid1 +//* - this question can't be move below group gid2 in position group_order2 because of the condition cid2 on question qid2 +//* +//*/ +//function checkMovequestionConstraintsForConditions($sid,$qid,$newgid="all") +//{ +// global $connect; +// $resarray=Array(); +// $resarray['notAbove']=null; // defaults to no constraint +// $resarray['notBelow']=null; // defaults to no constraint +// $sid=sanitize_int($sid); +// $qid=sanitize_int($qid); +// +// if ($newgid != "all") +// { +// $newgid=sanitize_int($newgid); +// $newgorder=getGroupOrder($sid,$newgid); +// } +// else +// { +// $neworder=""; // Not used in this case +// } +// +// $baselang = GetBaseLanguageFromSurveyID($sid); +// +// // First look for 'my dependencies': questions on which I have set conditions +// $condquery = "SELECT tq.qid as depqid, tq.gid as depgid, tg.group_order as depgorder, " +// . "tq2.qid as targqid, tq2.gid as targgid, tg2.group_order as targgorder, " +// . "tc.cid FROM " +// . db_table_name('conditions')." AS tc, " +// . db_table_name('questions')." AS tq, " +// . db_table_name('questions')." AS tq2, " +// . db_table_name('groups')." AS tg, " +// . db_table_name('groups')." AS tg2 " +// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " +// . "AND tq2.qid=tc.cqid AND tg.gid=tq.gid AND tg2.gid=tq2.gid AND tq.qid=$qid ORDER BY tg2.group_order DESC"; +// +// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked +// +// if ($condresult->RecordCount() > 0) { +// +// while ($condrow = $condresult->FetchRow() ) +// { +// // This Question can go up to the minimum GID on the 1st row +// $depqid=$condrow['depqid']; +// $depgid=$condrow['depgid']; +// $depgorder=$condrow['depgorder']; +// $targetqid=$condrow['targqid']; +// $targetgid=$condrow['targgid']; +// $targetgorder=$condrow['targgorder']; +// $condid=$condrow['cid']; +// //echo "This question can't go above to GID=$targetgid/order=$targetgorder because of CID=$condid"; +// if ($newgid != "all") +// { // Get only constraints when trying to move to this group +// if ($newgorder < $targetgorder) +// { +// $resarray['notAbove'][]=Array($targetgid,$targetgorder,$depqid,$condid); +// } +// } +// else +// { // get all moves constraints +// $resarray['notAbove'][]=Array($targetgid,$targetgorder,$depqid,$condid); +// } +// } +// } +// +// // Secondly look for 'questions dependent on me': questions that have conditions on my answers +// $condquery = "SELECT tq.qid as depqid, tq.gid as depgid, tg.group_order as depgorder, " +// . "tq2.qid as targqid, tq2.gid as targgid, tg2.group_order as targgorder, " +// . "tc.cid FROM " +// . db_table_name('conditions')." AS tc, " +// . db_table_name('questions')." AS tq, " +// . db_table_name('questions')." AS tq2, " +// . db_table_name('groups')." AS tg, " +// . db_table_name('groups')." AS tg2 " +// . "WHERE tq.language='{$baselang}' AND tq2.language='{$baselang}' AND tc.qid = tq.qid AND tq.sid=$sid " +// . "AND tq2.qid=tc.cqid AND tg.gid=tq.gid AND tg2.gid=tq2.gid AND tq2.qid=$qid ORDER BY tg.group_order"; +// +// $condresult=db_execute_assoc($condquery) or safe_die($connect->ErrorMsg()); //Checked +// +// if ($condresult->RecordCount() > 0) { +// +// while ($condrow = $condresult->FetchRow()) +// { +// // This Question can go down to the maximum GID on the 1st row +// $depqid=$condrow['depqid']; +// $depgid=$condrow['depgid']; +// $depgorder=$condrow['depgorder']; +// $targetqid=$condrow['targqid']; +// $targetgid=$condrow['targgid']; +// $targetgorder=$condrow['targgorder']; +// $condid=$condrow['cid']; +// //echo "This question can't go below to GID=$depgid/order=$depgorder because of CID=$condid"; +// if ($newgid != "all") +// { // Get only constraints when trying to move to this group +// if ($newgorder > $depgorder) +// { +// $resarray['notBelow'][]=Array($depgid,$depgorder,$depqid,$condid); +// } +// } +// else +// { // get all moves constraints +// $resarray['notBelow'][]=Array($depgid,$depgorder,$depqid,$condid); +// } +// } +// } +// return $resarray; +//} + +function incompleteAnsFilterstate() +{ + global $filterout_incomplete_answers; + $letsfilter=''; + $letsfilter = returnglobal('filterinc'); //read get/post filterinc + + // first let's initialize the incompleteanswers session variable + if ($letsfilter != '') + { // use the read value if not empty + $_SESSION['incompleteanswers']=$letsfilter; + } + elseif (!isset($_SESSION['incompleteanswers'])) + { // sets default variable value from config file + $_SESSION['incompleteanswers'] = $filterout_incomplete_answers; + } + + if ($_SESSION['incompleteanswers']=='filter') { + return "filter"; //COMPLETE ANSWERS ONLY + } + elseif ($_SESSION['incompleteanswers']=='show') { + return false; //ALL ANSWERS + } + elseif ($_SESSION['incompleteanswers']=='incomplete') { + return "inc"; //INCOMPLETE ANSWERS ONLY + } + else + { // last resort is to prevent filtering + return false; + } +} + +/** +* captcha_enabled($screen, $usecaptchamode) +* @param string $screen - the screen name for which to test captcha activation +* +* @return boolean - returns true if captcha must be enabled +**/ +function captcha_enabled($screen, $captchamode='') +{ + switch($screen) + { + case 'registrationscreen': + if ($captchamode == 'A' || + $captchamode == 'B' || + $captchamode == 'D' || + $captchamode == 'R') + { + return true; + } + else + { + return false; + } + break; + case 'surveyaccessscreen': + if ($captchamode == 'A' || + $captchamode == 'B' || + $captchamode == 'C' || + $captchamode == 'X') + { + return true; + } + else + { + return false; + } + break; + case 'saveandloadscreen': + if ($captchamode == 'A' || + $captchamode == 'C' || + $captchamode == 'D' || + $captchamode == 'S') + { + return true; + } + else + { + return false; + } + return true; + break; + default: + return true; + break; + } +} + + +/** +* used for import[survey|questions|groups] +* +* @param mixed $string +* @return mixed +*/ +function convertCsvreturn2return($string) +{ + $string= str_replace('\n', "\n", $string); + return str_replace('\%n', '\n', $string); +} + + + +/** +* Checks that each object from an array of CSV data [question-rows,answer-rows,labelsets-row] supports at least a given language +* +* @param mixed $csvarray array with a line of csv data per row +* @param mixed $idkeysarray array of integers giving the csv-row numbers of the object keys +* @param mixed $langfieldnum integer giving the csv-row number of the language(s) filed +* ==> the language field can be a single language code or a +* space separated language code list +* @param mixed $langcode the language code to be tested +* @param mixed $hasheader if we should strip off the first line (if it contains headers) +*/ +function bDoesImportarraySupportsLanguage($csvarray,$idkeysarray,$langfieldnum,$langcode, $hasheader = false) +{ + // An array with one row per object id and langsupport status as value + $objlangsupportarray=Array(); + if ($hasheader === true) + { // stripping first row to skip headers if any + array_shift($csvarray); + } + + foreach ($csvarray as $csvrow) + { + $rowcontents = convertCSVRowToArray($csvrow,',','"'); + $rowid = ""; + foreach ($idkeysarray as $idfieldnum) + { + $rowid .= $rowcontents[$idfieldnum]."-"; + } + $rowlangarray = explode (" ", $rowcontents[$langfieldnum]); + if (!isset($objlangsupportarray[$rowid])) + { + if (array_search($langcode,$rowlangarray)!== false) + { + $objlangsupportarray[$rowid] = "true"; + } + else + { + $objlangsupportarray[$rowid] = "false"; + } + } + else + { + if ($objlangsupportarray[$rowid] == "false" && + array_search($langcode,$rowlangarray) !== false) + { + $objlangsupportarray[$rowid] = "true"; + } + } + } // end foreach rown + + // If any of the object doesn't support the given language, return false + if (array_search("false",$objlangsupportarray) === false) + { + return true; + } + else + { + return false; + } +} + +/** This function checks to see if there is an answer saved in the survey session +* data that matches the $code. If it does, it returns that data. +* It is used when building a questions text to allow incorporating the answer +* to an earlier question into the text of a later question. +* IE: Q1: What is your name? [Jason] +* Q2: Hi [Jason] how are you ? +* This function is called from the retriveAnswers function. +* +* @param mixed $code +* @param mixed $phpdateformat The date format in which any dates are shown +* @return mixed returns the answerText from session variable corresponding to a question code +*/ +function retrieve_Answer($code, $phpdateformat=null) +{ + //This function checks to see if there is an answer saved in the survey session + //data that matches the $code. If it does, it returns that data. + //It is used when building a questions text to allow incorporating the answer + //to an earlier question into the text of a later question. + //IE: Q1: What is your name? [Jason] + // Q2: Hi [Jason] how are you ? + //This function is called from the retriveAnswers function. + global $dbprefix, $connect, $clang; + //Find question details + if (isset($_SESSION[$code])) + { + $questiondetails=getsidgidqidaidtype($code); + //the getsidgidqidaidtype function is in common.php and returns + //a SurveyID, GroupID, QuestionID and an Answer code + //extracted from a "fieldname" - ie: 1X2X3a + // also returns question type + + if ($questiondetails['type'] == "M" || $questiondetails['type'] == "P") + { + if ((strpos($code,'comment')>0 || strpos($code,'other')>0) && isset($_SESSION[$code])) + { + return $_SESSION[$code]; + } + $query="SELECT * FROM {$dbprefix}questions WHERE parent_qid='".$questiondetails['qid']."' AND language='".$_SESSION['s_lang']."'"; + $result=db_execute_assoc($query) or safe_die("Error getting answer
      $query
      ".$connect->ErrorMsg()); //Checked + while($row=$result->FetchRow()) + { + if (isset($_SESSION[$code.$row['title']]) && $_SESSION[$code.$row['title']] == "Y") + { + $returns[] = $row['question']; + } + elseif (isset($_SESSION[$code]) && $_SESSION[$code] == "Y" && $questiondetails['aid']==$row['title']) + { + return $row['question']; + } + } + if (isset($_SESSION[$code."other"]) && $_SESSION[$code."other"]) + { + $returns[]=$_SESSION[$code."other"]; + } + if (isset($returns)) + { + $return=implode(", ", $returns); + if (strpos($return, ",")) + { + $return=substr_replace($return, " &", strrpos($return, ","), 1); + } + } + else + { + $return=$clang->gT("No answer"); + } + } + elseif (!$_SESSION[$code] && $_SESSION[$code] !=0) + { + $return=$clang->gT("No answer"); + } + else + { + $return=getextendedanswer($code, $_SESSION[$code], 'INSERTANS',$phpdateformat); + } + } + else + { + $return=$clang->gT("Error") . "($code)"; + } + return html_escape($return); +} + +/** +* Check if a table does exist in the database +* +* @param mixed $sid Table name to check for (without dbprefix!)) +* @return boolean True or false if table exists or not +*/ +function tableExists($tablename) +{ + global $connect; + static $tablelist; + + if (!isset($tablelist)) $tablelist = $connect->MetaTables(); + if ($tablelist==false) + { + return false; + } + foreach ($tablelist as $tbl) + { + if (db_quote_id($tbl) == db_table_name($tablename)) + { + return true; + } + } + return false; +} + +// Returns false if the survey is anonymous, +// and a token table exists: in this case the completed field of a token +// will contain 'Y' instead of the submitted date to ensure privacy +// Returns true otherwise +function bIsTokenCompletedDatestamped($thesurvey) +{ + if ($thesurvey['anonymized'] == 'Y' && tableExists('tokens_'.$thesurvey['sid'])) + { + return false; + } + else + { + return true; + } +} + +/** +* example usage +* $date = "2006-12-31 21:00"; +* $shift "+6 hours"; // could be days, weeks... see function strtotime() for usage +* +* echo sql_date_shift($date, "Y-m-d H:i:s", $shift); +* +* will output: 2007-01-01 03:00:00 +* +* @param mixed $date +* @param mixed $dformat +* @param mixed $shift +* @return string +*/ +function date_shift($date, $dformat, $shift) +{ + return date($dformat, strtotime($shift, strtotime($date))); +} + + +// getBounceEmail: returns email used to receive error notifications +function getBounceEmail($surveyid) +{ + $surveyInfo=getSurveyInfo($surveyid); + + if ($surveyInfo['bounceprocessing'] == 'G') + { + return getGlobalSetting('siteadminbounce'); + } + else if ($surveyInfo['bounce_email'] == '') + { + return null; // will be converted to from in MailText + } + else + { + return $surveyInfo['bounce_email']; + } +} + +// getEmailFormat: returns email format for the survey +// returns 'text' or 'html' +function getEmailFormat($surveyid) +{ + + $surveyInfo=getSurveyInfo($surveyid); + if ($surveyInfo['htmlemail'] == 'Y') + { + return 'html'; + } + else + { + return 'text'; + } + +} + +// Check if user has manage rights for a template +function hasTemplateManageRights($userid, $templatefolder) { + global $connect; + global $dbprefix; + $userid=sanitize_int($userid); + $templatefolder=sanitize_paranoid_string($templatefolder); + $query = "SELECT ".db_quote_id('use')." FROM {$dbprefix}templates_rights WHERE uid=".$userid." AND folder LIKE '".$templatefolder."'"; + + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Safe + + if ($result->RecordCount() == 0) return false; + + $row = $result->FetchRow(); + + return $row["use"]; +} + +/** +* This function creates an incrementing answer code based on the previous source-code +* +* @param mixed $sourcecode The previous answer code +*/ +function getNextCode($sourcecode) +{ + $i=1; + $found=true; + $foundnumber=-1; + while ($i<=strlen($sourcecode) && $found) + { + $found=is_numeric(substr($sourcecode,-$i)); + if ($found) + { + $foundnumber=substr($sourcecode,-$i); + $i++; + } + } + if ($foundnumber==-1) + { + return($sourcecode); + } + else + { + $foundnumber++; + $result=substr($sourcecode,0,strlen($sourcecode)-strlen($foundnumber)).$foundnumber; + return($result); + } + +} + +/** +* Translink +* +* @param mixed $type +* @param mixed $oldid +* @param mixed $newid +* @param mixed $text +* @return mixed +*/ +function translink($type, $oldid, $newid, $text) +{ + global $relativeurl; + if (!isset($_POST['translinksfields'])) + { + return $text; + } + + if ($type == 'survey') + { + $pattern = "([^'\"]*)/upload/surveys/$oldid/"; + $replace = "$relativeurl/upload/surveys/$newid/"; + return preg_replace('#'.$pattern.'#', $replace, $text); + } + elseif ($type == 'label') + { + $pattern = "([^'\"]*)/upload/labels/$oldid/"; + $replace = "$relativeurl/upload/labels/$newid/"; + return preg_replace('#'.$pattern.'#', $replace, $text); + } + else + { + return $text; + } +} + +/** +* This function creates the old fieldnames for survey import +* +* @param mixed $iOldSID The old survey id +* @param mixed $iNewSID The new survey id +* @param array $aGIDReplacements An array with group ids (oldgid=>newgid) +* @param array $aQIDReplacements An array with question ids (oldqid=>newqid) +*/ +function aReverseTranslateFieldnames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements) +{ + $aGIDReplacements=array_flip($aGIDReplacements); + $aQIDReplacements=array_flip($aQIDReplacements); + $aFieldMap=createFieldMap($iNewSID); + $aFieldMappings=array(); + foreach ($aFieldMap as $sFieldname=>$aFieldinfo) + { + if ($aFieldinfo['qid']!=null) + { + $aFieldMappings[$sFieldname]=$iOldSID.'X'.$aGIDReplacements[$aFieldinfo['gid']].'X'.$aQIDReplacements[$aFieldinfo['qid']].$aFieldinfo['aid']; + // now also add a shortened field mapping which is needed for certain kind of condition mappings + $aFieldMappings[$iNewSID.'X'.$aFieldinfo['gid'].'X'.$aFieldinfo['qid']]=$iOldSID.'X'.$aGIDReplacements[$aFieldinfo['gid']].'X'.$aQIDReplacements[$aFieldinfo['qid']]; + } + } + return array_flip($aFieldMappings); +} + + +/** +* This function replaces the old insertans tags with new ones across a survey +* +* @param string $newsid Old SID +* @param string $oldsid New SID +* @param mixed $fieldnames Array array('oldfieldname'=>'newfieldname') +*/ +function TranslateInsertansTags($newsid,$oldsid,$fieldnames) +{ + global $connect, $dbprefix; + + $newsid=sanitize_int($newsid); + $oldsid=sanitize_int($oldsid); + + + # translate 'surveyls_urldescription' and 'surveyls_url' INSERTANS tags in surveyls + $sql = "SELECT surveyls_survey_id, surveyls_language, surveyls_urldescription, surveyls_url from {$dbprefix}surveys_languagesettings WHERE surveyls_survey_id=".$newsid." AND (surveyls_urldescription LIKE '%{INSERTANS:".$oldsid."X%' OR surveyls_url LIKE '%{INSERTANS:".$oldsid."X%')"; + $res = db_execute_assoc($sql) or safe_die("Can't read groups table in transInsertAns ".$connect->ErrorMsg()); // Checked + + while ($qentry = $res->FetchRow()) + { + $urldescription = $qentry['surveyls_urldescription']; + $endurl = $qentry['surveyls_url']; + $language = $qentry['surveyls_language']; + + foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) + { + $pattern = $sOldFieldname; + $replacement = $sNewFieldname; + $urldescription=preg_replace('/'.$pattern.'/', $replacement, $urldescription); + $endurl=preg_replace('/'.$pattern.'/', $replacement, $endurl); + } + + if (strcmp($urldescription,$qentry['surveyls_urldescription']) !=0 || + (strcmp($endurl,$qentry['surveyls_url']) !=0)) + { + // Update Field + $sqlupdate = "UPDATE {$dbprefix}surveys_languagesettings SET surveyls_urldescription='".db_quote($urldescription)."', surveyls_url='".db_quote($endurl)."' WHERE surveyls_survey_id=$newsid AND surveyls_language='$language'"; + $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in surveys_languagesettings
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked + } // Enf if modified + } // end while qentry + + # translate 'quotals_urldescrip' and 'quotals_url' INSERTANS tags in quota_languagesettings + $sql = "SELECT quotals_id, quotals_urldescrip, quotals_url from {$dbprefix}quota_languagesettings qls,{$dbprefix}quota q WHERE sid=".$newsid." AND q.id=qls.quotals_quota_id AND (quotals_urldescrip LIKE '%{INSERTANS:".$oldsid."X%' OR quotals_url LIKE '%{INSERTANS:".$oldsid."X%')"; + $res = db_execute_assoc($sql) or safe_die("Can't read quota table in transInsertAns ".$connect->ErrorMsg()); // Checked + + while ($qentry = $res->FetchRow()) + { + $urldescription = $qentry['quotals_urldescrip']; + $endurl = $qentry['quotals_url']; + + foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) + { + $pattern = $sOldFieldname; + $replacement = $sNewFieldname; + $urldescription=preg_replace('/'.$pattern.'/', $replacement, $urldescription); + $endurl=preg_replace('/'.$pattern.'/', $replacement, $endurl); + } + + if (strcmp($urldescription,$qentry['quotals_urldescrip']) !=0 || + (strcmp($endurl,$qentry['quotals_url']) !=0)) + { + // Update Field + $sqlupdate = "UPDATE {$dbprefix}quota_languagesettings SET quotals_urldescrip='".db_quote($urldescription)."', quotals_url='".db_quote($endurl)."' WHERE quotals_id={$qentry['quotals_id']}"; + $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in quota_languagesettings
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked + } // Enf if modified + } // end while qentry + + + # translate 'description' INSERTANS tags in groups + $sql = "SELECT gid, language, group_name, description from {$dbprefix}groups WHERE sid=".$newsid." AND description LIKE '%{INSERTANS:".$oldsid."X%' OR group_name LIKE '%{INSERTANS:".$oldsid."X%'"; + $res = db_execute_assoc($sql) or safe_die("Can't read groups table in transInsertAns ".$connect->ErrorMsg()); // Checked + + while ($qentry = $res->FetchRow()) + { + $gpname = $qentry['group_name']; + $description = $qentry['description']; + $gid = $qentry['gid']; + $language = $qentry['language']; + + foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) + { + $pattern = $sOldFieldname; + $replacement = $sNewFieldname; + $gpname = preg_replace('/'.$pattern.'/', $replacement, $gpname); + $description=preg_replace('/'.$pattern.'/', $replacement, $description); + } + + if (strcmp($description,$qentry['description']) !=0 || + strcmp($gpname,$qentry['group_name']) !=0) + { + // Update Fields + $sqlupdate = "UPDATE {$dbprefix}groups SET description='".db_quote($description)."', group_name='".db_quote($gpname)."' WHERE gid=$gid AND language='$language'"; + $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in groups
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked + } // Enf if modified + } // end while qentry + + # translate 'question' and 'help' INSERTANS tags in questions + $sql = "SELECT qid, language, question, help from {$dbprefix}questions WHERE sid=".$newsid." AND (question LIKE '%{INSERTANS:".$oldsid."X%' OR help LIKE '%{INSERTANS:".$oldsid."X%')"; + $res = db_execute_assoc($sql) or safe_die("Can't read question table in transInsertAns ".$connect->ErrorMsg()); // Checked + + while ($qentry = $res->FetchRow()) + { + $question = $qentry['question']; + $help = $qentry['help']; + $qid = $qentry['qid']; + $language = $qentry['language']; + + foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) + { + $pattern = $sOldFieldname; + $replacement = $sNewFieldname; + $question=preg_replace('/'.$pattern.'/', $replacement, $question); + $help=preg_replace('/'.$pattern.'/', $replacement, $help); + } + + if (strcmp($question,$qentry['question']) !=0 || + strcmp($help,$qentry['help']) !=0) + { + // Update Field + $sqlupdate = "UPDATE {$dbprefix}questions SET question='".db_quote($question)."', help='".db_quote($help)."' WHERE qid=$qid AND language='$language'"; + $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in question
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked + } // Enf if modified + } // end while qentry + + + # translate 'answer' INSERTANS tags in answers + $sql = "SELECT a.qid, a.language, a.code, a.answer from {$dbprefix}answers as a INNER JOIN {$dbprefix}questions as b ON a.qid=b.qid WHERE b.sid=".$newsid." AND a.answer LIKE '%{INSERTANS:".$oldsid."X%'"; + $res = db_execute_assoc($sql) or safe_die("Can't read answers table in transInsertAns ".$connect->ErrorMsg()); // Checked + + while ($qentry = $res->FetchRow()) + { + $answer = $qentry['answer']; + $code = $qentry['code']; + $qid = $qentry['qid']; + $language = $qentry['language']; + + foreach ($fieldnames as $sOldFieldname=>$sNewFieldname) + { + $pattern = $sOldFieldname; + $replacement = $sNewFieldname; + $answer=preg_replace('/'.$pattern.'/', $replacement, $answer); + } + + if (strcmp($answer,$qentry['answer']) !=0) + { + // Update Field + $sqlupdate = "UPDATE {$dbprefix}answers SET answer='".db_quote($answer)."' WHERE qid=$qid AND code='$code' AND language='$language'"; + $updateres=$connect->Execute($sqlupdate) or safe_die ("Couldn't update INSERTANS in answers
      $sqlupdate
      ".$connect->ErrorMsg()); //Checked + } // Enf if modified + } // end while qentry +} + + +/** +* put your comment there... +* +* @param mixed $id +* @param mixed $type +*/ +function hasResources($id,$type='survey') +{ + global $publicdir,$uploaddir; + $dirname = $uploaddir; + + if ($type == 'survey') + { + $dirname .= "/surveys/$id"; + } + elseif ($type == 'label') + { + $dirname .= "/labels/$id"; + } + else + { + return false; + } + + if (is_dir($dirname) && $dh=opendir($dirname)) + { + while(($entry = readdir($dh)) !== false) + { + if($entry !== '.' && $entry !== '..') + { + return true; + break; + } + } + closedir($dh); + } + else + { + return false; + } + + return false; +} + +/** +* Creates a random sequence of characters +* +* @param mixed $length Length of resulting string +* @param string $pattern To define which characters should be in the resulting string +*/ +function sRandomChars($length,$pattern="23456789abcdefghijkmnpqrstuvwxyz") +{ + $patternlength = strlen($pattern)-1; + for($i=0;$i<$length;$i++) + { + if(isset($key)) + $key .= $pattern{rand(0,$patternlength)}; + else + $key = $pattern{rand(0,$patternlength)}; + } + return $key; +} + + + +/** +* used to translate simple text to html (replacing \n with
      +* +* @param mixed $mytext +* @param mixed $ishtml +* @return mixed +*/ +function conditional_nl2br($mytext,$ishtml,$encoded='') +{ + if ($ishtml === true) + { + // $mytext has been processed by clang->gT with html mode + // and thus \n has already been translated to + if ($encoded == '') + { + $mytext=str_replace(' ', '
      ',$mytext); + } + return str_replace("\n", '
      ',$mytext); + } + else + { + return $mytext; + } +} + +function conditional2_nl2br($mytext,$ishtml) +{ + if ($ishtml === true) + { + return str_replace("\n", '
      ',$mytext); + } + else + { + return $mytext; + } +} + +function br2nl( $data ) { + return preg_replace( '!!iU', "\n", $data ); +} + + +function safe_die($text) +{ + //Only allowed tag:
      + $textarray=explode('
      ',$text); + $textarray=array_map('htmlspecialchars',$textarray); + die(implode( '
      ',$textarray)); +} + +/** +* getQuotaInformation() returns quota information for the current survey +* @param string $surveyid - Survey identification number +* @param string $quotaid - Optional quotaid that restricts the result to a given quota +* @return array - nested array, Quotas->Members->Fields +*/ +function getQuotaInformation($surveyid,$language,$quotaid='all') +{ + global $clang, $clienttoken; + $baselang = GetBaseLanguageFromSurveyID($surveyid); + + $query = "SELECT * FROM ".db_table_name('quota').", ".db_table_name('quota_languagesettings')." + WHERE ".db_table_name('quota').".id = ".db_table_name('quota_languagesettings').".quotals_quota_id + AND sid='{$surveyid}' + AND quotals_language='".$language."'"; + if ($quotaid != 'all') + { + $query .= " AND id=$quotaid"; + } + + $result = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + $quota_info = array(); + $x=0; + + $surveyinfo=getSurveyInfo($surveyid); + + // Check all quotas for the current survey + if ($result->RecordCount() > 0) + { + while ($survey_quotas = $result->FetchRow()) + { + //Modify the URL - thanks janokary + $survey_quotas['quotals_url']=str_replace("{SAVEDID}",isset($_SESSION['srid']) ? $_SESSION['srid'] : '', $survey_quotas['quotals_url']); + $survey_quotas['quotals_url']=str_replace("{SID}", $surveyid, $survey_quotas['quotals_url']); + $survey_quotas['quotals_url']=str_replace("{LANG}", $clang->getlangcode(), $survey_quotas['quotals_url']); + $survey_quotas['quotals_url']=str_replace("{TOKEN}",$clienttoken, $survey_quotas['quotals_url']); + + array_push($quota_info,array('Name' => $survey_quotas['name'], + 'Limit' => $survey_quotas['qlimit'], + 'Action' => $survey_quotas['action'], + 'Message' => $survey_quotas['quotals_message'], + 'Url' => passthruReplace(insertansReplace($survey_quotas['quotals_url']), $surveyinfo), + 'UrlDescrip' => $survey_quotas['quotals_urldescrip'], + 'AutoloadUrl' => $survey_quotas['autoload_url'])); + $query = "SELECT * FROM ".db_table_name('quota_members')." WHERE quota_id='{$survey_quotas['id']}'"; + $result_qe = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + $quota_info[$x]['members'] = array(); + if ($result_qe->RecordCount() > 0) + { + while ($quota_entry = $result_qe->FetchRow()) + { + $query = "SELECT type, title,gid FROM ".db_table_name('questions')." WHERE qid='{$quota_entry['qid']}' AND language='{$baselang}'"; + $result_quest = db_execute_assoc($query) or safe_die($connect->ErrorMsg()); //Checked + $qtype = $result_quest->FetchRow(); + + $fieldnames = "0"; + + if ($qtype['type'] == "I" || $qtype['type'] == "G" || $qtype['type'] == "Y") + { + $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); + $value = $quota_entry['code']; + } + + if($qtype['type'] == "L" || $qtype['type'] == "O" || $qtype['type'] =="!") + { + $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); + $value = $quota_entry['code']; + } + + if($qtype['type'] == "M") + { + $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$quota_entry['code']); + $value = "Y"; + } + + if($qtype['type'] == "A" || $qtype['type'] == "B") + { + $temp = explode('-',$quota_entry['code']); + $fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$temp[0]); + $value = $temp[1]; + } + + array_push($quota_info[$x]['members'],array('Title' => $qtype['title'], + 'type' => $qtype['type'], + 'code' => $quota_entry['code'], + 'value' => $value, + 'qid' => $quota_entry['qid'], + 'fieldnames' => $fieldnames)); + } + } + $x++; + } + } + return $quota_info; +} + +/** +* get_quotaCompletedCount() returns the number of answers matching the quota +* @param string $surveyid - Survey identification number +* @param string $quotaid - quota id for which you want to compute the completed field +* @return string - number of mathing entries in the result DB or 'N/A' +*/ +function get_quotaCompletedCount($surveyid, $quotaid) +{ + $result ="N/A"; + $quota_info = getQuotaInformation($surveyid,GetBaseLanguageFromSurveyID($surveyid),$quotaid); + $quota = $quota_info[0]; + + if ( db_tables_exist(db_table_name_nq('survey_'.$surveyid)) && + count($quota['members']) > 0) + { + $fields_list = array(); // Keep a list of fields for easy reference + // construct an array of value for each $quota['members']['fieldnames'] + unset($querycond); + $fields_query = array(); + foreach($quota['members'] as $member) + { + foreach($member['fieldnames'] as $fieldname) + { + if (!in_array($fieldname,$fields_list)){ + $fields_list[] = $fieldname; + $fields_query[$fieldname] = array(); + } + $fields_query[$fieldname][]= db_quote_id($fieldname)." = '{$member['value']}'"; + } + } + + foreach($fields_list as $fieldname) + { + $select_query = " ( ".implode(' OR ',$fields_query[$fieldname]).' )'; + $querycond[] = $select_query; + } + + $querysel = "SELECT count(id) as count FROM ".db_table_name('survey_'.$surveyid)." WHERE ".implode(' AND ',$querycond)." "." AND submitdate IS NOT NULL"; + $result = db_execute_assoc($querysel) or safe_die($connect->ErrorMsg()); //Checked + $quota_check = $result->FetchRow(); + $result = $quota_check['count']; + } + + return $result; +} + +function fix_FCKeditor_text($str) +{ + $str = str_replace('
      ','',$str); + if ($str == "
      " || $str == " " || $str == " ") + { + $str = ""; + } + if (preg_match("/^[\s]+$/",$str)) + { + $str=''; + } + if ($str == "\n") + { + $str = ""; + } + if (trim($str) == " " || trim($str)=='') + { // chrome adds a single   element to empty fckeditor fields + $str = ""; + } + + return $str; +} + + +function recursive_stripslashes($array_or_string) +{ + if (is_array($array_or_string)) + { + return array_map('recursive_stripslashes', $array_or_string); + } + else + { + return stripslashes($array_or_string); + } +} + + + + +/** +* This is a helper function for GetAttributeFieldNames +* +* @param mixed $fieldname +*/ +function filterforattributes ($fieldname) +{ + if (strpos($fieldname,'attribute_')===false) return false; else return true; +} + + +/** +* Retrieves the attribute field names from the related token table +* +* @param mixed $surveyid The survey ID +* @return array The fieldnames +*/ +function GetAttributeFieldNames($surveyid) +{ + global $dbprefix, $connect; + if (tableExists('tokens_'.$surveyid) === false) + { + return Array(); + } + $tokenfieldnames = array_values($connect->MetaColumnNames("{$dbprefix}tokens_$surveyid", true)); + return array_filter($tokenfieldnames,'filterforattributes'); +} + +/** +* Retrieves the token field names usable for conditions from the related token table +* +* @param mixed $surveyid The survey ID +* @return array The fieldnames +*/ +function GetTokenConditionsFieldNames($surveyid) +{ + $extra_attrs=GetAttributeFieldNames($surveyid); + $basic_attrs=Array('firstname','lastname','email','token','language','sent','remindersent','remindercount','usesleft'); + return array_merge($basic_attrs,$extra_attrs); +} + +/** +* Retrieves the attribute names from the related token table +* +* @param mixed $surveyid The survey ID +* @param boolean $onlyAttributes Set this to true if you only want the fieldnames of the additional attribue fields - defaults to false +* @return array The fieldnames as key and names as value in an Array +*/ +function GetTokenFieldsAndNames($surveyid, $onlyAttributes=false) +{ + global $dbprefix, $connect, $clang; + if (tableExists('tokens_'.$surveyid) === false) + { + return Array(); + } + $extra_attrs=GetAttributeFieldNames($surveyid); + $basic_attrs=Array('firstname','lastname','email','token','language','sent','remindersent','remindercount','usesleft'); + $basic_attrs_names=Array( + $clang->gT('First name'), + $clang->gT('Last name'), + $clang->gT('Email address'), + $clang->gT('Token code'), + $clang->gT('Language code'), + $clang->gT('Invitation sent date'), + $clang->gT('Last Reminder sent date'), + $clang->gT('Total numbers of sent reminders'), + $clang->gT('Uses left') + ); + + $thissurvey=getSurveyInfo($surveyid); + $attdescriptiondata=!empty($thissurvey['attributedescriptions']) ? $thissurvey['attributedescriptions'] : ""; + $attdescriptiondata=explode("\n",$attdescriptiondata); + $attributedescriptions=array(); + $basic_attrs_and_names=array(); + $extra_attrs_and_names=array(); + foreach ($attdescriptiondata as $attdescription) + { + $attributedescriptions['attribute_'.substr($attdescription,10,strpos($attdescription,'=')-10)] = substr($attdescription,strpos($attdescription,'=')+1); + } + foreach ($extra_attrs as $fieldname) + { + if (isset($attributedescriptions[$fieldname])) + { + $extra_attrs_and_names[$fieldname]=$attributedescriptions[$fieldname]; + } + else + { + $extra_attrs_and_names[$fieldname]=sprintf($clang->gT('Attribute %s'),substr($fieldname,10)); + } + } + if ($onlyAttributes===false) + { + $basic_attrs_and_names=array_combine($basic_attrs,$basic_attrs_names); + return array_merge($basic_attrs_and_names,$extra_attrs_and_names); + } + else + { + return $extra_attrs_and_names; + } +} + +/** +* Retrieves the token attribute value from the related token table +* +* @param mixed $surveyid The survey ID +* @param mixed $attrName The token-attribute field name +* @param mixed $token The token code +* @return string The token attribute value (or null on error) +*/ +function GetAttributeValue($surveyid,$attrName,$token) +{ + global $dbprefix, $connect; + $attrName=strtolower($attrName); + if (!tableExists('tokens_'.$surveyid) || !in_array($attrName,GetTokenConditionsFieldNames($surveyid))) + { + return null; + } + $sanitized_token=$connect->qstr($token,get_magic_quotes_gpc()); + $surveyid=sanitize_int($surveyid); + + $query="SELECT $attrName FROM {$dbprefix}tokens_$surveyid WHERE token=$sanitized_token"; + $result=db_execute_num($query); + $count=$result->RecordCount(); + if ($count != 1) + { + return null; + } + else + { + $row=$result->FetchRow(); + return $row[0]; + } +} + +/** +* This function strips any content between and including @siU' // Strip style tags properly + /* ,'@<[\/\!]*?[^<>]*?>@si', // Strip out HTML tags + '@@' // Strip multi-line comments including CDATA + */ + ); + $text = preg_replace($search, '', $content); + return $text; +} + + +/** +* This function cleans files from the temporary directory being older than 1 day +* @todo Make the days configurable +*/ +function cleanTempDirectory() +{ + global $tempdir; + $dir= $tempdir.'/'; + $dp = opendir($dir) or die ('Could not open temporary directory'); + while ($file = readdir($dp)) { + if (is_file($dir.$file) && (filemtime($dir.$file)) < (strtotime('-1 days')) && $file!='index.html' && $file!='readme.txt' && $file!='..' && $file!='.' && $file!='.svn') { + @unlink($dir.$file); + } + } + $dir= $tempdir.'/upload/'; + $dp = opendir($dir) or die ('Could not open temporary directory'); + while ($file = readdir($dp)) { + if (is_file($dir.$file) && (filemtime($dir.$file)) < (strtotime('-1 days')) && $file!='index.html' && $file!='readme.txt' && $file!='..' && $file!='.' && $file!='.svn') { + @unlink($dir.$file); + } + } + closedir($dp); +} + + +function use_firebug() +{ + if(FIREBUG == true) + { + return ''; + }; +}; + +/** +* This is a convenience function for the coversion of datetime values +* +* @param mixed $value +* @param mixed $fromdateformat +* @param mixed $todateformat +* @return string +*/ +function convertDateTimeFormat($value, $fromdateformat, $todateformat) +{ + $datetimeobj = new Date_Time_Converter($value , $fromdateformat); + return $datetimeobj->convert($todateformat); +} + + +/** +* This function removes the UTF-8 Byte Order Mark from a string +* +* @param string $str +* @return string +*/ +function removeBOM($str=""){ + if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { + $str=substr($str, 3); + } + return $str; +} + +/** +* This function requests the latest update information from the LimeSurvey.org website +* +* @returns array Contains update information or false if the request failed for some reason +*/ +function GetUpdateInfo() +{ + global $homedir, $debug, $buildnumber, $versionnumber; + require_once($homedir."/classes/http/http.php"); + + $http=new http_class; + + /* Connection timeout */ + $http->timeout=0; + /* Data transfer timeout */ + $http->data_timeout=0; + $http->user_agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"; + $http->GetRequestArguments("http://update.limesurvey.org?build=$buildnumber",$arguments); + + $updateinfo=false; + $error=$http->Open($arguments); + $error=$http->SendRequest($arguments); + + $http->ReadReplyHeaders($headers); + + + if($error=="") { + $body=''; $full_body=''; + for(;;){ + $error = $http->ReadReplyBody($body,10000); + if($error != "" || strlen($body)==0) break; + $full_body .= $body; + } + $updateinfo=json_decode($full_body,true); + if ($http->response_status!='200') + { + $updateinfo['errorcode']=$http->response_status; + $updateinfo['errorhtml']=$full_body; + } + } + else + { + $updateinfo['errorcode']=$error; + $updateinfo['errorhtml']=$error; + } + unset( $http ); + return $updateinfo; +} + + + +/** +* This function updates the actual global variables if an update is available after using GetUpdateInfo +* @return Array with update or error information +*/ +function updatecheck() +{ + global $buildnumber; + $updateinfo=GetUpdateInfo(); + if (isset($updateinfo['Targetversion']['build']) && (int)$updateinfo['Targetversion']['build']>(int)$buildnumber && trim($buildnumber)!='') + { + setGlobalSetting('updateavailable',1); + setGlobalSetting('updatebuild',$updateinfo['Targetversion']['build']); + setGlobalSetting('updateversion',$updateinfo['Targetversion']['versionnumber']); + } + else + { + setGlobalSetting('updateavailable',0); + } + setGlobalSetting('updatelastcheck',date('Y-m-d H:i:s')); + return $updateinfo; +} + +/** +* This function removes a directory recursively +* +* @param mixed $dirname +* @return bool +*/ +function rmdirr($dirname) +{ + // Sanity check + if (!file_exists($dirname)) { + return false; + } + + // Simple delete for a file + if (is_file($dirname) || is_link($dirname)) { + return @unlink($dirname); + } + + // Loop through the folder + $dir = dir($dirname); + while (false !== $entry = $dir->read()) { + // Skip pointers + if ($entry == '.' || $entry == '..') { + continue; + } + + // Recurse + rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); + } + + // Clean up + $dir->close(); + return @rmdir($dirname); +} + +function getTokenData($surveyid, $token) +{ + global $dbprefix, $connect; + $query = "SELECT * FROM ".db_table_name('tokens_'.$surveyid)." WHERE token='".db_quote($token)."'"; + $result = db_execute_assoc($query) or safe_die("Couldn't get token info in getTokenData()
      ".$query."
      ".$connect->ErrorMsg()); //Checked + $thistoken=array(); // so has default value + while($row=$result->FetchRow()) + { + $thistoken=array("firstname"=>$row['firstname'], + "lastname"=>$row['lastname'], + "email"=>$row['email'], + "language" =>$row['language'], + "usesleft" =>$row['usesleft'], + ); + $attrfieldnames=GetAttributeFieldnames($surveyid); + foreach ($attrfieldnames as $attr_name) + { + $thistoken[$attr_name]=$row[$attr_name]; + } + } // while + return $thistoken; +} + + +/** +* This function returns the complete directory path to a given template name +* +* @param mixed $sTemplateName +*/ +function sGetTemplatePath($sTemplateName) +{ + global $standardtemplaterootdir, $usertemplaterootdir, $defaulttemplate; + if (isStandardTemplate($sTemplateName)) + { + return $standardtemplaterootdir.'/'.$sTemplateName; + } + else + { + if (file_exists($usertemplaterootdir.'/'.$sTemplateName)) + { + return $usertemplaterootdir.'/'.$sTemplateName; + } + elseif (file_exists($usertemplaterootdir.'/'.$defaulttemplate)) + { + return $usertemplaterootdir.'/'.$defaulttemplate; + } + elseif (file_exists($standardtemplaterootdir.'/'.$defaulttemplate)) + { + return $standardtemplaterootdir.'/'.$defaulttemplate; + } + else + { + return $standardtemplaterootdir.'/default'; + } + } +} + +/** +* This function returns the complete URL path to a given template name +* +* @param mixed $sTemplateName +*/ +function sGetTemplateURL($sTemplateName) +{ + global $standardtemplaterooturl, $standardtemplaterootdir, $usertemplaterooturl, $usertemplaterootdir, $defaulttemplate; + if (isStandardTemplate($sTemplateName)) + { + return $standardtemplaterooturl.'/'.$sTemplateName; + } + else + { + if (file_exists($usertemplaterootdir.'/'.$sTemplateName)) + { + return $usertemplaterooturl.'/'.$sTemplateName; + } + elseif (file_exists($usertemplaterootdir.'/'.$defaulttemplate)) + { + return $usertemplaterooturl.'/'.$defaulttemplate; + } + elseif (file_exists($standardtemplaterootdir.'/'.$defaulttemplate)) + { + return $standardtemplaterooturl.'/'.$defaulttemplate; + } + else + { + return $standardtemplaterooturl.'/default'; + } + } +} + +/** +* Return the goodchars to be used when filtering input for numbers. +* +* @param $lang string language used, for localisation +* @param $integer bool use only integer +* @param $negative bool allow negative values +*/ +function getNumericalFormat($lang = 'en', $integer = false, $negative = true) { + $goodchars = "0123456789"; + if ($integer === false) $goodchars .= "."; //Todo, add localisation + if ($negative === true) $goodchars .= "-"; //Todo, check databases + return $goodchars; +} + +/** +* Return an array of subquestions for a given sid/qid +* +* @param int $sid +* @param int $qid +* @param $sLanguage Language of the subquestion text +*/ +function getSubQuestions($sid, $qid, $sLanguage) { + global $dbprefix, $connect, $clang; + static $subquestions; + + if (!isset($subquestions[$sid])) { + $sid = sanitize_int($sid); + $query = "SELECT sq.*, q.other FROM {$dbprefix}questions as sq, {$dbprefix}questions as q" + ." WHERE sq.parent_qid=q.qid AND q.sid=$sid" + ." AND sq.language='".$sLanguage. "' " + ." AND q.language='".$sLanguage. "' " + ." ORDER BY sq.parent_qid, q.question_order,sq.scale_id , sq.question_order"; + $result=db_execute_assoc($query) or safe_die ("Couldn't get perform answers query
      $query
      ".$connect->ErrorMsg()); //Checked + $resultset=array(); + while ($row=$result->FetchRow()) + { + $resultset[$row['parent_qid']][] = $row; + } + $subquestions[$sid] = $resultset; + } + if (isset($subquestions[$sid][$qid])) return $subquestions[$sid][$qid]; + return array(); +} + +/** +* Wrapper function to retrieve an xmlwriter object and do error handling if it is not compiled +* into PHP +*/ +function getXMLWriter() { + if (!extension_loaded('xmlwriter')) { + safe_die('XMLWriter class not compiled into PHP, please contact your system administrator'); + } else { + $xmlwriter = new XMLWriter(); + } + return $xmlwriter; +} + + + +/* +* Return a sql statement for renaming a table +*/ +function db_rename_table($oldtable, $newtable) +{ + global $connect; + + $dict = NewDataDictionary($connect); + $result=$dict->RenameTableSQL($oldtable, $newtable); + return $result[0]; +} + +/** +* Returns true when a token can not be used (either doesn't exist or has less then one usage left +* +* @param mixed $tid Token +*/ +function usedTokens($token) +{ + global $dbprefix, $surveyid; + + $utresult = true; + $query = "SELECT tid, usesleft from {$dbprefix}tokens_$surveyid WHERE token=".db_quoteall($token); + + $result=db_execute_assoc($query,null,true); + if ($result !== false) { + $row=$result->FetchRow(); + if ($row['usesleft']>0) $utresult = false; + } + return $utresult; +} + + + +/** +* redirect() generates a redirect URL for the apporpriate SSL mode then applies it. +* +* @param $ssl_mode string 's' or '' (empty). +*/ +function redirect($ssl_mode) +{ + $url = 'http'.$ssl_mode.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; + if (!headers_sent()) + { // If headers not sent yet... then do php redirect + ob_clean(); + header('Location: '.$url); + ob_flush(); + exit; + }; +}; + +/** +* SSL_mode() $force_ssl is on or off, it checks if the current +* request is to HTTPS (or not). If $force_ssl is on, and the +* request is not to HTTPS, it redirects the request to the HTTPS +* version of the URL, if the request is to HTTPS, it rewrites all +* the URL variables so they also point to HTTPS. +*/ +function SSL_mode() +{ + global $rooturl , $homeurl , $publicurl , $tempurl , $imageurl , $uploadurl; + global $usertemplaterooturl , $standardtemplaterooturl; + global $parsedurl , $relativeurl , $fckeditordir , $ssl_emergency_override; + + $https = isset($_SERVER['HTTPS'])?$_SERVER['HTTPS']:''; + if($ssl_emergency_override !== true ) + { + $force_ssl = strtolower(getGlobalSetting('force_ssl')); + } + else + { + $force_ssl = 'off'; + }; + if( $force_ssl == 'on' && $https == '' ) + { + redirect('s'); + } + if( $force_ssl == 'off' && $https != '') + { + redirect(''); + }; +}; + + +/** +* Creates an array with details on a particular response for display purposes +* Used in Print answers (done), Detailed response view (Todo:)and Detailed admin notification email (done) +* +* @param mixed $iSurveyID +* @param mixed $iResponseID +* @param mixed $sLanguageCode +* @param boolean $bHonorConditions Apply conditions +*/ +function aGetFullResponseTable($iSurveyID, $iResponseID, $sLanguageCode, $bHonorConditions=false) +{ + global $connect; + $aFieldMap = createFieldMap($iSurveyID,'full',false,false,$sLanguageCode); + //Get response data + $idquery = "SELECT * FROM ".db_table_name('survey_'.$iSurveyID)." WHERE id=".$iResponseID; + $idrow=$connect->GetRow($idquery) or safe_die ("Couldn't get entry
      \n$idquery
      \n".$connect->ErrorMsg()); //Checked + + $aResultTable=array(); + + $oldgid = 0; + $oldqid = 0; + foreach ($aFieldMap as $sKey=>$fname) + { + if (!empty($fname['qid'])) + { + $attributes = getQuestionAttributes($fname['qid']); + if (getQuestionAttributeValue($attributes, 'hidden') == 1) + { + continue; + } + } + $question = $fname['question']; + $subquestion=''; + if (isset($fname['gid']) && !empty($fname['gid'])) { + //Check to see if gid is the same as before. if not show group name + if ($oldgid !== $fname['gid']) + { + $oldgid = $fname['gid']; + $aResultTable['gid_'.$fname['gid']]=array($fname['group_name']); + } + } + if (isset($fname['qid']) && !empty($fname['qid'])) + { + if ($oldqid !== $fname['qid']) + { + $oldqid = $fname['qid']; + if (($bHonorConditions && LimeExpressionManager::QuestionIsRelevant($fname['qid'])) || !$bHonorConditions) + { + if (isset($fname['subquestion']) || isset($fname['subquestion1']) || isset($fname['subquestion2'])) + { + $aResultTable['qid_'.$fname['sid'].'X'.$fname['gid'].'X'.$fname['qid']]=array($fname['question'],'',''); + } + else + { + $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); + $aResultTable[$fname['fieldname']]=array($question,'',$answer); + continue; + } + + } + else + { + continue; + } + + } + } + else + { + $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); + $aResultTable[$fname['fieldname']]=array($question,'',$answer); + continue; + } + if (isset($fname['subquestion'])) + $subquestion = "{$fname['subquestion']}"; + + if (isset($fname['subquestion1'])) + $subquestion = "{$fname['subquestion1']}"; + + if (isset($fname['subquestion2'])) + $subquestion .= "[{$fname['subquestion2']}]"; + + $answer=getextendedanswer($fname['fieldname'], $idrow[$fname['fieldname']]); + $aResultTable[$fname['fieldname']]=array('',$subquestion,$answer); + } + return $aResultTable; +} + + + +/** +* Check if $str is an integer, or string representation of an integer +* +* @param mixed $mStr +*/ +function bIsNumericInt($mStr) +{ + if(is_int($mStr)) + return true; + elseif(is_string($mStr)) + return preg_match("/^[0-9]+$/", $mStr); + return false; +} + +/** +* Invert key/values of an associative array, preserving multiple values in +* the source array as a single key with multiple values in the resulting +* array. +* +* This is not the same as array_flip(), which flattens the structure of the +* source array. +* +* @param array $aArr +*/ +function aArrayInvert($aArr) +{ + $aRet = array(); + foreach($aArr as $k => $v) + $aRet[$v][] = $k; + return $aRet; +} + +/** +* Include Keypad headers +*/ +function vIncludeKeypad() +{ + global $js_header_includes, $css_header_includes, $clang; + + $js_header_includes[] = '/scripts/jquery/jquery.keypad.min.js'; + if ($clang->langcode !== 'en') + { + $js_header_includes[] = '/scripts/jquery/locale/jquery.ui.keypad-'.$clang->langcode.'.js'; + } + $css_header_includes[] = '/scripts/jquery/css/jquery.keypad.alt.css'; +} + +/** +* Strips the DB prefix from a string - does not verify just strips the according number of characters +* +* @param mixed $sTableName +* @return string +*/ +function sStripDBPrefix($sTableName) +{ + global $dbprefix; + return substr($sTableName,strlen($dbprefix)); +} + +/* +* Emit the standard (last) onsubmit handler for the survey. +* +* This code in injected in the three questionnaire modes right after the element, +* before the individual questions emit their own onsubmit replacement code. +*/ +function sDefaultSubmitHandler() +{ + return << + + +EOS; +} + +/** +* This function fixes the group ID and type on all subquestions +* +*/ +function fixSubquestions() +{ + $surveyidresult=db_select_limit_assoc("select sq.qid, sq.parent_qid, sq.gid as sqgid, q.gid, sq.type as sqtype, q.type + from ".db_table_name('questions')." sq JOIN ".db_table_name('questions')." q on sq.parent_qid=q.qid + where sq.parent_qid>0 and (sq.gid!=q.gid or sq.type!=q.type)",1000); + while ($sv = $surveyidresult->FetchRow()) + { + db_execute_assoc('update '.db_table_name('questions')." set type='{$sv['type']}', gid={$sv['gid']} where qid={$sv['qid']}"); + } + +} + + +// Closing PHP tag intentionally omitted - yes, it is okay