Presentation & navigation -> "Public statistics?"
*
* The admin can set a question attribute "public_statistics" for each question
* to determine whether the results of a certain question should be shown to the user
* after he/she has submitted the survey.
*
* See http://docs.limesurvey.org/tiki-index.php?page=Question+attributes#public_statistics
*/
//don't call this script directly!
if (isset($_REQUEST['homedir'])) {die('You cannot start this script directly');}
require_once(dirname(__FILE__).'/admin/classes/core/class.progressbar.php');
require_once(dirname(__FILE__).'/classes/core/startup.php');
require_once(dirname(__FILE__).'/config-defaults.php');
require_once(dirname(__FILE__).'/common.php');
require_once(dirname(__FILE__).'/classes/core/language.php');
//XXX enable/disable this for testing
//$publicgraphs = 1;
//$showaggregateddata = 1;
/*
* List of important settings:
* - publicstatistics: General survey setting which determines if public statistics for this survey
* should be shown at all.
*
* - publicgraphs: General survey setting which determines if public statistics for this survey
* should include graphs or only show a tabular overview.
*
* - public_statistics: Question attribute which has to be applied to each question so that
* its statistics will be shown to the user. If not set no statistics for this question will be shown.
*
* - filterout_incomplete_answers: Setting taken from config-defaults.php which determines if
* not completed answers will be filtered.
*/
$surveyid=returnglobal('sid');
if (!$surveyid){
//This next line ensures that the $surveyid value is never anything but a number.
safe_die('You have to provide a valid survey ID.');
}
if ($surveyid)
{
$actquery="SELECT * FROM ".db_table_name('surveys')." WHERE sid=$surveyid and active='Y'";
$actresult=db_execute_assoc($actquery) or safe_die ("Couldn't access survey settings
$query
".$connect->ErrorMsg()); //Checked
if ($actresult->RecordCount() == 0) { safe_die('You have to provide a valid survey ID.'); }
else
{
$surveyinfo=getSurveyInfo($surveyid);
// CHANGE JSW_NZ - let's get the survey title for display
$thisSurveyTitle = $surveyinfo["name"];
// CHANGE JSW_NZ - let's get css from individual template.css - so define path
$thisSurveyCssPath = $surveyinfo["template"];
if ($surveyinfo['publicstatistics']!='Y')
{
safe_die('The public statistics for this survey are deactivated.');
}
//check if graphs should be shown for this survey
if ($surveyinfo['publicgraphs']=='Y')
{
$publicgraphs = 1;
}
}
}
//we collect all the output within this variable
$statisticsoutput ='';
//for creating graphs we need some more scripts which are included here
//True -> include
//False -> forget about charts
if (isset($publicgraphs) && $publicgraphs == 1)
{
require_once('classes/pchart/pchart/pChart.class');
require_once('classes/pchart/pchart/pData.class');
require_once('classes/pchart/pchart/pCache.class');
$MyCache = new pCache($tempdir.'/');
//$currentuser is created as prefix for pchart files
if (isset($_SERVER['REDIRECT_REMOTE_USER']))
{
$currentuser=$_SERVER['REDIRECT_REMOTE_USER'];
}
elseif (session_id())
{
$currentuser=substr(session_id(), 0, 15);
}
else
{
$currentuser="standard";
}
}
// Set language for questions and labels to base language of this survey
$language = GetBaseLanguageFromSurveyID($surveyid);
//pick the best font file if font setting is 'auto'
if ($chartfontfile=='auto')
{
$chartfontfile='vera.ttf';
if ( $language=='ar')
{
$chartfontfile='KacstOffice.ttf';
}
elseif ($language=='fa' )
{
$chartfontfile='KacstFarsi.ttf';
}
}
//set survey language for translations
$clang = SetSurveyLanguage($surveyid, $language);
//Create header (fixes bug #3097)
$surveylanguage= $language;
sendcacheheaders();
if ( !$embedded )
{
$header= "\n"
. "\n\t
"
//headline
.$clang->gT("Field summary for")." $qtitle: "
." | |||
"
."$qquestion | |||
| " .$clang->gT("Calculation")." | \n" ."\t\t" .$clang->gT("Result")." | \n" ."\t||
| $shw[0] | \n" ."\t\t$shw[1] | \n" ."\t||
| \n"
."\t\t\t".$clang->gT("Null values are ignored in calculations")." \n" ."\t\t\t".sprintf($clang->gT("Q1 and Q3 calculated using %s"), "".$clang->gT("minitab method")."") ."\n" ."\t\t | \n"
."\t|||
"
//headline
.$clang->gT("Field summary for")." $qtitle: "
." | |||||||||||
"
//question title
."$qquestion | |||||||||||
| ";
// this will count the answers considered completed
$TotalCompleted = 0;
//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])
{
//handling for "other" option
if ($al[1] == $clang->gT("Other"))
{
//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 '')";
}
// 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]'";
}
else
{
$query .= " 'Y'";
}
}
} //end if -> alist set
else
{
//get more data
if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n')
{
// 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]'";
}
//check filter option
if ($filterout_incomplete_answers == true) {$query .= " AND submitdate is not null";}
//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()); // this just extracts the data, after we present while ($row=$result->FetchRow()) { //increase counter $TotalCompleted += $row[0]; //"no answer" handling if ($al[0] == "") {$fname=$clang->gT("No answer");} //check if aggregated results should be shown elseif ($showaggregateddata == 1 && isset($showaggregateddata)) { if(!isset($showheadline) || $showheadline != false) { if($qtype == "5" || $qtype == "A") { //four columns $statisticsoutput .= "".$clang->gT("Answer")." | \n"
."\t\t" ."".$clang->gT("Count")." | \n" ."\t\t" ."".$clang->gT("Percentage")." | \n" ."\t\t" ."".$clang->gT("Sum")." | \n" ."\t" ."".$clang->gT("Count")." | \n" ."\t\t" ."".$clang->gT("Percentage")." | \n" ."\t\n"; $showheadline = false; } } //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]; //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*$totalrecords); } //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*$totalrecords); } //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*$totalrecords); } } //end if -> question type = "5"/"A" } //end if -> show aggregated data //handling what's left else { if(!isset($showheadline) || $showheadline != false) { //three columns $statisticsoutput .= "".$clang->gT("Answer")."\n" ."\t\t" ."".$clang->gT("Count")." | \n" ."\t\t" ."".$clang->gT("Percentage")." | \n" ."\t\n"; $showheadline = false; } //answer text $fname="$al[1] ($al[0])"; } //are there some results to play with? if ($totalrecords > 0) { //calculate percentage $gdata[] = ($row[0]/$totalrecords)*100; } //no results else { //no data! $gdata[] = "N/A"; } //only add this if we don't handle question type "5"/"A" if(!isset($justadded)) { //put absolute data into array $grawdata[]=$row[0]; } else { //unset to handle "no answer" data correctly unset($justadded); } //put question title and code into array $label[]=$fname; //put only the code into the array $justcode[]=$al[0]; //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 while -> loop through results } //end foreach -> loop through answer data //no filtering of incomplete answers and NO multiple option questions if (($filterout_incomplete_answers == false) and ($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)) { //counter $i=0; while (isset($gdata[$i])) { //we want to have some "real" data here if ($gdata[$i] != "N/A") { //calculate percentage $gdata[$i] = ($grawdata[$i]/$TotalCompleted)*100; } //increase counter $i++; } //end while (data available) } //end if -> noncompleted checked //noncompleted is NOT checked else { //calculate total number of incompleted records $TotalIncomplete = $totalrecords - $TotalCompleted; //output $fname=$clang->gT("Non completed"); //we need some data if ($totalrecords > 0) { //calculate percentage $gdata[] = ($TotalIncomplete/$totalrecords)*100; } //no data :( else { $gdata[] = "N/A"; } //put data of incompleted records into array $grawdata[]=$TotalIncomplete; //put question title ("Not completed") into array $label[]= $fname; //put the code ("Not completed") into the array $justcode[]=$fname; //edit labels and put them into antoher array $lbl[] = wordwrap(FlattenText($fname), 20, "\n"); } //end else -> noncompleted NOT checked } //end if -> no filtering of incomplete answers and no multiple option questions //counter $i=0; //we need to know which item we are editing $itemcounter = 1; //array to store items 1 - 5 of question types "5" and "A" $stddevarray = array(); //loop through all available answers while (isset($gdata[$i])) { //repeat header (answer, count, ...) for each new question unset($showheadline); /* * there are 3 colums: * * 1 (50%) = answer (title and code in brackets) * 2 (25%) = count (absolute) * 3 (25%) = percentage */ $statisticsoutput .= "\t||||
| " . $label[$i] ."\n" ."\t\t | \n" //output absolute number of records ."\t\t" . $grawdata[$i] . "\n"; //no data if ($gdata[$i] == "N/A") { //output when having no data $statisticsoutput .= "\t\t | "; //percentage = 0 $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; $gdata[$i] = 0; //check if we have to adjust ouput due to $showaggregateddata setting if($showaggregateddata == 1 && isset($showaggregateddata) && ($qtype == "5" || $qtype == "A")) { $statisticsoutput .= "\t\t | "; } } //data available else { //check if data should be aggregated if($showaggregateddata == 1 && isset($showaggregateddata) && ($qtype == "5" || $qtype == "A")) { //mark that we have done soemthing special here $aggregated = true; //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] == $clang->gT("No answer")) { //prevent division by zero if(($totalrecords - $grawdata[$i+4]) > 0) { //re-calculate percentage $percentage = ($grawdata[$i] / ($totalrecords - $grawdata[$i+4])) * 100; } else { $percentage = 0; } } elseif($itemcounter == 4 && $label[$i+2] == $clang->gT("No answer")) { //prevent division by zero if(($totalrecords - $grawdata[$i+2]) > 0) { //re-calculate percentage $percentage = ($grawdata[$i] / ($totalrecords - $grawdata[$i+2])) * 100; } else { $percentage = 0; } } else { $percentage = $gdata[$i]; } //output $statisticsoutput .= "\t\t | "; //output percentage $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; //adjust output $statisticsoutput .= "\t\t | "; } //item 3 - just show results twice if($gdata[$i] >= 400 && $i != 0) { //remove "400" which was added before $gdata[$i] -= 400; if($itemcounter == 3 && $label[$i+3] == $clang->gT("No answer")) { //prevent division by zero if(($totalrecords - $grawdata[$i+3]) > 0) { //re-calculate percentage $percentage = ($grawdata[$i] / ($totalrecords - $grawdata[$i+3])) * 100; } else { $percentage = 0; } } else { //get the original percentage $percentage = $gdata[$i]; } //output percentage $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; //output again (no real aggregation here) $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $percentage)."%"; $statisticsoutput .= "\t\t"; } //FIRST value -> add percentage of item 1 + item 2 if(($gdata[$i] >= 300 && $gdata[$i] < 400) || ($i == 0 && $gdata[$i] <= 400)) { //remove "300" which was added before $gdata[$i] -= 300; if($itemcounter == 1 && $label[$i+5] == $clang->gT("No answer")) { //prevent division by zero if(($totalrecords - $grawdata[$i+5]) > 0) { //re-calculate percentage $percentage = ($grawdata[$i] / ($totalrecords - $grawdata[$i+5])) * 100; $percentage2 = ($grawdata[$i + 1] / ($totalrecords - $grawdata[$i+5])) * 100; } else { $percentage = 0; $percentage2 = 0; } } else { $percentage = $gdata[$i]; $percentage2 = $gdata[$i+1]; } //percentage of item 1 + item 2 $aggregatedgdata = $percentage + $percentage2; //output percentage $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; //output aggregated data $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; $statisticsoutput .= "\t\t"; } //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] == $clang->gT("No answer")) { //prevent division by zero if(($totalrecords - $grawdata[$i+1]) > 0) { //re-calculate percentage $percentage = ($grawdata[$i] / ($totalrecords - $grawdata[$i+1])) * 100; $percentage2 = ($grawdata[$i - 1] / ($totalrecords - $grawdata[$i+1])) * 100; } else { $percentage = 0; $percentage2 = 0; } } else { $percentage = $gdata[$i]; $percentage2 = $gdata[$i-1]; } //item 4 + item 5 $aggregatedgdata = $percentage + $percentage2; //output percentage $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $percentage) . "%"; //output aggregated data $statisticsoutput .= "\t\t | "; $statisticsoutput .= sprintf("%01.2f", $aggregatedgdata)."%"; $statisticsoutput .= "\t\t"; //calculate sum of items 1-5 $sumitems = $grawdata[$i] + $grawdata[$i-1] + $grawdata[$i-2] + $grawdata[$i-3] + $grawdata[$i-4]; //special treatment for zero values if($sumitems > 0) { $sumpercentage = "100.00"; } else { $sumpercentage = "0"; } //special treatment for zero values if($TotalCompleted > 0) { $casepercentage = "100.00"; } else { $casepercentage = "0"; } $statisticsoutput .= "\t\t  | \n\t
| ".$clang->gT("Sum")." (".$clang->gT("Answers").") | "; $statisticsoutput .= "".$sumitems." | "; $statisticsoutput .= "$sumpercentage% | "; $statisticsoutput .= "$sumpercentage% | "; $statisticsoutput .= "\t\t \n\t||||||||
| ".$clang->gT("Number of cases")." | "; //German: "Fallzahl" $statisticsoutput .= "".$TotalCompleted." | "; $statisticsoutput .= "$casepercentage% | "; //there has to be a whitespace within the table cell to display correctly $statisticsoutput .= "  | "; $statisticsoutput .= sprintf("%01.2f", $gdata[$i]) . "%"; $statisticsoutput .= "\t\t"; } } //end else -> $gdata[$i] != "N/A" //end output per line. there has to be a whitespace within the table cell to display correctly $statisticsoutput .= "\t\t  | \n\t\n"; //increase counter $i++; $itemcounter++; } //end while //only show additional values when this setting is enabled if($showaggregateddata == 1 && isset($showaggregateddata)) { //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++) { //create product of item * value $am += (($x+1) * $stddevarray[$x]); } //prevent division by zero if(isset($stddevarray) && array_sum($stddevarray) > 0) { $am = round($am / array_sum($stddevarray),2); } else { $am = 0; } //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 */ for($j = 0; $j < 5; $j++) { //1 = calculate difference between item and arithmetic mean $diff = (($j+1) - $am); //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]; } } //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) { $stddev = $stddev / (array_sum($stddevarray)-1); //formula source: http://de.wikipedia.org/wiki/Empirische_Varianz } else { $stddev = 0; } //5 = get root $stddev = sqrt($stddev); $stddev = round($stddev,2); } //calculate standard deviation $statisticsoutput .= "|||||||
| ".$clang->gT("Arithmetic mean")." | ".$clang->gT("Standard deviation")." | "; //German: "Fallzahl" $statisticsoutput .= "$am | $stddev | "; //there has to be a whitespace within the table cell to display correctly $statisticsoutput .= "  | |||||||||