Location: PHPKode > scripts > AskPeople-Free PHP survey application > AskPeople_2_2_2/includes/functions.inc.php
<?

include('surveys/apconfig.php'); // include the global config file

ini_set('error_reporting', E_ERROR); // set a fairly high level of error reporting only
ini_set('magic_quotes_gpc','0'); // turn off magic quotes to avoid multiple escaping problems
ini_set('magic_quotes_runtime','0'); // turn off magic quotes to avoid multiple escaping problems

function exportQuestToText($id,$boxes="on") { // NEED TO UPDATE THIS TO ACCOMODATE SCALE QUESTIONS

	$pollfilename = "surveys/quest_" . $id . ".xml";

	if ($boxes == "on") {
		$boxesarray = array(
		"box" => "[ ] ",
		"line" => "------------------------------------------------------------------------",
		"dotted" => "....................................................................................................\n",
		"shortdotted" => " ...................."
		);
	}
	
	$loaded = loadQuest2($pollfilename);

	if (strlen($loaded[meta][title])>0) { $output .= $loaded[meta][title] . "\n\n"; }
	if (strlen($loaded[meta][introduction])>0) { $output .= $loaded[meta][introduction] . "\n\n"; }
	
	$typearray = array("single","dropdown","multi","smallbox","bigbox","info","pagebreak");
	$newtypearray = array("Please tick one option","Please choose one option","Please tick all that apply","Please write your answer in the space below","Please write your answer in the space below","","");

	for ($a=1;$a<=count($loaded['questions']);$a++) {	
		if ($loaded[questions][$a][type] != "pagebreak") {		
			$output .= $loaded[questions][$a][questiontext] . "\n\n";	
			
			if (count($loaded[questions][$a][scale])>0 && $loaded[questions][$a][type] == "single") { // a single grid
				$output .= "Please tick one option per row" . "\n\n";			
			} elseif (count($loaded[questions][$a][scale])>0 && $loaded[questions][$a][type] == "multi") { // a multi grid
				$output .= "Please tick all that apply in each row" . "\n\n";					
			} else {
				$output .= str_replace($typearray,$newtypearray,$loaded[questions][$a][type]) . "\n\n";
			}
			if ($loaded[questions][$a][type] == "multi" || $loaded[questions][$a][type] == "single" || $loaded[questions][$a][type] == "dropdown") {
				
				if (count($loaded[questions][$a][scale])>0) { // a scale
					$output .= "\t";
					foreach((array)$loaded[questions][$a][scale] as $scpt) {
						$output .= "\t" . $scpt;
					}
					$output .= "\n";
					foreach((array)$loaded[questions][$a][options] as $v) {
						$output .= $v . "\t\t";
						foreach((array)$loaded[questions][$a][scale] as $scpt) {
							$output .= $boxesarray[box] . "\t";
						}
						$output .= "\n";
					}								
				} else {
					foreach((array)$loaded[questions][$a][options] as $v) {
						if (eregi("other_specify:",$v)) {
						  $otherlabel = str_replace("other_specify:","",$v);
						  $otherlabel = (strlen($otherlabel)>0) ? $otherlabel : "Other (please specify)";
						  $output .= $otherlabel . $boxesarray[shortdotted] ."\n";
						} else {
							$output .= $boxesarray[box] . $v . "\n";					
						}
					}				
				}
			} else {
				$testoptions = @implode("\n",$loaded[questions][$a][options]);
				if (strlen($testoptions)>0) { $output .= "(" . $testoptions . ")\n"; }
				$output .=  $boxesarray[dotted];
			}
		}
		$output .= "\n\n";
	}
	return($output);
}	

function savePoll($id,$pollarray) {
	// save a poll datafile and confirm
	
	// two 'templates' used to define the datafile structure:

	$polldatatemplate = "<?xml version=\"1.0\"?>
<questionnaire>
<id>%id%</id>
<title>%title%</title>
<creator>%creator%</creator>
<template>%template%</template>
<introduction>%introduction%</introduction>
%questions%
<date>%date%</date>
</questionnaire>
	";

	$pollanswertemplate = "
	<question>
		<questionid>%q_id%</questionid>
		<type>%q_type%</type>
		<validation>%q_validation%</validation>
		<questiontext>%q_text%</questiontext>
		<options>%q_options%</options>
		<scale>%q_scale%</scale>
	</question>
	";
	
	for ($a=0;$a<count($pollarray);$a++) {		
	
		if (strlen($pollarray[$a])>0) {
		
			$answertemp = $pollanswertemplate;
			
			$answertemp = str_replace("%q_id%",$pollarray[$a][questionid],$answertemp);
			$answertemp = str_replace("%q_type%",$pollarray[$a][type],$answertemp);
			$answertemp = str_replace("%q_validation%",$pollarray[$a][validation],$answertemp);
			$answertemp = str_replace("%q_text%",str_replace("\t","",$pollarray[$a][questiontext]),$answertemp); // strip stray tabs from pasted-in text
			$answertemp = str_replace("%q_options%",str_replace("\t","",$pollarray[$a][options]),$answertemp); // strip stray tabs from pasted-in text
			$answertemp = str_replace("%q_scale%",str_replace("\t","",$pollarray[$a][scale]),$answertemp); // strip stray tabs from pasted-in text
	
			$outputchunk .= $answertemp;
		}
	}
	
	$outputfile = $polldatatemplate;
	
	$outputfile = str_replace("%id%",$pollarray[id],$outputfile);
	$outputfile = str_replace("%title%",$pollarray[title],$outputfile);
	$outputfile = str_replace("%date%",$pollarray[date],$outputfile);
	$outputfile = str_replace("%creator%",$pollarray[creator],$outputfile);
	$outputfile = str_replace("%template%",$pollarray[template],$outputfile);
	$outputfile = str_replace("%introduction%",$pollarray[introduction],$outputfile);
	$outputfile = str_replace("%questions%",$outputchunk,$outputfile);
	
	// save file to disk
	
	$filename = "surveys/quest_" . $id . ".xml";
	$open = fopen ($filename, "w+");

	if ($open) {
		
		if (flock($open,LOCK_EX)) {
			fwrite ($open, $outputfile);	
			flock ($open, LOCK_UN);
		}

		fclose ($open);	
		@chmod($filename,0777);
		
		return (true);
				
	} else {

		die("<p>Unable to save changes to questionnaire data file. Check file permissions for this directory.</p>");
	
	}
}



function makeQuestionnaireMenu($dir="surveys/",$selected="",$mode="menu") {

	if ($handle = opendir($dir)) { // specify questionnaire directory

	    //$excludedfiles = array('functions.inc','.','..','upload.php','fileupload.class');

	    while (false !== ($file = readdir($handle))) {
    	    //if (!in_array($file,$excludedfiles)) {
    	    if (substr($file,-3) == "xml") { // only find XML files in the directory
    	        $file_id_key = substr($file,6,-4);
    	        $filemenuarray[$file_id_key] = 'surveys/' . $file;
    	    }
    	}
    	closedir($handle);
	}
	
	
	foreach((array)$filemenuarray as $k => $v) {
		if (file_exists($v)) {
			$polldata = @implode("",file($v));

			preg_match_all("/<title>(.*?)<\/title>/si",$polldata,$poll_title);
			$filemenuarray2[$k]['title'] = trim($poll_title[1][0]);

			preg_match_all("/<date>(.*?)<\/date>/si",$polldata,$poll_date);
			$filemenuarray2[$k]['date'] = strtotime(trim($poll_date[1][0]));
		}
	}

	//print_r($filemenuarray2);

	$a=1; // a little counter, so we can fix date problems for multiple surveys
	
	foreach((array)$filemenuarray2 as $k => $v) {
		if (is_array($outputarray[$v['date']])) {  // hmm, there's already a project with this date, so let's knock it back slightly to avoid overwriting
			$newdate = ($v['date'])+$a;
			$a++;
			$outputarray[$newdate] = array("id"=>$k,"title"=>$v['title']); // reorder the array so we can sort by date	
		} else {
			$outputarray[$v['date']] = array("id"=>$k,"title"=>$v['title']); // reorder the array so we can sort by date	
		}
	}
 
	@krsort($outputarray); // sort in reverse date order

	//print_r($outputarray);

	if ($mode == "menu") { // whether to return the output as a formatted <select>
	
		$filemenu = "<select name=\"sid\">";
	
		foreach((array)$outputarray as $k => $v) {
			if (strlen($v['title'])>0) { 
				if (strlen($v['title'])>30) {
					$v['title'] = substr($v['title'],0,30) . "...";
				}
				
				if ($v['id'] == $selected) {
					$filemenu .= "<option value=\"{$v['id']}\" selected='selected'>{$v['title']}</option>\n"; 				
				} else {			
					$filemenu .= "<option value=\"{$v['id']}\">{$v['title']}</option>\n"; 
				}
			}
		}
	
		$filemenu .= "</select>";

	} else {

		foreach((array)$outputarray as $k => $v) {
			$filemenu[$v['id']] = $v['title'];
		}
			
	}
	return($filemenu);
}	

function makeTemplateMenu($dir="templates/",$selected="AskPeopleDefault",$menuname="templatename",$phponly="FALSE",$mode="menu") {

	if (strlen(trim($selected))<1) { // quick hack to ensure Default is selected if blank
		$selected = "AskPeopleDefault.php";
	}

	if ($handle = opendir($dir)) { // specify template directory

	    $excludedfiles = array('.','..','.htaccess','config.php','images');

	    while (false !== ($file = readdir($handle))) {
    	    if (!in_array($file,$excludedfiles)) {
    	    	if ($phponly == "TRUE") {    	    	
					if (substr($file,-3) == "php") {
		     	    	$filemenuarray[] = $file;					
					}
    	    	} elseif ($phponly == "NOT") {
					if (substr($file,-3) != "php") {
		     	    	$filemenuarray[] = $file;					
					}
    	    	} else {
	     	    	$filemenuarray[] = $file;   	    	
    	    	}
      	    }
    	}
    	closedir($handle);
	}

	sort($filemenuarray);
	
	if ($mode == "menu") {
		$filemenu = "<select name=\"{$menuname}\">";
	
		if (strlen($filemenuarray)>0) {
			foreach($filemenuarray as $v) {
				if (strlen($v)>0) { 
					if ($v == $selected) {
						$filemenu .= "<option value=\"$v\" selected=\"selected\">$v</option>\n"; 
					} else {
						$filemenu .= "<option value=\"$v\">$v</option>\n"; 				
					}
				}
			}
		}
	
		$filemenu .= "</select>";
	} else {
		$filemenu = $filemenuarray;	
	}

	return($filemenu);
}

function makeUserLevelMenu($name,$selected="",$maxlevel) {
	
	$userlevels[0] = 'Level 0 (suspended)';
	for ($i=1;$i<11;$i++) {
		if ($i<=$maxlevel) {			
			$userlevels[$i] = 'Level '.$i;
		}
	}
		
	$menu .= "<select name=\"$name\">\n";
	$menu .= "\t<option value=''>--Select access level--</option>\n";
	foreach ($userlevels as $k => $u) {
		if ($k == $selected) {
			$menu .= "\t<option value=\"$k\" selected='selected'>$u</option>\n";
		} else {
			$menu .= "\t<option value=\"$k\">$u</option>\n";
		}
	}
	$menu .= "</select>\n";

	return($menu);
}

function getNextId($dir="surveys/") {

	$salt = date("U");	
	$testid = strtoupper(substr(@md5($salt),26,32));
	
	//echo ($testid);

	if ($handle = opendir($dir)) { // specify questionnaire directory

	    //$excludedfiles = array('functions.inc','.','..','upload.php','fileupload.class');
		
		while (false !== ($file = readdir($handle))) {
    	    //if (!in_array($file,$excludedfiles)) {
    	    if (substr($file,-3) == "xml") { // only find XML files in the directory
    	        $file_id_key = substr($file,6,-4);
    	        $filemenuarray[$file_id_key] = 'surveys/' . $file;
    	    }
    	}
    	   	
    	closedir($handle);
	}
	
	//print_r($filemenuarray);
	
	//ksort($filemenuarray);
	//end($filemenuarray);
	//$lastid = key($filemenuarray);
	//return($lastid+1);
		
	if (strlen($filemenuarray[$testid])>0) { // already exists
		$testid = strtoupper(substr(@md5(substr($salt,3,8)),0,6)); // pick another random ID and just hope it doesn't clash...
	}
	
	return($testid);
}	

function loadFile($destination,$charstostrip="") {

	if (file_exists($destination)) {

		$open = fopen($destination,"r");

			if ($open) {

				$output = file($destination);
				if (count($output)>0) {
					$output = implode("",$output);
				}
		
				$output = stripslashes(str_replace($charstostrip,"",$output));
				
				fclose($open);
				
				return ($output);
			} else {
				die("Unable to load file from \"$destination\" (the file may not be readable, or may not have been created yet. Check the file permissions, and that data exists in this file.");			
			}
					
	} else {
		die("Unable to load file (the file may not be readable, or may not have been created yet. Check the file permissions, and that data exists in this file.");
	}
} 

function saveFile($destination,$content) {
	if (ini_get('magic_quotes_gpc')) {
		$content = stripslashes($content);
	}	
	$open = fopen($destination,"w+");
	if ($open) {

		if (flock($open,LOCK_EX)) {
			fwrite ($open, $content);	
			flock ($open, LOCK_UN);
		}

		fclose($open);	
		@chmod($destination,0777);
	} else {
		die("Unable to save file (the file may not be writeable, or may not have been created yet. Check the directory permissions.");
	}
	return (true);
}

function cleanUpTemp($dir="surveys/temp/",$id) {

	if ($handle = opendir($dir)) { // specify temp files directory

 	    $excludedfiles = array('.','..');

	    while (false !== ($file = readdir($handle))) {
    	    if (!in_array($file,$excludedfiles)) {
     	    	if (substr($file,-3) == "dat" && substr($file,0,4) == "temp" && substr($file,5,1) == $id) { // only find temp and .dat files for specified project in the directory
					$deleted_temp[] = $file;
					$filetodel = $dir . $file;
					unlink($filetodel);
    	    	}
    	    }
    	}
    	closedir($handle);
	}
	
	return($deleted_temp);

}

// Version 2 FUNCTIONS:

function loadQuest2($id) { // load a questionnaire definition file, parse and return array
	
	if (file_exists($id)) {
		$loaded_polldata = stripslashes(file_get_contents($id));
		
		preg_match_all("/<id>(.*?)<\/id>/si",$loaded_polldata,$poll_id);
   		$loadedpoll['meta']['id'] = trim($poll_id[1][0]);   		

		preg_match_all("/<title>(.*?)<\/title>/si",$loaded_polldata,$poll_title);
   		$loadedpoll['meta']['title'] = stripslashes(trim($poll_title[1][0]));   		
   					
		preg_match_all("/<creator>(.*?)<\/creator>/si",$loaded_polldata,$poll_creator);
   		$loadedpoll['meta']['creator'] = trim($poll_creator[1][0]);   		

		preg_match_all("/<template>(.*?)<\/template>/si",$loaded_polldata,$poll_template);
   		$loadedpoll['meta']['template'] = trim($poll_template[1][0]);   		

		preg_match_all("/<date>(.*?)<\/date>/si",$loaded_polldata,$poll_date);
   		$loadedpoll['meta']['date'] = trim($poll_date[1][0]);   		

		preg_match_all("/<introduction>(.*?)<\/introduction>/si",$loaded_polldata,$poll_intro);
   		$loadedpoll['meta']['introduction'] = stripslashes(trim($poll_intro[1][0]));   		
    		
		preg_match_all("/<question>(.*?)<\/question>/si",$loaded_polldata,$poll_question);
    		
   		for ($a=0;$a<count($poll_question[1]);$a++) { // iterate through answers
						
			preg_match_all("/<questionid>(.*?)<\/questionid>/si",$poll_question[1][$a],$poll_questionid);
   			$loadedpoll['questions'][$poll_questionid[1][0]]['questionid'] = trim($poll_questionid[1][0]);

			preg_match_all("/<type>(.*?)<\/type>/si",$poll_question[1][$a],$poll_questiontype);
   			$loadedpoll['questions'][$poll_questionid[1][0]]['type'] = trim($poll_questiontype[1][0]);

			preg_match_all("/<validation>(.*?)<\/validation>/si",$poll_question[1][$a],$poll_questionvalidation);
   			$loadedpoll['questions'][$poll_questionid[1][0]]['validation'] = trim($poll_questionvalidation[1][0]);

			preg_match_all("/<questiontext>(.*?)<\/questiontext>/si",$poll_question[1][$a],$poll_questiontext);
   			$loadedpoll['questions'][$poll_questionid[1][0]]['questiontext'] = str_replace("\t"," ",stripslashes(trim($poll_questiontext[1][0])));

			preg_match_all("/<options>(.*?)<\/options>/si",$poll_question[1][$a],$poll_questionoptions);
   		
   			if (strlen($poll_questionoptions[1][0])>0) { // there are some options here
   				 $rawoptions = @explode("|", stripslashes(trim($poll_questionoptions[1][0])));
   				 foreach((array)$rawoptions as $o) {
   				 	$niceo = (strlen(idWord($o))>0) ? idWord($o) : "0";
   				 	$loadedpoll['questions'][$poll_questionid[1][0]]['options'][$niceo] = str_replace("\t"," ",$o);
   				 }
   			} else {
   				$loadedpoll['questions'][$poll_questionid[1][0]]['options'] = null;
			}
			
			preg_match_all("/<scale>(.*?)<\/scale>/si",$poll_question[1][$a],$poll_questionscale);

   			if (strlen($poll_questionscale[1][0])>0) { // there are some scale points here
   				 $rawscalepoints = @explode("|", stripslashes(trim($poll_questionscale[1][0])));
   				 foreach((array)$rawscalepoints as $sc) {
   				 	$nicesc = idWord($sc);
   				 	$loadedpoll['questions'][$poll_questionid[1][0]]['scale'][$nicesc] = str_replace("\t"," ",$sc);
   				 }
   			} else {
   				$loadedpoll['questions'][$poll_questionid[1][0]]['scale'] = null;
			}

   		}	
   	} else {
   		die ("Unable to load questionnaire file");
   	}
   	
	return ($loadedpoll);
}

function saveResponse2($surveyid,$responsearray) {
	$output = date("d-M-Y H:i" . "\t"); 
	if (strlen($responsearray['uid'])>0) { // if UserID specified, grab and store it
		$output .= $responsearray['uid'] . "\t"; 
	}
	
	$dodgy = array("\r","\t","\n");
	
	// load questionnaire (so we know the questiontype for each question)
	$quid = "surveys/quest_" . $surveyid . ".xml";
	$loaded = loadQuest2($quid); // load questionnaire
	
	//print_r($loaded[questions]);
	//print_r($responsearray);
	
	//GO THROUGH THE QUESTIONNAIRE AND MATCH IT AGAINST $RESPONSEARRAY, to pick up blanks
	
	foreach((array)$loaded['questions'] as $qid => $q) { // step through each question...

		$combined = null; // initialise this variable
		
		switch($loaded['questions'][$qid]['type']) {
		
			case "single" :
			
				if (is_array($q['scale'])) { // grid				
					// then data will come in an array of the form: questionoption -> scalepointvalue
					foreach((array)$q[options] as $opt) {
						$thisoptid = idWord($opt);
						$combined .= ($responsearray[data][$qid][$thisoptid]) ? $responsearray[data][$qid][$thisoptid] . "\t" : "\t"; // if there is response data for this option, add it; else, move on
					}
					$output .= $combined;
				} else { // flat single
					// then data will come in the form: value
					if (is_array($responsearray[data][$qid])) { // an other, with a code + other text
						$output .= @implode("\t",$responsearray[data][$qid]) . "\t"; // effectively add a new col in the data file for the 'other'		
					} else { // a standard code-only value
						$output .= $responsearray[data][$qid] . "\t";
					}
				}
			
			 break;
			
			case "dropdown" :
			
				$output .= $responsearray[data][$qid] . "\t";
			
			 break;
			 
			 case "multi" :
			
				if (is_array($q['scale'])) { // grid				
					// then data will come in an array of the form: questionoption -> array (scalepointvalue -> TRUE)
					foreach((array)$q[options] as $opt) {
						$thisoptid = idWord($opt);
						foreach((array)$q[scale] as $scpt) {
							$thisscptid = idWord($scpt);
							$combined .= ($responsearray[data][$qid][$thisoptid][$thisscptid]) ? $responsearray[data][$qid][$thisoptid][$thisscptid] . "\t" : "\t"; // if there is response data for this option, add it; else, move on
						}
					}
					$output .= $combined;
				} else { // flat multi (but still in an array form, showing which boxes checked)
					// then data will come in an array of the form: questionoption -> TRUE
					foreach((array)$q[options] as $opt) {
						$thisoptid = idWord($opt);
						if (eregi("other_specify:",$opt)) { // this is an other_specify option
							$combined .= ($responsearray[data][$qid][$thisoptid]) ? $responsearray[data][$qid][$thisoptid] . "\t" : "\t"; // if there is response data for this option, add it; else, move on
							$combined .= $responsearray[data][$qid][_other] . "\t";
						} else {
							$combined .= ($responsearray[data][$qid][$thisoptid]) ? $responsearray[data][$qid][$thisoptid] . "\t" : "\t"; // if there is response data for this option, add it; else, move on						
						}
					}
					$output .= $combined;
				}
				
			 break;
			 
			default : //anything else (in the form of a simple value - including a blank col for info/pagebreak questions)
			
				// clean up text and store in a single cell
				$output .= str_replace($dodgy," ",$responsearray[data][$qid]) . "\t";
			
			 break;
		
		}
	}
	
	$output = substr($output,0,-1) . "\n";	
	$filename = "surveys/data_" . $surveyid . ".dat";	
	if (!file_exists($filename)) { $chmod = TRUE;} // if data file doesn't exist, set a flag to CHMOD it for writing
	$open = fopen ($filename, "a+");
	if ($open) {	
		if (flock($open,LOCK_EX)) {
			fwrite ($open, $output);	
			flock ($open, LOCK_UN);
		}
		fclose ($open);	
		if ($chmod) { @chmod($filename,0777); } // is this a good idea?
		return ($output);			
	} else {
		die("<p>Unable to save response data to file.</p>");
	}
}

function makeFieldRow($surveyid,$mode="export") { // makes a tab-delimited row of fields/options/scale points to put at the top of a data file export
	$output = "Submitted" . "\t"; 
	$output .= "User ID" . "\t"; 

	$dodgy = array("\r","\t","\n");
	
	// load questionnaire (so we know the questiontype for each question)
	$quid = "surveys/quest_" . $surveyid . ".xml";
	$loaded = loadQuest2($quid); // load questionnaire
	
	foreach((array)$loaded['questions'] as $qid => $q) { // step through each question...

		$combined = null; // initialise this variable
		
		switch($loaded['questions'][$qid]['type']) {
		
			case "single" :
				if (is_array($q['scale'])) { // grid				
					foreach((array)$q[options] as $opt) {
						if ($mode == "array") {
							$combined .= $qid . "_" . idWord($opt) . "\t";						
						} else {
							$combined .= "q" . $qid . " [" . str_replace($dodgy," ",$opt) . "]\t"; // square brackets = a scale point
						}
					}
					$output .= $combined;
				} else { // flat single
					if (eregi("other_specify:",@implode("",$q[options]))) { // is there an other in the options list?
						$output .= ($mode == "array") ? $qid . "\tother_" . $qid . "\t" : "q" . $qid . "\tother_" . "q" . $qid . "\t";
					} else {
						$output .= ($mode == "array") ? $qid . "\t" : "q" . $qid . "\t";
					}
				}
			 break;
			
			case "dropdown" :
				$output .= ($mode == "array") ? $qid . "\t" : "q" . $qid . "\t";
			break;

			case "multi" :
				if (is_array($q['scale'])) { // grid				
					foreach((array)$q[options] as $opt) {
						foreach((array)$q[scale] as $scpt) {
							if ($mode == "array") {
								$combined .= $qid . "_" . idWord($opt) . "_" .idWord($scpt) . "\t";							
							} else {
								$combined .= "q" . $qid . " [" . str_replace($dodgy," ",$opt) . "](" . str_replace($dodgy," ",$scpt) . ")\t";
							}
						}
					}
					$output .= $combined;
				} else { // flat multi (but still in an array form, showing which boxes checked)
					foreach((array)$q[options] as $opt) {
						if (eregi("other_specify:",$opt)) { // this is an other_specify option
							$combined .= ($mode == "array") ? $qid . "_" . idWord($opt) . "\tother_" . $qid . "\t": "q" . $qid . " (" . str_replace($dodgy," ",$opt) . ")\tother_" . $qid . "\t"; // round brackets = a multi option (T/F)												
						} else {
							$combined .= ($mode == "array") ? $qid . "_" . idWord($opt) . "\t" : "q" . $qid . " (" . str_replace($dodgy," ",$opt) . ")\t"; // round brackets = a multi option (T/F)						
						}
					}
					$output .= $combined;
				}
			 break;
			 
			default : //anything else (in the form of a simple value - including a blank col for info/pagebreak questions)
				if ($mode == "array") {
					$output .= $qid . "\t";
				} else {
					$output .= "q" . $qid . "\t";
				}
		 	break;
		
		}
	}
	if ($mode == "array") {
		$output = substr($output,0,-1);	
	} else {
		$output = substr($output,0,-1) . "\n";		
	}
	return ($output);	
}

function makeQuestionRow($surveyid) { // makes a tab-delimited row of fields/options/scale points to put at the top of a data file export
	$output = "\t\t"; // skip cols for Submitted data and User ID
	$dodgy = array("\r","\t","\n");
	
	// load questionnaire (so we know the questiontype for each question)
	$quid = "surveys/quest_" . $surveyid . ".xml";
	$loaded = loadQuest2($quid); // load questionnaire
	
	foreach((array)$loaded['questions'] as $qid => $q) { // step through each question...
		
		switch($loaded['questions'][$qid]['type']) {
		
			case "single" :
				if (is_array($q['scale'])) { // grid				
					foreach((array)$q[options] as $opt) {
						$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . " " . $opt . "\t";
					}
				} else { // flat single
					if (eregi("other_specify:",@implode("",$q[options]))) { // is there an other in the options list?
						$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . "\tOther comments:\t"; // add an extra col for the other_specify comments
					} else {
						$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . "\t";
					}
				}
			 break;
			
			case "dropdown" :
				$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . "\t";
			break;

			case "multi" :
				if (is_array($q['scale'])) { // grid				
					foreach((array)$q[options] as $opt) {
						foreach((array)$q[scale] as $scpt) {
							$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']). " " . $opt . " - " . $scpt . "\t";
						}
					}
				} else { // flat multi (but still in an array form, showing which boxes checked)
					foreach((array)$q[options] as $opt) {
						if (eregi("other_specify:",$opt)) { // this is an other_specify option
							$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . " " . $opt . "\tOther comments:\t";
						} else {
							$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . " " . $opt . "\t";
						}
					}
				}
			 break;
			 
			default : //anything else (in the form of a simple value - including a blank col for info/pagebreak questions)
				$output .= str_replace($dodgy," ",$loaded['questions'][$qid]['questiontext']) . "\t";
		 	break;
		}
	}
	$output = substr($output,0,-1) . "\n";		
	return ($output);	
}

function idWord($string) { // tidies up a string so it can be used as a field label
  $okchars = "abcdefghijklmnopqrstuvwxyz1234567890";
  for($a=0;$a<strlen($string);$a++) {
    if (@eregi(addslashes($string{$a}),$okchars)) {
      $output .= $string{$a};
    }
  }
  return($output);
}

function findBreak($currentstartid,$direction,$questionnaire) { // returns the id of the preceding or subsequent page break, for use in next/prev buttons	
	$breaks[] = 0; // put the start in as break 0
	
    foreach((array)$questionnaire as $id => $v) {
      if ($v[type] == "pagebreak") {
        $breaks[] = $id;
      }
    }
    $lastq = @array_pop($questionnaire);
    
	$breaks[] = $lastq[questionid]+1; // put the start in as break 0

    $lastbreak = ($currentstartid>0) ? $currentstartid-1 : 0;

	//print_r($breaks);
	
    if ($direction == "next") {
		for($a=0;$a<count($breaks);$a++) {
		  if ($breaks[$a] == $lastbreak) {
		    return ($breaks[$a+1])+1;
		  }
		}
	} else { // find previous
		for($a=0;$a<count($breaks);$a++) {
		  if ($breaks[$a] == $lastbreak) {
		    return ($breaks[$a-1])+1;
		  }
		}

	}
}

function cleanOptions($rawstring,$replace,$delimiter="|") {
	$output = null;
	foreach ($rawstring as $v) {
		if (strlen(trim($v))>0) {
			$output .= str_replace($replace,"",$v) . $delimiter;
		}
	}
	$output = substr($output,0,-1);

	return ($output);
}

if (!function_exists('array_combine')) { // for PHP4 compatibility
  function array_combine($keys, $values) {
   $keys = @array_flip($keys); // for some reason...
   foreach((array)$keys as $key=>$value) $out[$key] = @array_shift($values);
   return $out;
  }
}

function makeResultTable($q,$thisqid,$calcPercentageOnAll="TRUE") {
    
    global $loadedq; // the questionnaire
    global $stats; // the calculatated counts based on $data2
    global $data2; // the response array
    global $respcount; // the number of respondents in each subgroup
    global $othervals; // a handy array of other_specify values by question
    global $questiontypes; // a quick lookup array to label questions by type
    global $blanks; // simple counter per question id of how many blank responses, to take out of bases/percentages
    
    //$calcPercentageOnAll = "FALSE"; // set to true to calc per-question bases on all forms, not just non-blank responses
    
    //print_r($blanks);
    
    if ($q['type'] == "single" || $q['type'] == "dropdown" || $q['type'] == "multi" || $q['type'] == "bigbox" || $q['type'] == "smallbox") {

      $table .= "\n<p class='wording'><strong><span class='questionnumber'>{$q['questionid']}. </span>{$q['questiontext']}</strong> <span class='questiontype'><em>{$questiontypes[$q[type]]}</em></span></p>";
 
      // make table header
      $table .= "\n<table class='results'>\n<thead><tr><th class='col_option'>Option:</th><th>TOTAL</th>";

      foreach((array)$loadedq['questions'][$_REQUEST['xtab']]['options'] as $xto) {
		$table .= "<th>{$xto}</th>";
      	$xto = idWord($xto);
      	$xtbase .= "<th>(".$respcount[$xto].")</th>";
      }
      $table .= "</tr><tr><th></th><th>(".(count($data2)-$blanks[$thisqid]).")</th>{$xtbase}</tr></thead>\n<tbody>\n";

      // populate table row/columns

      $colcount = count($loadedq['questions'][$_REQUEST['xtab']]['options']) + 1; // count the total number of cols -1 so we can use this in a colspan attribute for header rows
      
      if ($loadedq['questions'][$thisqid]['type'] == "smallbox" || $loadedq['questions'][$thisqid]['type'] == "bigbox") { // an open text question
        
        if (strlen($_REQUEST['xtab'])>0) {
			foreach((array)$loadedq['questions'][$_REQUEST['xtab']]['options'] as $xto) {
			  $xto2 = idWord($xto);
			  $table .= "<tr><td class='questionoption'><strong>Comments ({$xto}):</strong></td><td colspan='{$colcount}'>".($stats[$xto2][$thisqid])."</td></tr>";
			}        
        } else { // no cross tabs, so just show comments in total col
		    $table .= "<tr><td class='questionoption'><strong>Comments:</strong></td><td colspan='{$colcount}'>".($stats[Total][$thisqid])."</td></tr>";        
        }

       $base = count($data2) - $blanks[$thisqid];

      } else {
        foreach((array)$loadedq['questions'][$thisqid]['options'] as $qo) {
	      
	      if (eregi("other_specify:",$qo)) { // this row is 'other specify', so show the values entered
	      	$qo_id = idWord($qo);
	        //$othervalues = "<span class='othervalues'>"hide@address.com(", ",$othervals[$thisqid][$qo_id])."</span>";
	        $othervalues = "<span class='othervalues'><em>Responses include:</em> ".substr(@implode(", ",$othervals[$thisqid]),0,255)."</span>";
		  } else {
	      	$othervalues = null;
	      }
	      
	      $table .= "<tr><td class='questionoption'><strong>{$qo}</strong>{$othervalues}</td>";	
	  		if (count($loadedq['questions'][$thisqid]['scale'])>0) { // this is a grid, so split out options as subrows
				$table .= "<td colspan='{$colcount}'></td></tr>\n"; // end the option row and blank out the rest of the row
				foreach((array)$loadedq['questions'][$thisqid]['scale'] as $scpt) {
					$table .= "<tr class='subrow'><td>&nbsp;<em>{$scpt}</em></td>";
					$ido = idWord($qo);
					$ids = idWord($scpt);
					if ($calcPercentageOnAll == "TRUE") { // use the total number of submitted responses, including blanks
						$percent = ($stats[Total][$thisqid][$ido][$ids]>0) ? round($stats[Total][$thisqid][$ido][$ids]/count($data2)*100) . "%": null;	
					} else { // calc percentages on the number of non-blank responses to this question
						$percent = ($stats[Total][$thisqid][$ido][$ids]>0) ? round($stats[Total][$thisqid][$ido][$ids]/(count($data2)-$blanks[$thisqid])*100) . "%": null;					
					}
					$table .= "<td class='total'>";
					if ($_REQUEST['show'] == "count" || $_REQUEST['show'] == "both" ) { $table .= $stats[Total][$thisqid][$ido][$ids]; }
					if ($_REQUEST['show'] == "percentage" || $_REQUEST['show'] == "both" ) { $table .= "<span class='percentage'>" . $percent . "</span>"; }
					$table .= "</td>";
		
					foreach((array)$loadedq['questions'][$_REQUEST['xtab']]['options'] as $xto) {
						$xto = idWord($xto);
						$xtopercent = ($stats[$xto][$thisqid][$ido][$ids]>0) ? round($stats[$xto][$thisqid][$ido][$ids]/$respcount[$xto]*100) . "%" : null;
						$table .= "<td class='subgroup'>";
						if ($_REQUEST['show'] == "count" || $_REQUEST['show'] == "both" ) { $table .= $stats[$xto][$thisqid][$ido][$ids]; }
						if ($_REQUEST['show'] == "percentage" || $_REQUEST['show'] == "both" ) { $table .= "<span class='percentage'>". $xtopercent . "</span>"; }
						$table .= "</td>";	
					}
					$table .= "</tr>\n";
				}
	  	  	} else { // just a one-dimensional questions
				$ido = idWord($qo);		
				if ($calcPercentageOnAll == "TRUE") { // use the total number of submitted responses, including blanks
					$percent = ($stats[Total][$thisqid][$ido]>0) ? round($stats[Total][$thisqid][$ido]/count($data2)*100) . "%" : null;	
				} else { // calc percentages on the number of non-blank responses to this question
					$percent = ($stats[Total][$thisqid][$ido]>0) ? round($stats[Total][$thisqid][$ido]/(count($data2)-$blanks[$thisqid])*100) . "%" : null;	
				}
				$table .= "<td class='total'>";
				if ($_REQUEST['show'] == "count" || $_REQUEST['show'] == "both" ) { $table .= $stats[Total][$thisqid][$ido]; }
				if ($_REQUEST['show'] == "percentage" || $_REQUEST['show'] == "both" ) { $table .= "<span class='percentage'>" . $percent . "</span>"; }
				$table .= "</td>";
				
				foreach((array)$loadedq['questions'][$_REQUEST['xtab']]['options'] as $xto) {
					$xto = idWord($xto);
					$xtopercent = ($stats[$xto][$thisqid][$ido]) ? round($stats[$xto][$thisqid][$ido]/$respcount[$xto]*100)."%" : null;	
					$table .= "<td class='subgroup'>";
					if ($_REQUEST['show'] == "count" || $_REQUEST['show'] == "both" ) { $table .= $stats[$xto][$thisqid][$ido]; }
					if ($_REQUEST['show'] == "percentage" || $_REQUEST['show'] == "both" ) { $table .= "<span class='percentage'>" . $xtopercent . "</span>"; }
					$table .= "</td>";
				}
	 			$table .= "</tr>\n";	
	 		}
        }
      }
      $base = count($data2) - $blanks[$thisqid];
      $table .= "</tbody></table>\n<p class='base'>Base: ".$base." out of ".count($data2)." people answered this question</p>\n\n";
    }
    
    return ($table);
}

function makeRespondentResultsTable($data_array="",$surveyid) {

	$fields = makeFieldRow($surveyid,"array");
	$fields = @explode("\t",$fields);
	//print_r($fields);

	$data = @array_combine($fields,$data_array); // merge the arrays, with $fields as the keys and $thisresp as the values (PHP5 only)
	
	//print_r($data);

	foreach((array)$data as $qid => $qval) {
		if (eregi("_other$",$qid)) { // an other_specify
			$keys = explode("_",$qid);
			$data2[$keys[1]][$keys[0]] = $qval;
		} elseif (eregi("_",$qid)) { // an element containing a grid/multi answer
			$keys = explode("_",$qid);
			if (count($keys)>2) { // a multi grid
				$data2[$keys[0]][$keys[1]][$keys[2]] = $qval;					
			} else {
				$data2[$keys[0]][$keys[1]] = $qval;		
			}
		} else {
			$data2[$qid] = $qval;
		}
	}

	$outputtable .= "<tr style='background:#eef;'><td style=\"color: #888;\">Questionnaire submitted on:</td><td>{$data['Submitted']}</td></tr>\n";
	$outputtable .= "<tr style='background:#eef;'><td style=\"color: #888;\">Respondent ID:</td><td>{$data['User ID']}</td></tr>\n";
	
	// load questionnaire
	$sid = "surveys/quest_" . $surveyid . ".xml";
	$loaded = loadQuest2($sid);

	//print_r($loaded);
	
	for($a=1;$a<=count($loaded['questions']);$a++) { // find right question
		
		$rowoutput = null;
		
		$v = $loaded['questions'][$a];
		$wording = strip_tags($v[questiontext]);
		
		$other = null;
		
		if ($v[type] == "multi" && count($v[scale])>0) { // a multi grid
			$rowoutput .= "<ul class='respondentreportlist'>";
			foreach((array)$data2[$a] as $k => $val) {
				$rowoutput .= "<li class='respondentanswer'>{$loaded[questions][$a][options][$k]}:</li>\n<ul>";
				foreach((array)$val as $mk => $mval) {
					$mval = ($mval == "TRUE") ? "<strong>YES</strong>" : "";
					$rowoutput .= "<li class='respondentanswer'>{$loaded[questions][$a][scale][$mk]}: {$mval}</li>\n";
				}
				$rowoutput .= "</ul>";
			}
			$rowoutput .= "</ul>";
		
		} elseif ($v[type] == "single" && count($v[scale])>0) { // a single scale 
			$rowoutput .= "<ul class='respondentreportlist'>";
			foreach((array)$data2[$a] as $k => $val) {
				$rowoutput .= "<li class='respondentanswer'>{$loaded[questions][$a][options][$k]}: {$val}</li>\n";
			}
			$rowoutput .= "</ul>";
		} elseif ($v[type] == "multi") { // a flat multi 
			$rowoutput .= "<ul class='respondentreportlist'>";
			foreach((array)$data2[$a] as $k => $val) {
				$other = null;
				if (eregi("otherspecify",$k)) { // this is an other_specify, so look in the 'other' array element for data
					$other = (strlen($data2[other][$a])>0) ? " (".htmlentities($data2[other][$a]).")" : null;
				}
				
				$val = ($val == "TRUE") ? "<strong>YES</strong>" : "";
				$rowoutput .= "<li class='respondentanswer'>{$loaded[questions][$a][options][$k]}: {$val}{$other}</li>\n";
			}
			$rowoutput .= "</ul>";
		} elseif (($v[type] == "info") || ($v[type] == "pagebreak")) { // no data
			$wording = "<span class='questionnumber'>PAGEBREAK/INFO NODE ONLY</span>";
		} else { // something else - a plain single, dropdown or big/smallbox
			if (eregi("other_specify:",$data2[$a])) { // this is an other_specify, so look in the 'other' array element for data
				$other = (strlen($data2[other][$a])>0) ? " (".htmlentities($data2[other][$a]).")" : null;
			}				
			$rowoutput = htmlentities($data2[$a]) . $other;		
		}
		
		$outputtable .= "
		<tr>
			<td width=\"50%\" valign=\"top\" style=\"color: #888;\"><span class='questionnumber'>q{$v[questionid]}. </span>{$wording}</td>
			<td width=\"50%\" valign=\"top\">$rowoutput</td>
		</tr>\n";
	}

	$output = "<table class=\"simpletable\" style='margin: 0 auto;width:90%;'>$outputtable</table>";

	return ($output);
}

function validEmail($string) {

	if (strlen($string)>0 && @eregi("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$",$string)) {
		return true;
	} else {
		return false;
	}
}

function backupProject($projectid,$projectname,$toemail,$sender="hide@address.com") {

	$headers = "Return-Path: {$sender}\r\n";
	$headers .= "Reply-To: {$sender}\r\n";
	$headers .= "From: {$sender}\r\n";

	$to = $toemail;
	$returnpath = $sender;
	$from = $sender;
	$subject = "Backup of AskPeople project files for {$projectname} project"; 		
	$message = "Dear AskPeople User,\r\n\r\nPlease find attached the backup copies of files from your {$projectname} project.\r\n\r\nBest regards\r\nAskPeople\r\n";

	// backup questionnaire
	 $files['questionnaire'] = "surveys/quest_".$projectid.".xml";
	// backup datafile
	 $files['datafile'] = "surveys/data_".$projectid.".dat";
	// backup config file
	 $files['configfile'] = "surveys/config_".$projectid.".php";
	// backup template used for this project
	 $loaded_polldata = stripslashes(file_get_contents($files['questionnaire']));	
 	 preg_match_all("/<template>(.*?)<\/template>/si",$loaded_polldata,$poll_template);
 	 $files['template'] = "templates/".trim($poll_template[1][0]);
	
	 if (file_exists($files['questionnaire'])) {
		$attachments['questionnaire'] = chunk_split(base64_encode(file_get_contents($files['questionnaire'])),76,"\r\n");
	 }
	 if (file_exists($files['datafile'])) {
		$attachments['datafile'] = chunk_split(base64_encode(file_get_contents($files['datafile'])),76,"\r\n");
	 }
	 if (file_exists($files['configfile'])) {
		$attachments['configfile'] = chunk_split(base64_encode(file_get_contents($files['configfile'])),76,"\r\n");
	 }
	 if (file_exists($files['template'])) {
		$attachments['template'] = chunk_split(base64_encode(file_get_contents($files['template'])),76,"\r\n");
	 }
	
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: multipart/mixed; boundary=askpeople12345\r\n";

	$fullmessage .= "--askpeople12345\r\n";

	$fullmessage .= "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n";
	$fullmessage .= "Content-Transfer-Encoding: 7bit\r\n";
	$fullmessage .= "\r\n" . $message ."\r\n";
	$fullmessage .= "--askpeople12345\r\n";
	$fullmessage .= "Content-Type: text/plain;\r\n";
	$fullmessage .= "Content-Disposition: attachment; filename=\"".$files['questionnaire']."\"\r\n";
	$fullmessage .= "Content-Transfer-Encoding: base64\r\n";
	$fullmessage .= "\r\n" . $attachments['questionnaire']. "\r\n";

	$fullmessage .= "--askpeople12345\r\n";
	$fullmessage .= "Content-Type: text/plain;\r\n";
	$fullmessage .= "Content-Disposition: attachment; filename=\"".$files['datafile']."\"\r\n";
	$fullmessage .= "Content-Transfer-Encoding: base64\r\n";
	$fullmessage .= "\r\n" . $attachments['datafile']. "\r\n";

	$fullmessage .= "--askpeople12345\r\n";
	$fullmessage .= "Content-Type: text/plain;\r\n";
	$fullmessage .= "Content-Disposition: attachment; filename=\"".$files['configfile']."\"\r\n";
	$fullmessage .= "Content-Transfer-Encoding: base64\r\n";
	$fullmessage .= "\r\n" . $attachments['configfile']. "\r\n";

	$fullmessage .= "--askpeople12345\r\n";
	$fullmessage .= "Content-Type: text/plain;\r\n";
	$fullmessage .= "Content-Disposition: attachment; filename=\"".$files['template']."\"\r\n";
	$fullmessage .= "Content-Transfer-Encoding: base64\r\n";
	$fullmessage .= "\r\n" . $attachments['template']. "\r\n";

	$fullmessage .= "--askpeople12345--";

	if ($to != "" && $subject != "" && $from != "" && $fullmessage != "") { // must be complete
		if (mail($to,$subject,$fullmessage,$headers,"-f$returnpath")) {
			return(true);
		} else {
			return(false);
		}
	} else {
		return(false);
	}

}

?>
Return current item: AskPeople-Free PHP survey application