calendar-eventmanager MDL-23290 Fixed up broken calendar when hidden
[moodle.git] / mod / choice / lib.php
CommitLineData
4636bf83 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
0d22e7cc 17
4636bf83 18/**
750eb434 19 * @package mod-choice
4636bf83 20 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
17da2e6f 24/** @global int $CHOICE_COLUMN_HEIGHT */
25global $CHOICE_COLUMN_HEIGHT;
26$CHOICE_COLUMN_HEIGHT = 300;
6d6c9389 27
8f7dc7f1 28define('CHOICE_PUBLISH_ANONYMOUS', '0');
29define('CHOICE_PUBLISH_NAMES', '1');
6d6c9389 30
c100a341 31define('CHOICE_SHOWRESULTS_NOT', '0');
32define('CHOICE_SHOWRESULTS_AFTER_ANSWER', '1');
33define('CHOICE_SHOWRESULTS_AFTER_CLOSE', '2');
34define('CHOICE_SHOWRESULTS_ALWAYS', '3');
f9af7fd0 35
6fd87e3b 36define('CHOICE_DISPLAY_HORIZONTAL', '0');
37define('CHOICE_DISPLAY_VERTICAL', '1');
38
4636bf83 39/** @global array $CHOICE_PUBLISH */
17da2e6f 40global $CHOICE_PUBLISH;
8f7dc7f1 41$CHOICE_PUBLISH = array (CHOICE_PUBLISH_ANONYMOUS => get_string('publishanonymous', 'choice'),
42 CHOICE_PUBLISH_NAMES => get_string('publishnames', 'choice'));
6d6c9389 43
4636bf83 44/** @global array $CHOICE_SHOWRESULTS */
17da2e6f 45global $CHOICE_SHOWRESULTS;
c100a341 46$CHOICE_SHOWRESULTS = array (CHOICE_SHOWRESULTS_NOT => get_string('publishnot', 'choice'),
47 CHOICE_SHOWRESULTS_AFTER_ANSWER => get_string('publishafteranswer', 'choice'),
48 CHOICE_SHOWRESULTS_AFTER_CLOSE => get_string('publishafterclose', 'choice'),
49 CHOICE_SHOWRESULTS_ALWAYS => get_string('publishalways', 'choice'));
f9af7fd0 50
4636bf83 51/** @global array $CHOICE_DISPLAY */
17da2e6f 52global $CHOICE_DISPLAY;
6fd87e3b 53$CHOICE_DISPLAY = array (CHOICE_DISPLAY_HORIZONTAL => get_string('displayhorizontal', 'choice'),
54 CHOICE_DISPLAY_VERTICAL => get_string('displayvertical','choice'));
6d6c9389 55
56/// Standard functions /////////////////////////////////////////////////////////
57
4636bf83 58/**
59 * @global object
60 * @param object $course
61 * @param object $user
62 * @param object $mod
63 * @param object $choice
64 * @return object|null
65 */
0d22e7cc 66function choice_user_outline($course, $user, $mod, $choice) {
407caeeb 67 global $DB;
68 if ($answer = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $user->id))) {
7cfc54b9 69 $result->info = "'".format_string(choice_get_option_text($choice, $answer->optionid))."'";
d1a67362 70 $result->time = $answer->timemodified;
0d22e7cc 71 return $result;
72 }
73 return NULL;
74}
75
4636bf83 76/**
77 * @global object
78 * @param object $course
79 * @param object $user
80 * @param object $mod
81 * @param object $choice
82 * @return string|void
83 */
0d22e7cc 84function choice_user_complete($course, $user, $mod, $choice) {
407caeeb 85 global $DB;
86 if ($answer = $DB->get_record('choice_answers', array("choiceid" => $choice->id, "userid" => $user->id))) {
7cfc54b9 87 $result->info = "'".format_string(choice_get_option_text($choice, $answer->optionid))."'";
d1a67362 88 $result->time = $answer->timemodified;
7cfc54b9 89 echo get_string("answered", "choice").": $result->info. ".get_string("updated", '', userdate($result->time));
0d22e7cc 90 } else {
c4016bc1 91 print_string("notanswered", "choice");
0d22e7cc 92 }
93}
94
4636bf83 95/**
96 * Given an object containing all the necessary data,
97 * (defined by the form in mod_form.php) this function
98 * will create a new instance and return the id number
99 * of the new instance.
100 *
101 * @global object
102 * @param object $choice
103 * @return int
104 */
04eba58f 105function choice_add_instance($choice) {
c18269c7 106 global $DB;
04eba58f 107
108 $choice->timemodified = time();
109
ebd3c7ac 110 if (empty($choice->timerestrict)) {
d30772b2 111 $choice->timeopen = 0;
112 $choice->timeclose = 0;
113 }
114
ff8d654f 115 //insert answers
c18269c7 116 if ($choice->id = $DB->insert_record("choice", $choice)) {
ebd3c7ac 117 foreach ($choice->option as $key => $value) {
118 $value = trim($value);
119 if (isset($value) && $value <> '') {
120 $option = new object();
121 $option->text = $value;
122 $option->choiceid = $choice->id;
123 if (isset($choice->limit[$key])) {
124 $option->maxanswers = $choice->limit[$key];
a77a6009 125 }
ebd3c7ac 126 $option->timemodified = time();
c18269c7 127 $DB->insert_record("choice_options", $option);
6fd87e3b 128 }
129 }
130 }
a77a6009 131 return $choice->id;
04eba58f 132}
133
4636bf83 134/**
135 * Given an object containing all the necessary data,
136 * (defined by the form in mod_form.php) this function
137 * will update an existing instance with new data.
138 *
139 * @global object
140 * @param object $choice
141 * @return bool
142 */
04eba58f 143function choice_update_instance($choice) {
c18269c7 144 global $DB;
04eba58f 145
146 $choice->id = $choice->instance;
147 $choice->timemodified = time();
148
d30772b2 149
ebd3c7ac 150 if (empty($choice->timerestrict)) {
d30772b2 151 $choice->timeopen = 0;
152 $choice->timeclose = 0;
153 }
ff8d654f 154
ebd3c7ac 155 //update, delete or insert answers
156 foreach ($choice->option as $key => $value) {
a77a6009 157 $value = trim($value);
ebd3c7ac 158 $option = new object();
159 $option->text = $value;
160 $option->choiceid = $choice->id;
161 if (isset($choice->limit[$key])) {
162 $option->maxanswers = $choice->limit[$key];
163 }
164 $option->timemodified = time();
a2e67a9a 165 if (isset($choice->optionid[$key]) && !empty($choice->optionid[$key])){//existing choice record
ebd3c7ac 166 $option->id=$choice->optionid[$key];
af834f3e 167 if (isset($value) && $value <> '') {
c18269c7 168 $DB->update_record("choice_options", $option);
b9135eca 169 } else { //empty old option - needs to be deleted.
c18269c7 170 $DB->delete_records("choice_options", array("id"=>$option->id));
c9ff813c 171 }
ebd3c7ac 172 } else {
173 if (isset($value) && $value <> '') {
c18269c7 174 $DB->insert_record("choice_options", $option);
a77a6009 175 }
ff8d654f 176 }
6fd87e3b 177 }
d30772b2 178
c18269c7 179 return $DB->update_record('choice', $choice);
ff8d654f 180
04eba58f 181}
182
4636bf83 183/**
184 * @global object
185 * @param object $choice
186 * @param object $user
187 * @param object $cm
188 * @param array $allresponses
189 * @return void output is echo'd
190 */
a61e4188 191function choice_show_form($choice, $user, $cm, $allresponses) {
407caeeb 192 global $DB;
348630d8 193//$cdisplay is an array of the display info for a choice $cdisplay[$optionid]->text - text name of option.
194// ->maxanswers -maxanswers for this option
195// ->full - whether this option is full or not. 0=not full, 1=full
39b3e7de 196 $cdisplay = array();
348630d8 197
198 $aid = 0;
3c56a7cc 199 $choicefull = false;
a61e4188 200 $cdisplay = array();
3c56a7cc 201
202 if ($choice->limitanswers) { //set choicefull to true by default if limitanswers.
203 $choicefull = true;
204 }
a61e4188 205
3c56a7cc 206 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
207
348630d8 208 foreach ($choice->option as $optionid => $text) {
a5f35b9f 209 if (isset($text)) { //make sure there are no dud entries in the db with blank text values.
dabfd0ed 210 $cdisplay[$aid]->optionid = $optionid;
211 $cdisplay[$aid]->text = $text;
a61e4188 212 $cdisplay[$aid]->maxanswers = $choice->maxanswers[$optionid];
55963a3a 213 if (isset($allresponses[$optionid])) {
214 $cdisplay[$aid]->countanswers = count($allresponses[$optionid]);
215 } else {
216 $cdisplay[$aid]->countanswers = 0;
217 }
407caeeb 218 if ($current = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $user->id, 'optionid' => $optionid))) {
ff8d654f 219 $cdisplay[$aid]->checked = ' checked="checked" ';
dabfd0ed 220 } else {
ff8d654f 221 $cdisplay[$aid]->checked = '';
dabfd0ed 222 }
407caeeb 223 if ( $choice->limitanswers &&
224 ($cdisplay[$aid]->countanswers >= $cdisplay[$aid]->maxanswers) &&
a61e4188 225 (empty($cdisplay[$aid]->checked)) ) {
ff8d654f 226 $cdisplay[$aid]->disabled = ' disabled="disabled" ';
dabfd0ed 227 } else {
ebd3c7ac 228 $cdisplay[$aid]->disabled = '';
a61e4188 229 if ($choice->limitanswers && ($cdisplay[$aid]->countanswers < $cdisplay[$aid]->maxanswers)) {
3c56a7cc 230 $choicefull = false; //set $choicefull to false - as the above condition hasn't been set.
231 }
dabfd0ed 232 }
348630d8 233 $aid++;
234 }
235 }
236
39b3e7de 237 switch ($choice->display) {
238 case CHOICE_DISPLAY_HORIZONTAL:
d71bc1ab 239 echo "<table cellpadding=\"20\" cellspacing=\"20\" class=\"boxaligncenter\"><tr>";
ebd3c7ac 240
241 foreach ($cdisplay as $cd) {
39b3e7de 242 echo "<td align=\"center\" valign=\"top\">";
ff8d654f 243 echo "<input type=\"radio\" name=\"answer\" value=\"".$cd->optionid."\" alt=\"".strip_tags(format_text($cd->text))."\"". $cd->checked.$cd->disabled." />";
ebd3c7ac 244 if (!empty($cd->disabled)) {
ff8d654f 245 echo format_text($cd->text."<br /><strong>".get_string('full', 'choice')."</strong>");
39b3e7de 246 } else {
247 echo format_text($cd->text);
348630d8 248 }
ff8d654f 249 echo "</td>";
39b3e7de 250 }
251 echo "</tr>";
252 echo "</table>";
253 break;
348630d8 254
39b3e7de 255 case CHOICE_DISPLAY_VERTICAL:
256 $displayoptions->para = false;
d71bc1ab 257 echo "<table cellpadding=\"10\" cellspacing=\"10\" class=\"boxaligncenter\">";
ff8d654f 258 foreach ($cdisplay as $cd) {
39b3e7de 259 echo "<tr><td align=\"left\">";
ff8d654f 260 echo "<input type=\"radio\" name=\"answer\" value=\"".$cd->optionid."\" alt=\"".strip_tags(format_text($cd->text))."\"". $cd->checked.$cd->disabled." />";
348630d8 261
39b3e7de 262 echo format_text($cd->text. ' ', FORMAT_MOODLE, $displayoptions); //display text for option.
ff8d654f 263
39b3e7de 264 if ($choice->limitanswers && ($choice->showresults==CHOICE_SHOWRESULTS_ALWAYS) ){ //if limit is enabled, and show results always has been selected, display info beside each choice.
265 echo "</td><td>";
ff8d654f 266
39b3e7de 267 if (!empty($cd->disabled)) {
268 echo get_string('full', 'choice');
269 } elseif(!empty($cd->checked)) {
dabfd0ed 270 //currently do nothing - maybe some text could be added here to signfy that the choice has been 'selected'
39b3e7de 271 } elseif ($cd->maxanswers-$cd->countanswers==1) {
272 echo ($cd->maxanswers - $cd->countanswers);
273 echo " ".get_string('spaceleft', 'choice');
274 } else {
275 echo ($cd->maxanswers - $cd->countanswers);
276 echo " ".get_string('spacesleft', 'choice');
277 }
278 echo "</td>";
279 } else if ($choice->limitanswers && ($cd->countanswers >= $cd->maxanswers)) { //if limitanswers and answers exceeded, display "full" beside the choice.
280 echo " <strong>".get_string('full', 'choice')."</strong>";
348630d8 281 }
39b3e7de 282 echo "</td>";
283 echo "</tr>";
284 }
285 echo "</table>";
286 break;
287 }
288 //show save choice button
d71bc1ab 289 echo '<div class="button">';
39b3e7de 290 echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />";
adef3099 291 echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
4f0c2d00 292 if (is_enrolled($context, NULL, 'mod/choice:choose')) { //only enrolled users are allowed to make a choice
3c56a7cc 293 if ($choicefull) {
294 print_string('choicefull', 'choice');
295 echo "</br>";
296 } else {
297 echo "<input type=\"submit\" value=\"".get_string("savemychoice","choice")."\" />";
298 }
c83d9e12 299 if ($choice->allowupdate && $aaa = $DB->get_record('choice_answers', array('choiceid'=> $choice->id, 'userid'=> $user->id))) {
adef3099 300 echo "<br /><a href='view.php?id=".$cm->id."&amp;action=delchoice&amp;sesskey=".sesskey()."'>".get_string("removemychoice","choice")."</a>";
243ac1fe 301 }
39b3e7de 302 } else {
303 print_string('havetologin', 'choice');
304 }
d71bc1ab 305 echo "</div>";
348630d8 306}
307
4636bf83 308/**
309 * @global object
310 * @param int $formanswer
311 * @param object $choice
312 * @param int $userid
313 * @param int $courseid
314 * @param object $cm
315 */
acaf7b86 316function choice_user_submit_response($formanswer, $choice, $userid, $courseid, $cm) {
407caeeb 317 global $DB;
318 $current = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'userid' => $userid));
dabfd0ed 319 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
c75ba879 320
321 $countanswers=0;
322 if($choice->limitanswers) {
323 // Find out whether groups are being used and enabled
324 if (groups_get_activity_groupmode($cm) > 0) {
325 $currentgroup = groups_get_activity_group($cm);
326 } else {
327 $currentgroup = 0;
328 }
329 if($currentgroup) {
330 // If groups are being used, retrieve responses only for users in
331 // current group
332 global $CFG;
407caeeb 333 $answers = $DB->get_records_sql("
334SELECT
c75ba879 335 ca.*
407caeeb 336FROM
337 {choice_answers} ca
338 INNER JOIN {groups_members} gm ON ca.userid=gm.userid
c75ba879 339WHERE
407caeeb 340 optionid=?
341 AND gm.groupid=?", array($formanswer, $currentgroup));
c75ba879 342 } else {
343 // Groups are not used, retrieve all answers for this option ID
407caeeb 344 $answers = $DB->get_records("choice_answers", array("optionid" => $formanswer));
ff8d654f 345 }
346
c75ba879 347 if ($answers) {
348 foreach ($answers as $a) { //only return enrolled users.
4f0c2d00 349 if (is_enrolled($context, $a->userid, 'mod/choice:choose')) {
c75ba879 350 $countanswers++;
351 }
352 }
353 }
354 $maxans = $choice->maxanswers[$formanswer];
39b3e7de 355 }
ff8d654f 356
357 if (!($choice->limitanswers && ($countanswers >= $maxans) )) {
39b3e7de 358 if ($current) {
ebd3c7ac 359
39b3e7de 360 $newanswer = $current;
361 $newanswer->optionid = $formanswer;
362 $newanswer->timemodified = time();
7826abc7 363 $DB->update_record("choice_answers", $newanswer);
39b3e7de 364 add_to_log($courseid, "choice", "choose again", "view.php?id=$cm->id", $choice->id, $cm->id);
365 } else {
366 $newanswer = NULL;
367 $newanswer->choiceid = $choice->id;
368 $newanswer->userid = $userid;
369 $newanswer->optionid = $formanswer;
370 $newanswer->timemodified = time();
7826abc7 371 $DB->insert_record("choice_answers", $newanswer);
39b3e7de 372 add_to_log($courseid, "choice", "choose", "view.php?id=$cm->id", $choice->id, $cm->id);
373 }
374 } else {
375 if (!($current->optionid==$formanswer)) { //check to see if current choice already selected - if not display error
c7281355 376 print_error('choicefull', 'choice');
39b3e7de 377 }
378 }
348630d8 379}
380
4636bf83 381/**
382 * @param array $user
383 * @param object $cm
384 * @return void Output is echo'd
385 */
a61e4188 386function choice_show_reportlink($user, $cm) {
387 $responsecount =0;
388 foreach($user as $optionid => $userlist) {
389 if ($optionid) {
390 $responsecount += count($userlist);
391 }
7b360f33 392 }
5c880488 393
39b3e7de 394 echo '<div class="reportlink">';
5c880488 395 echo "<a href=\"report.php?id=$cm->id\">".get_string("viewallresponses", "choice", $responsecount)."</a>";
39b3e7de 396 echo '</div>';
348630d8 397}
398
4636bf83 399/**
400 * @global object
401 * @global int
402 * @global string
9f319372 403 * @global object
4636bf83 404 * @uses CONTEXT_MODULE
405 * @uses CHOICE_PUBLISH_NAMES
406 * @uses CHOICE_PUBLISH_ANONYMOUS
407 * @param object $choice
408 * @param object $course
409 * @param object $cm
410 * @param array $allresponses
411 * @param int $forcepublish
412 * @return void Output is echo'd
413 */
5d9d5227 414function choice_show_results($choice, $course, $cm, $allresponses, $forcepublish='') {
db8935ef 415 global $CFG, $CHOICE_COLUMN_HEIGHT, $FULLSCRIPT, $PAGE, $OUTPUT, $DB;
407caeeb 416
5ddd4e06 417 echo $OUTPUT->heading(get_string("responses", "choice"));
39b3e7de 418 if (empty($forcepublish)) { //alow the publish setting to be overridden
419 $forcepublish = $choice->publish;
ff8d654f 420 }
421
9acb7700 422 if (empty($allresponses)) {
5ddd4e06 423 echo $OUTPUT->heading(get_string("nousersyet"));
9acb7700 424 return false;
39b3e7de 425 }
c2a4d016 426
427 $totalresponsecount = 0;
5d9d5227 428 foreach ($allresponses as $optionid => $userlist) {
c2a4d016 429 if ($choice->showunanswered || $optionid) {
430 $totalresponsecount += count($userlist);
431 }
432 }
407caeeb 433
a61e4188 434 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
348630d8 435
a61e4188 436 $hascapfullnames = has_capability('moodle/site:viewfullnames', $context);
407caeeb 437
438 $viewresponses = has_capability('mod/choice:readresponses', $context);
39b3e7de 439 switch ($forcepublish) {
440 case CHOICE_PUBLISH_NAMES:
4ec64b4f 441 echo '<div id="tablecontainer">';
442 if ($viewresponses) {
11e7b506 443 echo '<form id="attemptsform" method="post" action="'.$FULLSCRIPT.'" onsubmit="var menu = document.getElementById(\'menuaction\'); return (menu.options[menu.selectedIndex].value == \'delete\' ? \''.addslashes_js(get_string('deleteattemptcheck','quiz')).'\' : true);">';
95aa949b 444 echo '<div>';
348630d8 445 echo '<input type="hidden" name="id" value="'.$cm->id.'" />';
afb6f77d 446 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
348630d8 447 echo '<input type="hidden" name="mode" value="overview" />';
4ec64b4f 448 }
ff8d654f 449
d71bc1ab 450 echo "<table cellpadding=\"5\" cellspacing=\"10\" class=\"results names\">";
348630d8 451 echo "<tr>";
407caeeb 452
aa4836f4 453 $columncount = array(); // number of votes in each column
a61e4188 454 if ($choice->showunanswered) {
455 $columncount[0] = 0;
456 echo "<th class=\"col0 header\" scope=\"col\">";
457 print_string('notanswered', 'choice');
458 echo "</th>";
459 }
460 $count = 1;
461 foreach ($choice->option as $optionid => $optiontext) {
aa4836f4 462 $columncount[$optionid] = 0; // init counters
a61e4188 463 echo "<th class=\"col$count header\" scope=\"col\">";
464 echo format_string($optiontext);
348630d8 465 echo "</th>";
466 $count++;
467 }
468 echo "</tr><tr>";
469
82ab7cb5 470 if ($choice->showunanswered) {
a61e4188 471 echo "<td class=\"col$count data\" >";
95aa949b 472 // added empty row so that when the next iteration is empty,
473 // we do not get <table></table> erro from w3c validator
474 // MDL-7861
475 echo "<table class=\"choiceresponse\"><tr><td></td></tr>";
82ab7cb5 476 if (!empty($allresponses[0])) {
477 foreach ($allresponses[0] as $user) {
478 echo "<tr>";
479 echo "<td class=\"picture\">";
812dbaf7 480 echo $OUTPUT->user_picture($user, array('courseid'=>$course->id));
82ab7cb5 481 echo "</td><td class=\"fullname\">";
482 echo "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">";
483 echo fullname($user, $hascapfullnames);
484 echo "</a>";
485 echo "</td></tr>";
486 }
348630d8 487 }
a61e4188 488 echo "</table></td>";
489 }
a82fb0b6 490 $count = 1;
a61e4188 491 foreach ($choice->option as $optionid => $optiontext) {
492 echo '<td class="col'.$count.' data" >';
493
494 // added empty row so that when the next iteration is empty,
495 // we do not get <table></table> erro from w3c validator
496 // MDL-7861
497 echo '<table class="choiceresponse"><tr><td></td></tr>';
5d9d5227 498 if (isset($allresponses[$optionid])) {
499 foreach ($allresponses[$optionid] as $user) {
a61e4188 500 $columncount[$optionid] += 1;
501 echo '<tr><td class="attemptcell">';
cb4db90d 502 if ($viewresponses and has_capability('mod/choice:deleteresponses',$context)) {
a61e4188 503 echo '<input type="checkbox" name="attemptid[]" value="'. $user->id. '" />';
504 }
505 echo '</td><td class="picture">';
812dbaf7 506 echo $OUTPUT->user_picture($user, array('courseid'=>$course->id));
a61e4188 507 echo '</td><td class="fullname">';
508 echo "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">";
509 echo fullname($user, $hascapfullnames);
510 echo '</a>';
511 echo '</td></tr>';
512 }
513 }
514 $count++;
515 echo '</table></td>';
348630d8 516 }
517 echo "</tr><tr>";
a82fb0b6 518 $count = 1;
407caeeb 519
a61e4188 520 if ($choice->showunanswered) {
521 echo "<td></td>";
522 }
3a11c09f 523
a61e4188 524 foreach ($choice->option as $optionid => $optiontext) {
a82fb0b6 525 echo "<td align=\"center\" class=\"col$count count\">";
a61e4188 526 if ($choice->limitanswers) {
348630d8 527 echo get_string("taken", "choice").":";
aa4836f4 528 echo $columncount[$optionid];
71502268 529 echo "<br/>";
348630d8 530 echo get_string("limit", "choice").":";
b723a4f8 531 echo $choice->maxanswers[$optionid];
19e559e4 532 } else {
a61e4188 533 if (isset($columncount[$optionid])) {
534 echo $columncount[$optionid];
535 }
348630d8 536 }
537 echo "</td>";
538 $count++;
539 }
3402a6f3 540 echo "</tr>";
407caeeb 541
39b3e7de 542 /// Print "Select all" etc.
cb4db90d 543 if ($viewresponses and has_capability('mod/choice:deleteresponses',$context)) {
3402a6f3 544 echo '<tr><td></td><td>';
9b854b2d
DM
545 echo '<a href="javascript:select_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('selectall').'</a> / ';
546 echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('deselectall').'</a> ';
39b3e7de 547 echo '&nbsp;&nbsp;';
9b854b2d
DM
548 echo html_writer::label(get_string('withselected', 'choice'), 'menuaction');
549 echo html_writer::select(array('delete' => get_string('delete')), 'action', '', array(''=>get_string('withselectedusers')), array('id'=>'menuaction'));
edc28287
PS
550 $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('attemptsform', 'menuaction', ''));
551 echo '<noscript id="noscriptmenuaction" style="display:inline">';
95aa949b 552 echo '<div>';
553 echo '<input type="submit" value="'.get_string('go').'" /></div></noscript>';
3402a6f3 554 echo '</td><td></td></tr>';
39b3e7de 555 }
407caeeb 556
4ec64b4f 557 echo "</table></div>";
a61e4188 558 if ($viewresponses) {
4ec64b4f 559 echo "</form></div>";
dabfd0ed 560 }
348630d8 561 break;
407caeeb 562
563
39b3e7de 564 case CHOICE_PUBLISH_ANONYMOUS:
ff8d654f 565
d71bc1ab 566 echo "<table cellpadding=\"5\" cellspacing=\"0\" class=\"results anonymous\">";
348630d8 567 echo "<tr>";
a61e4188 568 $maxcolumn = 0;
569 if ($choice->showunanswered) {
570 echo "<th class=\"col0 header\" scope=\"col\">";
571 print_string('notanswered', 'choice');
348630d8 572 echo "</th>";
a61e4188 573 $column[0] = 0;
5d9d5227 574 foreach ($allresponses[0] as $user) {
a61e4188 575 $column[0]++;
576 }
577 $maxcolumn = $column[0];
348630d8 578 }
a61e4188 579 $count = 1;
348630d8 580
a61e4188 581 foreach ($choice->option as $optionid => $optiontext) {
582 echo "<th class=\"col$count header\" scope=\"col\">";
583 echo format_string($optiontext);
584 echo "</th>";
407caeeb 585
348630d8 586 $column[$optionid] = 0;
5d9d5227 587 if (isset($allresponses[$optionid])) {
588 $column[$optionid] = count($allresponses[$optionid]);
a61e4188 589 if ($column[$optionid] > $maxcolumn) {
590 $maxcolumn = $column[$optionid];
591 }
592 } else {
593 $column[$optionid] = 0;
348630d8 594 }
595 }
a61e4188 596 echo "</tr><tr>";
348630d8 597
a61e4188 598 $height = 0;
599
600 if ($choice->showunanswered) {
601 if ($maxcolumn) {
17da2e6f 602 $height = $CHOICE_COLUMN_HEIGHT * ((float)$column[0] / (float)$maxcolumn);
348630d8 603 }
a61e4188 604 echo "<td style=\"vertical-align:bottom\" align=\"center\" class=\"col0 data\">";
605 echo "<img src=\"column.png\" height=\"$height\" width=\"49\" alt=\"\" />";
606 echo "</td>";
607 }
608 $count = 1;
609 foreach ($choice->option as $optionid => $optiontext) {
348630d8 610 if ($maxcolumn) {
17da2e6f 611 $height = $CHOICE_COLUMN_HEIGHT * ((float)$column[$optionid] / (float)$maxcolumn);
348630d8 612 }
41daad76 613 echo "<td style=\"vertical-align:bottom\" align=\"center\" class=\"col$count data\">";
348630d8 614 echo "<img src=\"column.png\" height=\"$height\" width=\"49\" alt=\"\" />";
615 echo "</td>";
616 $count++;
617 }
a61e4188 618 echo "</tr><tr>";
348630d8 619
a61e4188 620
621 if ($choice->showunanswered) {
c2a4d016 622 echo '<td align="center" class="col0 count">';
623 if (!$choice->limitanswers) {
624 echo $column[0];
625 echo '<br />('.format_float(((float)$column[0]/(float)$totalresponsecount)*100.0,1).'%)';
626 }
627 echo '</td>';
a61e4188 628 }
629 $count = 1;
630 foreach ($choice->option as $optionid => $optiontext) {
348630d8 631 echo "<td align=\"center\" class=\"col$count count\">";
a61e4188 632 if ($choice->limitanswers) {
348630d8 633 echo get_string("taken", "choice").":";
c2a4d016 634 echo $column[$optionid].'<br />';
348630d8 635 echo get_string("limit", "choice").":";
b723a4f8 636 echo $choice->maxanswers[$optionid];
348630d8 637 } else {
638 echo $column[$optionid];
c2a4d016 639 echo '<br />('.format_float(((float)$column[$optionid]/(float)$totalresponsecount)*100.0,1).'%)';
348630d8 640 }
641 echo "</td>";
642 $count++;
643 }
644 echo "</tr></table>";
407caeeb 645
a61e4188 646 break;
ebd3c7ac 647 }
348630d8 648}
649
4636bf83 650/**
651 * @global object
652 * @param array $attemptids
653 * @param int $choiceid
654 * @return bool
655 */
a61e4188 656function choice_delete_responses($attemptids, $choiceid) {
407caeeb 657 global $DB;
dabfd0ed 658 if(!is_array($attemptids) || empty($attemptids)) {
348630d8 659 return false;
660 }
661
662 foreach($attemptids as $num => $attemptid) {
663 if(empty($attemptid)) {
664 unset($attemptids[$num]);
665 }
666 }
667
668 foreach($attemptids as $attemptid) {
407caeeb 669 if ($todelete = $DB->get_record('choice_answers', array('choiceid' => $choiceid, 'userid' => $attemptid))) {
670 $DB->delete_records('choice_answers', array('choiceid' => $choiceid, 'userid' => $attemptid));
348630d8 671 }
ebd3c7ac 672 }
348630d8 673 return true;
674}
675
04eba58f 676
4636bf83 677/**
678 * Given an ID of an instance of this module,
679 * this function will permanently delete the instance
680 * and any data that depends on it.
681 *
682 * @global object
683 * @param int $id
684 * @return bool
685 */
04eba58f 686function choice_delete_instance($id) {
c18269c7 687 global $DB;
04eba58f 688
c18269c7 689 if (! $choice = $DB->get_record("choice", array("id"=>"$id"))) {
04eba58f 690 return false;
691 }
692
693 $result = true;
694
c18269c7 695 if (! $DB->delete_records("choice_answers", array("choiceid"=>"$choice->id"))) {
04eba58f 696 $result = false;
697 }
698
c18269c7 699 if (! $DB->delete_records("choice_options", array("choiceid"=>"$choice->id"))) {
04eba58f 700 $result = false;
701 }
a77a6009 702
c18269c7 703 if (! $DB->delete_records("choice", array("id"=>"$choice->id"))) {
6fd87e3b 704 $result = false;
ebd3c7ac 705 }
04eba58f 706
707 return $result;
708}
709
4636bf83 710/**
711 * Returns the users with data in one choice
712 * (users with records in choice_responses, students)
713 *
714 * @param int $choiceid
715 * @return array
716 */
05855091 717function choice_get_participants($choiceid) {
585fb1f4 718 global $DB;
05855091 719
720 //Get students
407caeeb 721 $students = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
722 FROM {user} u,
723 {choice_answers} a
724 WHERE a.choiceid = ? AND
725 u.id = a.userid", array($choiceid));
05855091 726
727 //Return students array (it contains an array of unique users)
728 return ($students);
729}
730
4636bf83 731/**
732 * Returns text string which is the answer that matches the id
733 *
734 * @global object
735 * @param object $choice
736 * @param int $id
737 * @return string
738 */
a77a6009 739function choice_get_option_text($choice, $id) {
407caeeb 740 global $DB;
4636bf83 741
407caeeb 742 if ($result = $DB->get_record("choice_options", array("id" => $id))) {
a77a6009 743 return $result->text;
6fd87e3b 744 } else {
745 return get_string("notanswered", "choice");
ff8d654f 746 }
c4016bc1 747}
748
4636bf83 749/**
750 * Gets a full choice record
751 *
752 * @global object
753 * @param int $choiceid
754 * @return object|bool The choice or false
755 */
cd3fccff 756function choice_get_choice($choiceid) {
407caeeb 757 global $DB;
a77a6009 758
407caeeb 759 if ($choice = $DB->get_record("choice", array("id" => $choiceid))) {
760 if ($options = $DB->get_records("choice_options", array("choiceid" => $choiceid), "id")) {
ff8d654f 761 foreach ($options as $option) {
ebd3c7ac 762 $choice->option[$option->id] = $option->text;
c9ff813c 763 $choice->maxanswers[$option->id] = $option->maxanswers;
ff8d654f 764 }
a77a6009 765 return $choice;
766 }
767 }
768 return false;
cd3fccff 769}
770
4636bf83 771/**
772 * @return array
773 */
f3221af9 774function choice_get_view_actions() {
775 return array('view','view all','report');
776}
777
4636bf83 778/**
779 * @return array
780 */
f3221af9 781function choice_get_post_actions() {
782 return array('choose','choose again');
783}
784
0b5a80a1 785
786/**
787 * Implementation of the function for printing the form elements that control
788 * whether the course reset functionality affects the choice.
1adbd2c3 789 *
4636bf83 790 * @param object $mform form passed by reference
0b5a80a1 791 */
792function choice_reset_course_form_definition(&$mform) {
793 $mform->addElement('header', 'choiceheader', get_string('modulenameplural', 'choice'));
794 $mform->addElement('advcheckbox', 'reset_choice', get_string('removeresponses','choice'));
795}
796
797/**
798 * Course reset form defaults.
4636bf83 799 *
800 * @return array
0b5a80a1 801 */
802function choice_reset_course_form_defaults($course) {
803 return array('reset_choice'=>1);
804}
805
806/**
807 * Actual implementation of the rest coures functionality, delete all the
808 * choice responses for course $data->courseid.
4636bf83 809 *
810 * @global object
811 * @global object
812 * @param object $data the data submitted from the reset course.
0b5a80a1 813 * @return array status array
814 */
815function choice_reset_userdata($data) {
407caeeb 816 global $CFG, $DB;
0b5a80a1 817
818 $componentstr = get_string('modulenameplural', 'choice');
819 $status = array();
820
821 if (!empty($data->reset_choice)) {
822 $choicessql = "SELECT ch.id
407caeeb 823 FROM {choice} ch
824 WHERE ch.course=?";
0b5a80a1 825
407caeeb 826 $DB->delete_records_select('choice_answers', "choiceid IN ($choicessql)", array($data->courseid));
0b5a80a1 827 $status[] = array('component'=>$componentstr, 'item'=>get_string('removeresponses', 'choice'), 'error'=>false);
828 }
829
830 /// updating dates - shift may be negative too
831 if ($data->timeshift) {
832 shift_course_mod_dates('choice', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid);
833 $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
834 }
835
836 return $status;
837}
838
4636bf83 839/**
840 * @global object
841 * @global object
842 * @global object
843 * @uses CONTEXT_MODULE
844 * @param object $choice
845 * @param object $cm
846 * @param int $groupmode
847 * @return array
848 */
a61e4188 849function choice_get_response_data($choice, $cm, $groupmode) {
407caeeb 850 global $CFG, $USER, $DB;
a61e4188 851
852 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
853
854/// Get the current group
855 if ($groupmode > 0) {
856 $currentgroup = groups_get_activity_group($cm);
857 } else {
858 $currentgroup = 0;
859 }
860
5d9d5227 861/// Initialise the returned array, which is a matrix: $allresponses[responseid][userid] = responseobject
862 $allresponses = array();
a61e4188 863
864/// First get all the users who have access here
865/// To start with we assume they are all "unanswered" then move them later
3a11c09f 866 $allresponses[0] = get_enrolled_users($context, 'mod/choice:choose', $currentgroup, user_picture::fields('u', array('idnumber')), 'u.lastname ASC,u.firstname ASC');
a61e4188 867
868/// Get all the recorded responses for this choice
407caeeb 869 $rawresponses = $DB->get_records('choice_answers', array('choiceid' => $choice->id));
a61e4188 870
871/// Use the responses to move users into the correct column
872
5d9d5227 873 if ($rawresponses) {
874 foreach ($rawresponses as $response) {
875 if (isset($allresponses[0][$response->userid])) { // This person is enrolled and in correct group
876 $allresponses[0][$response->userid]->timemodified = $response->timemodified;
877 $allresponses[$response->optionid][$response->userid] = clone($allresponses[0][$response->userid]);
878 unset($allresponses[0][$response->userid]); // Remove from unanswered column
a61e4188 879 }
880 }
881 }
9acb7700 882 if (empty($allresponses[0])) {
883 unset($allresponses[0]);
884 }
5d9d5227 885 return $allresponses;
f432bebf 886}
a61e4188 887
f432bebf 888/**
889 * Returns all other caps used in module
4636bf83 890 *
891 * @return array
f432bebf 892 */
db19ec01 893function choice_get_extra_capabilities() {
f432bebf 894 return array('moodle/site:accessallgroups');
a61e4188 895}
f432bebf 896
18a2a0cb 897/**
4636bf83 898 * @uses FEATURE_GROUPS
899 * @uses FEATURE_GROUPINGS
900 * @uses FEATURE_GROUPMEMBERSONLY
901 * @uses FEATURE_MOD_INTRO
902 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
903 * @uses FEATURE_GRADE_HAS_GRADE
904 * @uses FEATURE_GRADE_OUTCOMES
18a2a0cb 905 * @param string $feature FEATURE_xx constant for requested feature
906 * @return mixed True if module supports feature, null if doesn't know
907 */
908function choice_supports($feature) {
909 switch($feature) {
42f103be 910 case FEATURE_GROUPS: return true;
911 case FEATURE_GROUPINGS: return true;
912 case FEATURE_GROUPMEMBERSONLY: return true;
dc5c2bd9 913 case FEATURE_MOD_INTRO: return true;
18a2a0cb 914 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42f103be 915 case FEATURE_GRADE_HAS_GRADE: return false;
916 case FEATURE_GRADE_OUTCOMES: return false;
98baf0d7 917 case FEATURE_BACKUP_MOODLE2: return true;
42f103be 918
18a2a0cb 919 default: return null;
920 }
921}
97011c64 922
0b29477b
SH
923/**
924 * Adds module specific settings to the settings block
925 *
926 * @param settings_navigation $settings The settings navigation object
927 * @param navigation_node $choicenode The node to add module settings to
928 */
929function choice_extend_settings_navigation(settings_navigation $settings, navigation_node $choicenode) {
930 global $PAGE;
97011c64 931
932 if (has_capability('mod/choice:readresponses', $PAGE->cm->context)) {
933
934 $groupmode = groups_get_activity_groupmode($PAGE->cm);
935 if ($groupmode) {
936 groups_get_activity_group($PAGE->cm, true);
937 }
56115eea
SH
938 // We only actually need the choice id here
939 $choice = new stdClass;
940 $choice->id = $PAGE->cm->instance;
97011c64 941 $allresponses = choice_get_response_data($choice, $PAGE->cm, $groupmode); // Big function, approx 6 SQL calls per user
942
943 $responsecount =0;
944 foreach($allresponses as $optionid => $userlist) {
945 if ($optionid) {
946 $responsecount += count($userlist);
947 }
948 }
0b29477b 949 $choicenode->add(get_string("viewallresponses", "choice", $responsecount), new moodle_url('/mod/choice/report.php', array('id'=>$PAGE->cm->id)));
97011c64 950 }
98baf0d7 951}