MDL-14679 fixed references to mod.html
[moodle.git] / mod / survey / lib.php
1 <?php // $Id$
3 // Graph size
4 $SURVEY_GHEIGHT = 500;
5 $SURVEY_GWIDTH  = 900;
7 $SURVEY_QTYPE = array (
8         "-3" => "Virtual Actual and Preferred",
9         "-2" => "Virtual Preferred",
10         "-1" => "Virtual Actual",
11          "0" => "Text",
12          "1" => "Actual",
13          "2" => "Preferred",
14          "3" => "Actual and Preferred",
15         );
18 define("SURVEY_COLLES_ACTUAL",           "1");
19 define("SURVEY_COLLES_PREFERRED",        "2");
20 define("SURVEY_COLLES_PREFERRED_ACTUAL", "3");
21 define("SURVEY_ATTLS",                   "4");
22 define("SURVEY_CIQ",                     "5");
25 // STANDARD FUNCTIONS ////////////////////////////////////////////////////////
27 function survey_add_instance($survey) {
28 // Given an object containing all the necessary data, 
29 // (defined by the form in mod_form.php) this function 
30 // will create a new instance and return the id number 
31 // of the new instance.
33     if (!$template = get_record("survey", "id", $survey->template)) {
34         return 0;
35     }
37     $survey->questions    = $template->questions; 
38     $survey->timecreated  = time();
39     $survey->timemodified = $survey->timecreated;
41     return insert_record("survey", $survey);
43 }
46 function survey_update_instance($survey) {
47 // Given an object containing all the necessary data, 
48 // (defined by the form in mod_form.php) this function 
49 // will update an existing instance with new data.
51     if (!$template = get_record("survey", "id", $survey->template)) {
52         return 0;
53     }
55     $survey->id           = $survey->instance; 
56     $survey->questions    = $template->questions; 
57     $survey->timemodified = time();
59     return update_record("survey", $survey);
60 }
62 function survey_delete_instance($id) {
63 // Given an ID of an instance of this module, 
64 // this function will permanently delete the instance 
65 // and any data that depends on it.  
67     if (! $survey = get_record("survey", "id", "$id")) {
68         return false;
69     }
71     $result = true;
73     if (! delete_records("survey_analysis", "survey", "$survey->id")) {
74         $result = false;
75     }
77     if (! delete_records("survey_answers", "survey", "$survey->id")) {
78         $result = false;
79     }
81     if (! delete_records("survey", "id", "$survey->id")) {
82         $result = false;
83     }
85     return $result;
86 }
88 function survey_user_outline($course, $user, $mod, $survey) {
89     if ($answers = get_records_select("survey_answers", "survey='$survey->id' AND userid='$user->id'")) {
91         $lastanswer = array_pop($answers);
93         $result->info = get_string("done", "survey");
94         $result->time = $lastanswer->time;
95         return $result;
96     }
97     return NULL;
98 }
101 function survey_user_complete($course, $user, $mod, $survey) {
102     global $CFG, $DB;
104     if (survey_already_done($survey->id, $user->id)) {
105         if ($survey->template == SURVEY_CIQ) { // print out answers for critical incidents
106             $table = NULL;
107             $table->align = array("left", "left");
109             $questions = $DB->get_records_list("survey_questions", "id", explode(',', $survey->questions));
110             $questionorder = explode(",", $survey->questions);
111             
112             foreach ($questionorder as $key=>$val) {
113                 $question = $questions[$val];
114                 $questiontext = get_string($question->shorttext, "survey");
115                 
116                 if ($answer = survey_get_user_answer($survey->id, $question->id, $user->id)) {
117                     $answertext = "$answer->answer1";
118                 } else {
119                     $answertext = "No answer";
120                 }
121                 $table->data[] = array("<b>$questiontext</b>", $answertext);
122             }
123             print_table($table);
124             
125         } else {
126         
127             survey_print_graph("id=$mod->id&amp;sid=$user->id&amp;type=student.png");
128         }
129         
130     } else {
131         print_string("notdone", "survey");
132     }
135 function survey_print_recent_activity($course, $viewfullnames, $timestart) {
136     global $CFG;
138     $modinfo = get_fast_modinfo($course);
139     $ids = array();
140     foreach ($modinfo->cms as $cm) {
141         if ($cm->modname != 'survey') {
142             continue;
143         }
144         if (!$cm->uservisible) {
145             continue;
146         }
147         $ids[$cm->instance] = $cm->instance;
148     }
150     if (!$ids) {
151         return false;
152     }
154     $slist = implode(',', $ids); // there should not be hundreds of glossaries in one course, right?
156     if (!$rs = get_recordset_sql("SELECT sa.userid, sa.survey, MAX(sa.time) AS time,
157                                          u.firstname, u.lastname, u.email, u.picture
158                                     FROM {$CFG->prefix}survey_answers sa
159                                          JOIN {$CFG->prefix}user u ON u.id = sa.userid
160                                    WHERE sa.survey IN ($slist) AND sa.time > $timestart
161                                    GROUP BY sa.userid, sa.survey, u.firstname, u.lastname, u.email, u.picture
162                                    ORDER BY time ASC")) {
163         return false;
164     }
166     $surveys = array();
168     while ($survey = rs_fetch_next_record($rs)) {
169         $cm = $modinfo->instances['survey'][$survey->survey];
170         $survey->name = $cm->name;
171         $survey->cmid = $cm->id;
172         $surveys[] = $survey;
173     } 
174     rs_close($rs);
176     if (!$surveys) {
177         return false;
178     }
180     print_headline(get_string('newsurveyresponses', 'survey').':');
181     foreach ($surveys as $survey) {
182         $url = $CFG->wwwroot.'/mod/survey/view.php?id='.$survey->cmid;
183         print_recent_activity_note($survey->time, $survey, $survey->name, $url, false, $viewfullnames);
184     }
185  
186     return true;
189 function survey_get_participants($surveyid) {
190 //Returns the users with data in one survey
191 //(users with records in survey_analysis and survey_answers, students)
193     global $CFG;
195     //Get students from survey_analysis
196     $st_analysis = get_records_sql("SELECT DISTINCT u.id, u.id
197                                     FROM {$CFG->prefix}user u,
198                                          {$CFG->prefix}survey_analysis a
199                                     WHERE a.survey = '$surveyid' and
200                                           u.id = a.userid");
201     //Get students from survey_answers
202     $st_answers = get_records_sql("SELECT DISTINCT u.id, u.id
203                                    FROM {$CFG->prefix}user u,
204                                         {$CFG->prefix}survey_answers a
205                                    WHERE a.survey = '$surveyid' and
206                                          u.id = a.userid");
208     //Add st_answers to st_analysis
209     if ($st_answers) {
210         foreach ($st_answers as $st_answer) {
211             $st_analysis[$st_answer->id] = $st_answer;
212         }
213     }
214     //Return st_analysis array (it contains an array of unique users)
215     return ($st_analysis);
218 // SQL FUNCTIONS ////////////////////////////////////////////////////////
221 function survey_log_info($log) {
222     global $CFG;
223     return get_record_sql("SELECT s.name, u.firstname, u.lastname, u.picture
224                              FROM {$CFG->prefix}survey s, 
225                                   {$CFG->prefix}user u
226                             WHERE s.id = '$log->info' 
227                               AND u.id = '$log->userid'");
230 function survey_get_responses($surveyid, $groupid, $groupingid) {
231     global $CFG;
233     if ($groupid) {
234         $groupsjoin = "INNER JOIN {$CFG->prefix}groups_members gm ON u.id = gm.userid AND gm.groupid = '$groupid' ";
236     } else if ($groupingid) {
237         $groupsjoin = "INNER JOIN {$CFG->prefix}groups_members gm ON u.id = gm.userid
238                        INNER JOIN {$CFG->prefix}groupings_groups gg ON gm.groupid = gg.groupid AND gg.groupingid = $groupingid ";
239     } else {
240         $groupsjoin = "";
241     }
243     return get_records_sql("SELECT u.id, u.firstname, u.lastname, u.picture, MAX(a.time) as time
244                             FROM {$CFG->prefix}survey_answers a
245                                 INNER JOIN {$CFG->prefix}user u ON a.userid = u.id
246                                 $groupsjoin
247                             WHERE a.survey = $surveyid
248                             GROUP BY u.id, u.firstname, u.lastname, u.picture
249                             ORDER BY time ASC");
252 function survey_get_analysis($survey, $user) {
253     global $CFG;
255     return get_record_sql("SELECT notes 
256                              FROM {$CFG->prefix}survey_analysis 
257                             WHERE survey='$survey' 
258                               AND userid='$user'");
261 function survey_update_analysis($survey, $user, $notes) {
262     global $CFG;
264     return execute_sql("UPDATE {$CFG->prefix}survey_analysis 
265                             SET notes='$notes' 
266                           WHERE survey='$survey' 
267                             AND userid='$user'");
271 function survey_get_user_answers($surveyid, $questionid, $groupid, $sort="sa.answer1,sa.answer2 ASC") {
272     global $CFG;
274     if ($groupid) {
275         $groupsql = "AND gm.groupid = $groupid AND u.id = gm.userid";
276     } else {
277         $groupsql = "";
278     }
280     return get_records_sql("SELECT sa.*,u.firstname,u.lastname,u.picture 
281                               FROM {$CFG->prefix}survey_answers sa, 
282                                    {$CFG->prefix}user u,
283                                    {$CFG->prefix}groups_members gm 
284                              WHERE sa.survey = '$surveyid' 
285                                AND sa.question = $questionid 
286                                AND u.id = sa.userid $groupsql
287                           ORDER BY $sort");
290 function survey_get_user_answer($surveyid, $questionid, $userid) {
291     global $CFG;
293     return get_record_sql("SELECT sa.* 
294                               FROM {$CFG->prefix}survey_answers sa
295                              WHERE sa.survey = '$surveyid' 
296                                AND sa.question = '$questionid' 
297                                AND sa.userid = '$userid'");
300 // MODULE FUNCTIONS ////////////////////////////////////////////////////////
302 function survey_add_analysis($survey, $user, $notes) {
303     global $CFG;
305     $record->survey = $survey;
306     $record->userid = $user;
307     $record->notes = $notes;
309     return insert_record("survey_analysis", $record, false);
312 function survey_already_done($survey, $user) {
313    return record_exists("survey_answers", "survey", $survey, "userid", $user);
316 function survey_count_responses($surveyid, $groupid, $groupingid) {
317     if ($responses = survey_get_responses($surveyid, $groupid, $groupingid)) {
318         return count($responses);
319     } else {
320         return 0;
321     }
325 function survey_print_all_responses($cmid, $results, $courseid) {
327     $table->head  = array ("", get_string("name"),  get_string("time"));
328     $table->align = array ("", "left", "left");
329     $table->size = array (35, "", "" );
331     foreach ($results as $a) {
332         $table->data[] = array(print_user_picture($a->id, $courseid, $a->picture, false, true, false),
333                "<a href=\"report.php?action=student&amp;student=$a->id&amp;id=$cmid\">".fullname($a)."</a>", 
334                userdate($a->time));
335     }
337     print_table($table);
341 function survey_get_template_name($templateid) {
342     global $DB;
344     if ($templateid) {
345         if ($ss = get_record("surveys", "id", $templateid)) {
346             return $ss->name;
347         }
348     } else {
349         return "";
350     }
355 function survey_shorten_name ($name, $numwords) {
356     $words = explode(" ", $name);
357     for ($i=0; $i < $numwords; $i++) {
358         $output .= $words[$i]." ";
359     }
360     return $output;
365 function survey_print_multi($question) {
366     global $USER, $DB, $qnum, $checklist, $DB;
368     $stripreferthat = get_string("ipreferthat", "survey");
369     $strifoundthat = get_string("ifoundthat", "survey");
370     $strdefault    = get_string('default');
371     $strresponses  = get_string('responses', 'survey');
373     print_heading($question->text, null, 3, 'questiontext');
374     echo "\n<table width=\"90%\" cellpadding=\"4\" cellspacing=\"1\" border=\"0\">";
376     $options = explode( ",", $question->options);
377     $numoptions = count($options);
379     $oneanswer = ($question->type == 1 || $question->type == 2) ? true : false;
380     if ($question->type == 2) {
381         $P = "P";
382     } else {
383         $P = "";
384     }
386     echo "<tr class=\"smalltext\"><th scope=\"row\">$strresponses</th>";
387     while (list ($key, $val) = each ($options)) {
388         echo "<th scope=\"col\" class=\"hresponse\">$val</th>\n";
389     }
390     echo "<th>&nbsp;</th></tr>\n";
392     if ($oneanswer) {
393         echo "<tr><th scope=\"col\" colspan=\"6\">$question->intro</th></tr>\n";
394     } else {
395         echo "<tr><th scope=\"col\" colspan=\"7\">$question->intro</th></tr>\n"; 
396     }
398     $subquestions = $DB->get_records_list("survey_questions", "id", explode(',', $question->multi));
400     foreach ($subquestions as $q) {
401         $qnum++;
402         $rowclass = survey_question_rowclass($qnum);
403         if ($q->text) {
404             $q->text = get_string($q->text, "survey");
405         }
407         echo "<tr class=\"$rowclass rblock\">";
408         if ($oneanswer) {
410             echo "<th scope=\"row\" class=\"optioncell\">";
411             echo "<b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
412             echo $q->text ."</th>\n";
413             for ($i=1;$i<=$numoptions;$i++) {
414                 $hiddentext = get_accesshide($options[$i-1]);
415                 $id = "q$P" . $q->id . "_$i";
416                 echo "<td><label for=\"$id\"><input type=\"radio\" name=\"q$P$q->id\" id=\"$id\" value=\"$i\" />$hiddentext</label></td>";
417             }
418             $default = get_accesshide($strdefault, 'label', '', "for=\"q$P$q->id\"");
419             echo "<td class=\"whitecell\"><input type=\"radio\" name=\"q$P$q->id\" id=\"q$P" . $q->id . "_D\" value=\"0\" checked=\"checked\" />$default</td>";
420             $checklist["q$P$q->id"] = $numoptions;
421         
422         } else { 
423             // yu : fix for MDL-7501, possibly need to use user flag as this is quite ugly.
424             echo "<th scope=\"row\" class=\"optioncell\">";
425             echo "<b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
426             $qnum++;
427             echo "<span class=\"preferthat smalltext\">$stripreferthat</span> &nbsp; ";
428             echo "<span class=\"option\">$q->text</span></th>\n";
429             for ($i=1;$i<=$numoptions;$i++) {
430                 $hiddentext = get_accesshide($options[$i-1]);
431                 $id = "qP" . $q->id . "_$i";
432                 echo "<td><label for=\"$id\"><input type=\"radio\" name=\"qP$q->id\" id=\"$id\" value=\"$i\" />$hiddentext</label></td>";
433             }
434             $default = get_accesshide($strdefault, 'label', '', "for=\"qP$q->id\"");
435             echo "<td><input type=\"radio\" name=\"qP$q->id\" id=\"qP$q->id\" value=\"0\" checked=\"checked\" />$default</td>";
436             echo "</tr>";
438             echo "<tr class=\"$rowclass rblock\">";
439             echo "<th scope=\"row\" class=\"optioncell\">";
440             echo "<b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
441             echo "<span class=\"foundthat smalltext\">$strifoundthat</span> &nbsp; ";
442             echo "<span class=\"option\">$q->text</span></th>\n";
443             for ($i=1;$i<=$numoptions;$i++) {
444                 $hiddentext = get_accesshide($options[$i-1]);
445                 $id = "q" . $q->id . "_$i";
446                 echo "<td><label for=\"$id\"><input type=\"radio\" name=\"q$q->id\" id=\"$id\" value=\"$i\" />$hiddentext</label></td>";
447             }
448             $default = get_accesshide($strdefault, 'label', '', "for=\"q$q->id\"");
449             echo "<td class=\"buttoncell\"><input type=\"radio\" name=\"q$q->id\" id=\"q$q->id\" value=\"0\" checked=\"checked\" />$default</td>";
450             $checklist["qP$q->id"] = $numoptions;
451             $checklist["q$q->id"] = $numoptions;            
452         }
453         echo "</tr>\n";
454     }
455     echo "</table>";
460 function survey_print_single($question) {
461     global $DB, $qnum;
463     $rowclass = survey_question_rowclass(0);
465     $qnum++;
467     echo "<br />\n";
468     echo "<table width=\"90%\" cellpadding=\"4\" cellspacing=\"0\">\n";
469     echo "<tr class=\"$rowclass\">";
470     echo "<th scope=\"row\" class=\"optioncell\"><label for=\"q$question->id\"><b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
471     echo "<span class=\"questioncell\">$question->text</span></label></th>\n";
472     echo "<td class=\"questioncell smalltext\">\n";
475     if ($question->type == 0) {           // Plain text field
476         echo "<textarea rows=\"3\" cols=\"30\" name=\"q$question->id\" id=\"q$question->id\">$question->options</textarea>";
478     } else if ($question->type > 0) {     // Choose one of a number
479         $strchoose = get_string("choose");
480         echo "<select name=\"q$question->id\" id=\"q$question->id\">";
481         echo "<option value=\"0\" selected=\"selected\">$strchoose...</option>";
482         $options = explode( ",", $question->options);
483         foreach ($options as $key => $val) {
484             $key++;
485             echo "<option value=\"$key\">$val</option>";
486         }
487         echo "</select>";
489     } else if ($question->type < 0) {     // Choose several of a number
490         $options = explode( ",", $question->options);
491         notify("This question type not supported yet");
492     }
494     echo "</td></tr></table>";
498 function survey_question_rowclass($qnum) {
500     if ($qnum) {
501         return $qnum % 2 ? 'r0' : 'r1';
502     } else {
503         return 'r0';
504     }
507 function survey_print_graph($url) {
508     global $CFG, $SURVEY_GHEIGHT, $SURVEY_GWIDTH;
510     if (empty($CFG->gdversion)) {
511         echo "(".get_string("gdneed").")";
513     } else {
514         echo "<img class='resultgraph' height=\"$SURVEY_GHEIGHT\" width=\"$SURVEY_GWIDTH\"".
515              " src=\"$CFG->wwwroot/mod/survey/graph.php?$url\" alt=\"".get_string("surveygraph", "survey")."\" />";
516     }
519 function survey_get_view_actions() {
520     return array('download','view all','view form','view graph','view report');
523 function survey_get_post_actions() {
524     return array('submit');
528 /**
529  * Implementation of the function for printing the form elements that control
530  * whether the course reset functionality affects the survey.
531  * @param $mform form passed by reference
532  */
533 function survey_reset_course_form_definition(&$mform) {
534     $mform->addElement('header', 'surveyheader', get_string('modulenameplural', 'survey'));
535     $mform->addElement('checkbox', 'reset_survey_answers', get_string('deleteallanswers','survey'));
536     $mform->addElement('checkbox', 'reset_survey_analysis', get_string('deleteanalysis','survey'));
537     $mform->disabledIf('reset_survey_analysis', 'reset_survey_answers', 'checked');
540 /**
541  * Course reset form defaults.
542  */
543 function survey_reset_course_form_defaults($course) {
544     return array('reset_survey_answers'=>1, 'reset_survey_analysis'=>1);
547 /**
548  * Actual implementation of the rest coures functionality, delete all the
549  * survey responses for course $data->courseid.
550  * @param $data the data submitted from the reset course.
551  * @return array status array
552  */
553 function survey_reset_userdata($data) {
554     global $CFG;
556     $componentstr = get_string('modulenameplural', 'survey');
557     $status = array();
559     $surveyssql = "SELECT ch.id
560                      FROM {$CFG->prefix}survey ch
561                     WHERE ch.course={$data->courseid}";
563     if (!empty($data->reset_survey_answers)) {
564         delete_records_select('survey_answers', "survey IN ($surveyssql)");
565         delete_records_select('survey_analysis', "survey IN ($surveyssql)");
566         $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallanswers', 'survey'), 'error'=>false);
567     }
569     if (!empty($data->reset_survey_analysis)) {
570         delete_records_select('survey_analysis', "survey IN ($surveyssql)");
571         $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallanswers', 'survey'), 'error'=>false);
572     }
574     // no date shifting
575     return $status;
578 ?>