3 * GForge Survey HTML Facility
5 * Copyright 2004 GForge, LLC
12 By Sung Kim, GForge, 02/2004
15 require_once('pre.php');
16 require_once('note.php');
19 * Survey HTML related functions
21 class SurveyHTML extends Error {
26 function SurveyHTML() {
33 function header($params) {
34 global $group_id,$is_admin_page,$HTML,$Language,$sys_use_survey;
36 if (!$sys_use_survey) {
40 $params['toptab']='surveys';
41 $params['group']=$group_id;
43 if ($project =& group_get_object($group_id)){
44 if (!$project->usesSurvey()) {
45 exit_error($Language->getText('general','error'), $Language->getText('survey_utils','error_this_group_has_turned_off'));
48 site_project_header($params);
50 if ($is_admin_page && $group_id) {
53 $Language->getText('group','short_survey'),
54 $Language->getText('survey_utils','admin'),
55 $Language->getText('survey_utils','edit_survey'),
56 $Language->getText('survey_utils','edit_questions'),
57 $Language->getText('survey_utils','show_results')
60 '/survey/?group_id='.$group_id,
61 '/survey/admin/?group_id='.$group_id,
62 '/survey/admin/survey.php?group_id='.$group_id,
63 '/survey/admin/question.php?group_id='.$group_id,
64 '/survey/admin/show_results.php?group_id='.$group_id
68 if (session_loggedin()) {
69 $perm =& $project->getPermission(session_get_user());
70 if ($perm && is_object($perm) && !$perm->isError() && $perm->isDocEditor()) {
74 $Language->getText('survey_utils','admin')
77 '/survey/admin/?group_id='.$group_id
83 }// end if (valid group id)
89 function footer($params) {
90 site_project_footer($params);
94 * Show Add/Modify Question Forums
95 * @param Survey Question Question Object
98 function showAddQuestionForm( &$q ) {
103 $title = $Language->getText('survey_add_question','title');
104 $question_button = $Language->getText('survey_add_question','add_this_question');
106 /* If we have a question object, it is a Modify */
107 if ($q && is_object($q) && !$q->isError() && $q->getID()) {
108 $title = $Language->getText('survey_edit_question','title');
109 $warning = '<span class="warning">'.
110 $Language->getText('survey_edit_question','warning_change_after_response').
112 $question_id = $q->getID();
113 $question = $q->getQuestion();
114 $question_type = $q->getQuestionType();
115 $question_button = $Language->getText('survey_edit', 'submit_changes');
118 $ret = '<h2>'. $title. '</h2>';
120 $ret.='<form action="'.getStringFromServer('PHP_SELF').'" method="post">';
121 $ret.='<input type="hidden" name="post" value="Y" />';
122 $ret.='<input type="hidden" name="group_id" value="'.$group_id.'" />';
123 $ret.='<input type="hidden" name="question_id" value="'.$question_id.'" />';
124 $ret.='<input type="hidden" name="form_key" value="' . form_generate_key() . '">';
125 $ret.=$Language->getText('survey_add_question','question').':<br />';
126 $ret.='<input type="text" name="question" value="'.$question.'" size="60" maxlength="150" />';
127 $ret.='<p>'. $Language->getText('survey_edit_question','question_type').':<br />';
129 $sql="SELECT * from survey_question_types";
130 $result=db_query($sql);
131 $ret.= html_build_select_box($result,'question_type',$question_type,false);
133 $ret.='</p><p><input type="submit" name="submit" value="'.$question_button.'"></p>';
140 * Show Add/Modify Question Forums
141 * @param Survey Question Question Object
144 function showAddSurveyForm( &$s) {
150 $title = $Language->getText('survey_add_survey','title');
151 $survey_button = $Language->getText('survey_add_survey','add_this_survey');
152 $active = ' checked="checked" ';
155 /* If we have a survey object, it is a Modify */
156 if ($s && is_object($s) && !$s->isError() && $s->getID()) {
157 $title = $Language->getText('survey_edit','title');
158 $warning = '<span class="warning">'.
159 $Language->getText('survey_edit','warning_survey_after_response').'</span>';
160 $survey_id = $s->getID();
161 $survey_title = $s->getTitle();
162 $survey_questions = $s->getQuestionString();
163 $survey_button = $Language->getText('survey_edit', 'submit_changes');
164 if (!$s->isActive()) {
165 $inactive = 'checked ="checked" ';
170 $ret = '<h2>'. $title. '</h2>';
172 $ret.='<form action="'.getStringFromServer('PHP_SELF').'" method="post">';
173 $ret.='<input type="hidden" name="post" value="Y" />';
174 $ret.='<input type="hidden" name="group_id" value="'.$group_id.'" />';
175 $ret.='<input type="hidden" name="survey_id" value="'.$survey_id.'" />';
176 $ret.='<input type="hidden" name="survey_questions" value="'.$survey_questions.'" />';
177 $ret.='<input type="hidden" name="form_key" value="' . form_generate_key() . '">';
178 $ret.='<strong>'. $Language->getText('survey_add_survey','name_of_survey').'</strong>' .utils_requiredField();
179 $ret.= '<input type="text" name="survey_title" value="'.$survey_title.'" length="60" maxlength="150" /><p>';
181 $ret.='<p><strong>'. $Language->getText('survey_add_survey','is_active').'</strong>';
182 $ret.='<br /><input type="radio" name="is_active" value="1"' .$active. '/>'.$Language->getText('survey_add_survey','yes');
183 $ret.='<br /><input type="radio" name="is_active" value="0"' .$inactive. '/>'.$Language->getText('survey_add_survey','no');
185 $arr_to_add = & $s->getAddableQuestionInstances();
186 $arr_to_del = & $s->getQuestionInstances();
188 if (count($arr_to_add)>0) {
189 $ret.='<p><strong>'. $Language->getText('survey_edit','addable_question').'</strong>';
190 $title_arr[] = " ";
191 $title_arr[] = $Language->getText('survey_index', 'survey_questions');
192 $title_arr[] = " ";
193 $ret.=$GLOBALS['HTML']->listTableTop ($title_arr);
196 for($i = 0; $i < count($arr_to_add); $i++) {
198 if ($arr_to_add[$i]->isError()) {
199 echo $arr_to_add[$i]->getErrorMessage();
204 $ret.= "<tr ". $GLOBALS['HTML']->boxGetAltRowStyle($i) .">\n";
207 $ret.= '<td><input type="checkbox" name="to_add[]" value="'.$arr_to_add[$i]->getID().'">'.
208 $arr_to_add[$i]->getQuestion().'('.
209 $arr_to_add[$i]->getQuestionStringType().')</td>';
216 if (count($arr_to_add)>0) {
217 /* Fill the remain cells */
219 $ret.='<td> </td><td> </td></tr>';
220 } else if ($i%3==2) {
221 $ret.='<td> </td></tr>';
224 $ret.= $GLOBALS['HTML']->listTableBottom();
227 /* Deletable questions */
228 if (count($arr_to_del) > 0) {
229 $ret.='<p><strong>'. $Language->getText('survey_edit','existing_question').'</strong>';
230 $title_arr = array('Question ID', 'Question', 'Type', 'Order', 'Delete from this Survey');
231 $ret.=$GLOBALS['HTML']->listTableTop ($title_arr);
234 for($i = 0; $i < count($arr_to_del); $i++) {
235 if ($arr_to_del[$i]->isError()) {
236 echo $arr_to_del[$i]->getErrorMessage();
241 $ret.= "<tr ". $GLOBALS['HTML']->boxGetAltRowStyle($i) .">\n";
243 $ret.= '<td>'.$arr_to_del[$i]->getID().'</td>';
244 $ret.= '<td>'.$arr_to_del[$i]->getQuestion().'</td>';
245 $ret.= '<td>'.$arr_to_del[$i]->getQuestionStringType().'</td>';
246 $ret.= '<td><center>[<a href="survey.php?group_id='.$group_id.'&survey_id='.
247 $survey_id.'&is_up=1&updown=Y'.
248 '&question_id='.$arr_to_del[$i]->getID().'">Up</a>]';
249 $ret.= '[<a href="'.$GLOBALS['sys_urlprefix'].'/survey/admin/survey.php?group_id='.$group_id.'&survey_id='.
250 $survey_id.'&is_up=0&updown=Y'.
251 '&question_id='.$arr_to_del[$i]->getID().'">Down</a>]</center></td>';
253 $ret.= '<td><center><input type="checkbox" name="to_del[]" value="'.$arr_to_del[$i]->getID().'"></center></td>';
258 if (count($arr_to_del)) {
259 $ret.= $GLOBALS['HTML']->listTableBottom();
262 /* Privous style question input text box. deprecated.
263 $ret.= $Language->getText('survey_add_survey','list_questions_numbers');
264 $ret.='<br /><input type="text" name="survey_questions" value="" length="90" maxlength="1500" /></p>';
267 $ret.='<p><input type="submit" name="submit" value="'.$survey_button.'"></p>';
274 * Show list of questions
276 function ShowQuestions(&$questions) {
280 $ret = "<h3>" . count($questions).' '.$Language->getText('survey_show_questions','found',array($rows))."</h3>";
282 /* Head information */
283 $title_arr = array ('Question ID', 'Question', 'Type', 'Edit/Delete');
284 $ret.=$GLOBALS['HTML']->listTableTop ($title_arr);
286 for($i = 0; $i < count($questions); $i++) {
287 if ($questions[$i]->isError()) {
288 echo $questions[$i]->getErrorMessage();
292 $ret.= "<tr ". $GLOBALS['HTML']->boxGetAltRowStyle($i) .">\n";
293 $ret.= "<td><a href=\"question.php?group_id=$group_id&question_id=".
294 $questions[$i]->getID()."\">".$questions[$i]->getID()."</a></td>\n";
296 $ret.= '<td>'.$questions[$i]->getQuestion().'</td>';
297 $ret.= '<td>'.$questions[$i]->getQuestionStringType().'</td>';
299 /* Edit/Delete Link */
300 $ret.= "<td>[<a href=\"question.php?group_id=$group_id&question_id=".$questions[$i]->getID().'">';
301 $ret.= $Language->getText('survey_admin', 'edit').'</a>] ';
302 $ret.= "[<a href=\"question.php?delete=Y&group_id=$group_id&question_id=".$questions[$i]->getID().'">';
303 $ret.= $Language->getText('survey_admin', 'delete').'</a>]</td>';
307 $ret.= $GLOBALS['HTML']->listTableBottom();
312 * Show list of surveys
314 * Show surveys with many options
315 * have to set $user_id to get the right show_vote option
319 function ShowSurveys(&$surveys, $show_id=0, $show_questions=0,
320 $show_number_questions=0, $show_number_votes=0,
321 $show_vote=0, $show_edit=0, $show_result=0,
322 $show_result_graph=0, $show_result_comment=0,
328 $ret = '<h2>'. $Language->getText('survey_edit','existing_surveys'). '</h2>';
330 /* Head information */
332 $title_arr[] = $Language->getText('survey_index', 'survey_id');
335 $title_arr[] = $Language->getText('survey_index', 'survey_title');
337 if ($show_questions) {
338 $title_arr[] = $Language->getText('survey_index', 'survey_questions');
340 if ($show_number_questions) {
341 $title_arr[] = $Language->getText('survey_index', 'survey_number_questions');
343 if ($show_number_votes) {
344 $title_arr[] = $Language->getText('survey_index', 'survey_number_votes');
346 if ($show_vote && $user_id) {
347 $title_arr[] = $Language->getText('survey_index', 'survey_vote');
350 $title_arr[] = $Language->getText('survey_index', 'survey_edit');
353 $title_arr[] = $Language->getText('survey_index', 'survey_result');
355 if ($show_result_graph) {
356 $title_arr[] = $Language->getText('survey_index', 'survey_result_graph');
358 if ($show_result_comment) {
359 $title_arr[] = $Language->getText('survey_index', 'survey_result_comments');
362 $ret.=$GLOBALS['HTML']->listTableTop ($title_arr);
364 /* Color index for table */
366 for($i = 0; $i < count($surveys); $i++) {
367 if ($surveys[$i]->isError()) {
368 echo $surveys[$i]->getErrorMessage();
372 if (!$surveys[$i]->isActive()) {
373 if ($show_inactive) {
374 $strike_open="<strike>";
375 $strike_close="</strike>";
385 $ret.= "<tr ". $GLOBALS['HTML']->boxGetAltRowStyle($color_index++) .">\n";
387 $ret.= '<td>'.$surveys[$i]->getID().'</td>';
390 $ret.= '<td>'.$strike_open.'<a href="'.$GLOBALS['sys_urlprefix'].'/survey/survey.php?group_id='.$group_id.'&survey_id='.
391 $surveys[$i]->getID().'">'.$surveys[$i]->getTitle().'</A>'.$strike_close.'</td>';
393 if ($show_questions) {
394 $ret.= '<td>'.$surveys[$i]->getQuestionString().'</td>';
396 if ($show_number_questions) {
397 $ret.= '<td>'.$surveys[$i]->getNumberOfQuestions().'</td>';
399 if ($show_number_votes) {
400 $ret.= '<td>'.$surveys[$i]->getNumberOfVotes().'</td>';
402 if ($show_vote && $user_id) {
403 if ($surveys[$i]->isUserVote($user_id)) {
404 $ret.='<td>YES</td>';
410 /* Edit/Delete Link */
411 $ret.= "<td>[<a href=\"".$GLOBALS['sys_urlprefix']."/survey/admin/survey.php?group_id=$group_id&survey_id=".
412 $surveys[$i]->getID().'">';
413 $ret.= $Language->getText('survey_admin', 'edit').'</a>] ';
415 /* We don;t support delete yet. Need to delete all results as well */
417 $ret.= "[<a href=\"".$GLOBALS['sys_urlprefix']."/survey/admin/survey.php?delete=Y&group_id=$group_id&survey_id=".
418 $surveys[$i]->getID().'">';
419 $ret.= $Language->getText('survey_admin', 'delete').'</a>]
424 /* Edit/Delete Link */
425 $ret.= "<td>[<a href=\"".$GLOBALS['sys_urlprefix']."/survey/admin/show_results.php?group_id=$group_id&survey_id=".
426 $surveys[$i]->getID().'">';
427 $ret.= $Language->getText('survey_index', 'survey_result').'</a>]</td>';
429 if ($show_result_graph) {
430 /* Edit/Delete Link */
431 $ret.= "<td>[<a href=\"".$GLOBALS['sys_urlprefix']."/survey/admin/show_results.php?graph=yes&group_id=$group_id&survey_id=".
432 $surveys[$i]->getID().'">';
433 $ret.= $Language->getText('survey_index', 'survey_result_graph').'</a>]</td>';
435 if ($show_result_comment) {
436 /* Edit/Delete Link */
437 $ret.= "<td>[<a href=\"".$GLOBALS['sys_urlprefix']."/survey/admin/show_results.php?graph=yes&show_comment=yes&group_id=$group_id&survey_id=".$surveys[$i]->getID().'">';
438 $ret.= $Language->getText('survey_index', 'survey_result_comments').'</a>]</td>';
443 $ret.= $GLOBALS['HTML']->listTableBottom();
448 * Show survey form - Show all forums of Survey
450 function ShowSurveyForm( &$s ) {
455 if (!$s->isActive()) {
456 return '<span class="error">'. $Language->getText('survey_error','no_vote_for_inactive').'</span>';
458 /* Get questions of this survey */
459 $questions = & $s->getQuestionInstances();
462 if ($s->isUserVote(user_getid())) {
463 $ret.= '<span class="error">'. $Language->getText('survey','warning_double_vote').'</span>';
465 $ret.= '<form action="/survey/survey_resp.php" method="post">'.
466 '<input type="hidden" name="group_id" value="'.$group_id.'" />'.
467 '<input type="hidden" name="survey_id" value="'.$survey_id. '" />';
469 $ret.= '<h3>'.$s->getTitle().'</h3>';
470 $ret.= '<table border="0">';
472 /* Keep question numbers */
474 $last_question_type = "";
475 for($i = 0; $i < count($questions); $i++) {
476 if ($questions[$i]->isError()) {
477 echo $questions[$i]->getErrorMessage();
480 $question_type = $questions[$i]->getQuestionType();
481 $question_id = $questions[$i]->getID();
482 $question_title = stripslashes($questions[$i]->getQuestion());
484 if ($question_type == '4') {
485 /* Don't show question number if it's just a comment */
486 $ret.='<tr><td valign="top"> </td><td>';
488 $ret.= '<tr><td valign="top"><strong>';
489 /* If it's a 1-5 question box and first in series, move Quest number down a bit */
490 if (($question_type != $last_question_type) && (($question_type == '1') || ($question_type == '3'))) {
491 $ret.= ' <br />';
494 $ret.= $index++.' <br /></td><td>';
499 switch($question_type) {
500 case 1: /* This is a radio-button question. Values 1-5.
501 Show the 1-5 markers only if this is the first in a series */
502 if ($question_type != $last_question_type) {
503 $ret.=' <strong>1</strong>'.$Language->getText('survey','low').
504 ' <strong>5</strong>' .
505 $Language->getText('survey','high').'<br />';
508 for ($j=1; $j<=5; $j++) {
509 $ret.= '<input type="radio" name="_'.$question_id.'" value="'.$j.'" />';
512 $ret.= ' '.$question_title;
515 case 2: /* This is a text-area question. */
516 $ret.= $question_title.'<br />';
517 $ret.='<textarea name="_'.$question_id.'" rows="5" cols="60" wrap="soft"></textarea>';
519 case 3: /* This is a Yes/No question.
520 Show the Yes/No only if this is the first in a series */
521 if ($question_type != $last_question_type) {
522 $ret.= '<strong>Yes / No</strong><br />';
525 $ret.='<input type="radio" name="_'.$question_id.'" value="1" />';
526 $ret.='<input type="radio" name="_'.$question_id.'" value="5" />';
527 $ret.=' '.$question_title;
529 case 4: /* This is a comment only. */
530 $ret.= ' <br /><strong>'.util_make_links($question_title).'</strong>';
531 $ret.= '<input type="hidden" name="_'.$question_id.'" value="-666" />';
533 case 5: /* This is a text-field question. */
534 $ret.= $question_title. '<br />';
535 $ret.= '<input type="text" name="_'.$question_id.'" size="20" maxlength="70" />';
538 $ret.= $question_title. '<br />';
542 $last_question_type=$question_type;
545 $ret.='<tr><td align="center" colspan="2">'.
546 '<input type="submit" name="submit" value="'.$Language->getText('general','submit').'" />'.
547 '<br /><a href="'.$GLOBALS['sys_urlprefix'].'/survey/privacy.php">'.$Language->getText('survey','survey_privacy').'</a>'.
548 '</td></tr></form></table>';
557 * @param Object a Survey Response Factory
559 function ShowResult( &$sr, $show_comment=0, $q_num="", $show_graph=0) {
563 $Survey = $sr->getSurvey();
564 $Question = $sr->getQuestion();
568 $ret.= $q_num . '. ';
571 $ret.=$Question->getQuestion().'</strong><br />';
572 $results = $sr->getResults();
574 echo ($sr->getErrorMessage());
577 $totalCount = $sr->getNumberOfSurveyResponsess();
578 $votes = $Survey->getNumberOfVotes();
580 /* No votes, no result to show */
582 $ret.= '<ul><li/>'.$Language->getText('survey_show_results_aggregate','no_votes').'</ul>';
586 switch($Question->getQuestionType()) {
587 case 1: /* This is a radio-button question. Values 1-5.
588 Show the 1-5 markers only if this is the first in a series */
589 $arr_name=array('No Answer', 'Low 1', '2', '3', '4', 'High 5', 'No Answer');
590 $arr_color=array('black', 'red', 'blue', 'yellow', 'green', 'brown', 'black');
591 $results[0] = $votes - $results[1] - $results[2] - $results[3] - $results[4] - $results[5];
594 $url ='graphs.php?type=vbar';
595 for ($j=5; $j>=0; $j--) {
596 $percent = sprintf("%02.1f%%", (float)$results[$j]*100/$votes);
598 $url.='&legend[]='.urlencode($arr_name[$j].' ('. $percent.')');
599 $url.='&value[]='.urlencode($results[$j]);
601 $ret.= '<img border="0" src="'.$url.'" alt="Graph of '.$Question->getQuestion().'"></img>';
603 $ret.= '<dd><table border="0" cellspacing="0" cellpadding="0" width=100%>';
605 for ($j=5; $j>=0; $j--) {
606 $percent = (float)$results[$j]*100/$votes;
607 $ret.= $this->_makeBar($arr_name[$j].' ('.$results[$j].')', $percent, $arr_color[$j]);
609 $ret.= '</table></dd>';
614 case 3: /* This is a Yes/No question. */
616 $arr_name=array('', 'YES', 'NO', 'No Answer');
617 $arr_color=array('', 'red', 'blue', 'black');
619 $res[1] = $results[1]; /* Yes */
620 $res[2] = $results[5]; /* No */
621 $res[3] = $votes - $res[1] -$res[2];
624 $url ='graphs.php?type=pie';
625 for ($j=1; $j<=3; $j++) {
626 $url.='&legend[]='.urlencode($arr_name[$j].'('.$res[$j].')');
627 $url.='&value[]='.urlencode($res[$j]);
629 $ret.= '<img border="0" src="'.$url.'" alt="Graph of '.$Question->getQuestion().'"></img>';
631 $ret.= '<dd><table border="0" cellspacing="0" cellpadding="0" width=100%>';
632 for ($j=1; $j<=3; $j++) {
633 $result_per[$j] = (float)$res[$j]*100/$votes;
634 $ret.= $this->_makeBar($arr_name[$j].' ('.$res[$j].')', $result_per[$j], $arr_color[$j]);
636 $ret.= '</table></dd>';
641 case 4: /* This is a comment only. */
644 case 2: /* This is a text-area question. */
645 case 5: /* This is a text-field question. */
647 for($j=0; $j<$totalCount; $j++) {
648 $ret.='<hr.><strong>'.$Language->getText('survey_show_results_aggregate','comments').
649 ' # '.($j+1).'/'.$totalCount. '</strong><p/>';
651 $words = explode(" ",$results[$j]);
654 //print 100 chars in words per line
655 foreach ($words as $word) {
656 // if we have a stupidly strange word with lots of letters, we´ll make a new line for it and split it
657 if ( (strlen($word)>100) && ((strlen($word)+$linelength)>100)) {
658 $chunks = $this->split_str($word,50);
659 foreach ($chunks as $chunk) {
665 $linelength += strlen($word);
666 if ($linelength>100) {
677 $ret.='<ul><li><a href="show_results.php?survey_id='.$Survey->getID().
678 '&question_id='.$Question->getID().
679 '&group_id='.$group_id.'">'.
680 $Language->getText('survey_show_results_aggregate','view_comments', $totalCount).
693 * split_str - works as str_split of PHP5 - Converts a string to an array.
696 * @param int length of chunk
697 * @return array array of chunks of the string
699 function split_str($str,$split_lengt=1) {
701 for ($i=0;$i<$cnt;$i+=$split_lengt) {
702 $rslt[]= substr($str,$i,$split_lengt);
709 * _makeBar - make Precentage bar as a cell in a table. Starts with <tr> and ends with </tr>
711 * @param String name Name
712 * @param int percentage of the name
715 function _makeBar($name, $percent, $color) {
716 $ret = '<tr><td width="30%">'.$name.'</td><td>';
717 $ret.= '<table width="'.$percent.'%" border="0" cellspacing="0" cellpadding="0"><tr>';
719 $ret.='<td width="90%" bgcolor="'.$color.'"> </td>';
722 $ret.= '<td>'.sprintf("%.2f", $percent).'%</td></tr></table></td></tr\>'."\n";
730 // c-file-style: "bsd"