MDL-10240:
[moodle-linuxchix.git] / mod / lesson / report.php
blob188e65bf01bac487ef059acbf9a80b8784d3afc8
1 <?php // $Id$
2 /**
3 * Displays the lesson statistics.
5 * @version $Id$
6 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7 * @package lesson
8 **/
10 require_once('../../config.php');
11 require_once('lib.php');
12 require_once('locallib.php');
14 $id = required_param('id', PARAM_INT); // Course Module ID
15 $pageid = optional_param('pageid', NULL, PARAM_INT); // Lesson Page ID
16 $action = optional_param('action', 'reportoverview', PARAM_ALPHA); // action to take
17 $nothingtodisplay = false;
19 list($cm, $course, $lesson) = lesson_get_basics($id);
21 if (! $students = get_records_sql("SELECT u.*
22 FROM {$CFG->prefix}user u,
23 {$CFG->prefix}lesson_attempts a
24 WHERE a.lessonid = '$lesson->id' and
25 u.id = a.userid
26 ORDER BY u.lastname")) {
27 $nothingtodisplay = true;
30 // make sure people are where they should be
31 require_login($course->id, false);
32 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
33 require_capability('mod/lesson:manage', $context);
35 /// Process any form data before fetching attempts, grades and times
36 if (has_capability('mod/lesson:edit', $context) and
37 $form = data_submitted($CFG->wwwroot.'/mod/lesson/report.php') and
38 confirm_sesskey()) {
39 /// Cycle through array of userids with nested arrays of tries
40 if (!empty($form->attempts)) {
41 foreach ($form->attempts as $userid => $tries) {
42 // Modifier IS VERY IMPORTANT! What does it do?
43 // Well, it is for when you delete multiple attempts for the same user.
44 // If you delete try 1 and 3 for a user, then after deleting try 1, try 3 then
45 // becomes try 2 (because try 1 is gone and all tries after try 1 get decremented).
46 // So, the modifier makes sure that the submitted try refers to the current try in the
47 // database - hope this all makes sense :)
48 $modifier = 0;
50 foreach ($tries as $try => $junk) {
51 $try -= $modifier;
53 /// Clean up the timer table
54 $timeid = get_field_sql("SELECT id FROM {$CFG->prefix}lesson_timer
55 WHERE userid = $userid AND lessonid = $lesson->id
56 ORDER BY starttime", $try, 1);
58 delete_records('lesson_timer', 'id', $timeid);
60 /// Remove the grade from the grades and high_scores tables
61 $gradeid = get_field_sql("SELECT id FROM {$CFG->prefix}lesson_grades
62 WHERE userid = $userid AND lessonid = $lesson->id
63 ORDER BY completed", $try, 1);
65 delete_records('lesson_grades', 'id', $gradeid);
66 delete_records('lesson_high_scores', 'gradeid', $gradeid, 'lessonid', $lesson->id, 'userid', $userid);
68 /// Remove attempts and update the retry number
69 delete_records('lesson_attempts', 'userid', $userid, 'lessonid', $lesson->id, 'retry', $try);
70 execute_sql("UPDATE {$CFG->prefix}lesson_attempts SET retry = retry - 1 WHERE userid = $userid AND lessonid = $lesson->id AND retry > $try", false);
72 /// Remove seen branches and update the retry number
73 delete_records('lesson_branch', 'userid', $userid, 'lessonid', $lesson->id, 'retry', $try);
74 execute_sql("UPDATE {$CFG->prefix}lesson_branch SET retry = retry - 1 WHERE userid = $userid AND lessonid = $lesson->id AND retry > $try", false);
76 /// update central gradebook
77 lesson_update_grades($lesson, $userid);
79 $modifier++;
82 lesson_set_message(get_string('attemptsdeleted', 'lesson'), 'notifysuccess');
86 if (! $attempts = get_records('lesson_attempts', 'lessonid', $lesson->id, 'timeseen')) {
87 $nothingtodisplay = true;
90 if (! $grades = get_records('lesson_grades', 'lessonid', $lesson->id, 'completed')) {
91 $grades = array();
94 if (! $times = get_records('lesson_timer', 'lessonid', $lesson->id, 'starttime')) {
95 $times = array();
98 lesson_print_header($cm, $course, $lesson, $action);
100 if ($nothingtodisplay) {
101 notify(get_string('nolessonattempts', 'lesson'));
102 print_footer($course);
103 exit();
106 /**************************************************************************
107 this action is for default view and overview view
108 **************************************************************************/
109 if ($action == 'reportoverview') {
110 $studentdata = array();
112 // build an array for output
113 foreach ($attempts as $attempt) {
114 // if the user is not in the array or if the retry number is not in the sub array, add the data for that try.
115 if (!array_key_exists($attempt->userid, $studentdata) || !array_key_exists($attempt->retry, $studentdata[$attempt->userid])) {
116 // restore/setup defaults
117 $n = 0;
118 $timestart = 0;
119 $timeend = 0;
120 $usergrade = NULL;
122 // search for the grade record for this try. if not there, the nulls defined above will be used.
123 foreach($grades as $grade) {
124 // check to see if the grade matches the correct user
125 if ($grade->userid == $attempt->userid) {
126 // see if n is = to the retry
127 if ($n == $attempt->retry) {
128 // get grade info
129 $usergrade = round($grade->grade, 2); // round it here so we only have to do it once
130 break;
132 $n++; // if not equal, then increment n
135 $n = 0;
136 // search for the time record for this try. if not there, the nulls defined above will be used.
137 foreach($times as $time) {
138 // check to see if the grade matches the correct user
139 if ($time->userid == $attempt->userid) {
140 // see if n is = to the retry
141 if ($n == $attempt->retry) {
142 // get grade info
143 $timeend = $time->lessontime;
144 $timestart = $time->starttime;
145 break;
147 $n++; // if not equal, then increment n
151 // build up the array.
152 // this array represents each student and all of their tries at the lesson
153 $studentdata[$attempt->userid][$attempt->retry] = array( "timestart" => $timestart,
154 "timeend" => $timeend,
155 "grade" => $usergrade,
156 "try" => $attempt->retry,
157 "userid" => $attempt->userid);
160 // set all the stats variables
161 $numofattempts = 0;
162 $avescore = 0;
163 $avetime = 0;
164 $highscore = NULL;
165 $lowscore = NULL;
166 $hightime = NULL;
167 $lowtime = NULL;
168 $table = new stdClass;
170 // set up the table object
171 $table->head = array(get_string('studentname', 'lesson', $course->student), get_string('attempts', 'lesson'), get_string('highscore', 'lesson'));
172 $table->align = array("center", "left", "left");
173 $table->wrap = array("nowrap", "nowrap", "nowrap");
174 $table->width = "90%";
175 $table->size = array("*", "70%", "*");
177 // print out the $studentdata array
178 // going through each student that has attempted the lesson, so, each student should have something to be displayed
179 foreach ($students as $student) {
180 // check to see if the student has attempts to print out
181 if (array_key_exists($student->id, $studentdata)) {
182 // set/reset some variables
183 $attempts = array();
184 // gather the data for each user attempt
185 $bestgrade = 0;
186 $bestgradefound = false;
187 // $tries holds all the tries/retries a student has done
188 $tries = $studentdata[$student->id];
189 $studentname = "{$student->lastname},&nbsp;$student->firstname";
190 foreach ($tries as $try) {
191 // start to build up the checkbox and link
192 if (has_capability('mod/lesson:edit', $context)) {
193 $temp = '<input type="checkbox" id="attempts" name="attempts['.$try['userid'].']['.$try['try'].']" /> ';
194 } else {
195 $temp = '';
198 $temp .= "<a href=\"report.php?id=$cm->id&amp;action=reportdetail&amp;userid=".$try['userid'].'&amp;try='.$try['try'].'">';
199 if ($try["grade"] !== NULL) { // if NULL then not done yet
200 // this is what the link does when the user has completed the try
201 $timetotake = $try["timeend"] - $try["timestart"];
203 $temp .= $try["grade"]."%";
204 $bestgradefound = true;
205 if ($try["grade"] > $bestgrade) {
206 $bestgrade = $try["grade"];
208 $temp .= "&nbsp;".userdate($try["timestart"]);
209 $temp .= ",&nbsp;(".format_time($timetotake).")</a>";
210 } else {
211 // this is what the link does/looks like when the user has not completed the try
212 $temp .= get_string("notcompleted", "lesson");
213 $temp .= "&nbsp;".userdate($try["timestart"])."</a>";
214 $timetotake = NULL;
216 // build up the attempts array
217 $attempts[] = $temp;
219 // run these lines for the stats only if the user finnished the lesson
220 if ($try["grade"] !== NULL) {
221 $numofattempts++;
222 $avescore += $try["grade"];
223 $avetime += $timetotake;
224 if ($try["grade"] > $highscore || $highscore == NULL) {
225 $highscore = $try["grade"];
227 if ($try["grade"] < $lowscore || $lowscore == NULL) {
228 $lowscore = $try["grade"];
230 if ($timetotake > $hightime || $hightime == NULL) {
231 $hightime = $timetotake;
233 if ($timetotake < $lowtime || $lowtime == NULL) {
234 $lowtime = $timetotake;
238 // get line breaks in after each attempt
239 $attempts = implode("<br />\n", $attempts);
240 // add it to the table data[] object
241 $table->data[] = array($studentname, $attempts, $bestgrade."%");
244 // print it all out !
245 if (has_capability('mod/lesson:edit', $context)) {
246 echo "<form id=\"theform\" method=\"post\" action=\"report.php\">\n
247 <input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n
248 <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n
249 <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
251 print_table($table);
253 if (has_capability('mod/lesson:edit', $context)) {
254 echo '<br /><table width="90%" align="center"><tr><td>'.
255 '<a href="javascript: checkall();">'.get_string('selectall').'</a> / '.
256 '<a href="javascript: checknone();">'.get_string('deselectall').'</a> ';
258 $options = array();
259 $options['delete'] = get_string('deleteselected');
260 choose_from_menu($options, 'attemptaction', 0, 'choose', 'submitFormById(\'theform\')');
262 echo '</td></tr></table></form>';
265 // some stat calculations
266 if ($numofattempts == 0) {
267 $avescore = get_string("notcompleted", "lesson");
268 } else {
269 $avescore = format_float($avescore/$numofattempts, 2, ".", ",");
271 if ($avetime == NULL) {
272 $avetime = get_string("notcompleted", "lesson");
273 } else {
274 $avetime = format_float($avetime/$numofattempts, 0, ".", ",");
275 $avetime = format_time($avetime);
277 if ($hightime == NULL) {
278 $hightime = get_string("notcompleted", "lesson");
279 } else {
280 $hightime = format_time($hightime);
282 if ($lowtime == NULL) {
283 $lowtime = get_string("notcompleted", "lesson");
284 } else {
285 $lowtime = format_time($lowtime);
287 if ($highscore == NULL) {
288 $highscore = get_string("notcompleted", "lesson");
290 if ($lowscore == NULL) {
291 $lowscore = get_string("notcompleted", "lesson");
294 // output the stats
295 print_heading(get_string('lessonstats', 'lesson'));
296 $stattable = new stdClass;
297 $stattable->head = array(get_string('averagescore', 'lesson'), get_string('averagetime', 'lesson'),
298 get_string('highscore', 'lesson'), get_string('lowscore', 'lesson'),
299 get_string('hightime', 'lesson'), get_string('lowtime', 'lesson'));
300 $stattable->align = array("center", "center", "center", "center", "center", "center");
301 $stattable->wrap = array("nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap");
302 $stattable->width = "90%";
303 $stattable->data[] = array($avescore.'%', $avetime, $highscore.'%', $lowscore.'%', $hightime, $lowtime);
305 print_table($stattable);
307 /**************************************************************************
308 this action is for a student detailed view and for the general detailed view
310 General flow of this section of the code
311 1. Generate a object which holds values for the statistics for each question/answer
312 2. Cycle through all the pages to create a object. Foreach page, see if the student actually answered
313 the page. Then process the page appropriatly. Display all info about the question,
314 Highlight correct answers, show how the user answered the question, and display statistics
315 about each page
316 3. Print out info about the try (if needed)
317 4. Print out the object which contains all the try info
319 **************************************************************************/
320 else if ($action == 'reportdetail') {
322 $formattextdefoptions->para = false; //I'll use it widely in this page
324 $userid = optional_param('userid', NULL, PARAM_INT); // if empty, then will display the general detailed view
325 $try = optional_param('try', NULL, PARAM_INT);
327 if (! $lessonpages = get_records("lesson_pages", "lessonid", $lesson->id)) {
328 error("Could not find Lesson Pages");
330 if (! $pageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) {
331 error("Could not find first page");
334 // now gather the stats into an object
335 $firstpageid = $pageid;
336 $pagestats = array();
337 while ($pageid != 0) { // EOL
338 $page = $lessonpages[$pageid];
340 if ($allanswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND pageid = $page->id", "timeseen")) {
341 // get them ready for processing
342 $orderedanswers = array();
343 foreach ($allanswers as $singleanswer) {
344 // ordering them like this, will help to find the single attempt record that we want to keep.
345 $orderedanswers[$singleanswer->userid][$singleanswer->retry][] = $singleanswer;
347 // this is foreach user and for each try for that user, keep one attempt record
348 foreach ($orderedanswers as $orderedanswer) {
349 foreach($orderedanswer as $tries) {
350 if(count($tries) > $lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
351 $temp = $tries[$lesson->maxattempts - 1];
352 } else {
353 // else, user attempted the question less than the max, so grab the last one
354 $temp = end($tries);
356 // page interpretation
357 // depending on the page type, process stat info for that page
358 switch ($page->qtype) {
359 case LESSON_MULTICHOICE:
360 case LESSON_TRUEFALSE:
361 if ($page->qoption) {
362 $userresponse = explode(",", $temp->useranswer);
363 foreach ($userresponse as $response) {
364 if (isset($pagestats[$temp->pageid][$response])) {
365 $pagestats[$temp->pageid][$response]++;
366 } else {
367 $pagestats[$temp->pageid][$response] = 1;
370 } else {
371 if (isset($pagestats[$temp->pageid][$temp->answerid])) {
372 $pagestats[$temp->pageid][$temp->answerid]++;
373 } else {
374 $pagestats[$temp->pageid][$temp->answerid] = 1;
377 if (isset($pagestats[$temp->pageid]["total"])) {
378 $pagestats[$temp->pageid]["total"]++;
379 } else {
380 $pagestats[$temp->pageid]["total"] = 1;
382 break;
383 case LESSON_SHORTANSWER:
384 case LESSON_NUMERICAL:
385 if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
386 $pagestats[$temp->pageid][$temp->useranswer]++;
387 } else {
388 $pagestats[$temp->pageid][$temp->useranswer] = 1;
390 if (isset($pagestats[$temp->pageid]["total"])) {
391 $pagestats[$temp->pageid]["total"]++;
392 } else {
393 $pagestats[$temp->pageid]["total"] = 1;
395 break;
396 case LESSON_MATCHING:
397 if ($temp->correct) {
398 if (isset($pagestats[$temp->pageid]["correct"])) {
399 $pagestats[$temp->pageid]["correct"]++;
400 } else {
401 $pagestats[$temp->pageid]["correct"] = 1;
404 if (isset($pagestats[$temp->pageid]["total"])) {
405 $pagestats[$temp->pageid]["total"]++;
406 } else {
407 $pagestats[$temp->pageid]["total"] = 1;
409 break;
410 case LESSON_ESSAY:
411 $essayinfo = unserialize($temp->useranswer);
412 if ($essayinfo->graded) {
413 if (isset($pagestats[$temp->pageid])) {
414 $essaystats = $pagestats[$temp->pageid];
415 $essaystats->totalscore += $essayinfo->score;
416 $essaystats->total++;
417 $pagestats[$temp->pageid] = $essaystats;
418 } else {
419 $essaystats->totalscore = $essayinfo->score;
420 $essaystats->total = 1;
421 $pagestats[$temp->pageid] = $essaystats;
424 break;
429 } else {
430 // no one answered yet...
432 //unset($orderedanswers); initialized above now
433 $pageid = $page->nextpageid;
438 $answerpages = array();
439 $answerpage = "";
440 $pageid = $firstpageid;
441 // cycle through all the pages
442 // foreach page, add to the $answerpages[] array all the data that is needed
443 // from the question, the users attempt, and the statistics
444 // grayout pages that the user did not answer and Branch, end of branch, cluster
445 // and end of cluster pages
446 while ($pageid != 0) { // EOL
447 $page = $lessonpages[$pageid];
448 $answerpage = new stdClass;
449 $data ='';
450 $answerdata = new stdClass;
452 $answerpage->title = format_string($page->title);
454 $options = new stdClass;
455 $options->noclean = true;
456 $answerpage->contents = format_text($page->contents, FORMAT_MOODLE, $options);
458 // get the page qtype
459 switch ($page->qtype) {
460 case LESSON_ESSAY :
461 case LESSON_MATCHING :
462 case LESSON_TRUEFALSE :
463 case LESSON_NUMERICAL :
464 $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
465 $answerpage->grayout = 0;
466 break;
467 case LESSON_SHORTANSWER :
468 $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
469 if ($page->qoption) {
470 $answerpage->qtype .= " - ".get_string("casesensitive", "lesson");
472 $answerpage->grayout = 0;
473 break;
474 case LESSON_MULTICHOICE :
475 $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
476 if ($page->qoption) {
477 $answerpage->qtype .= " - ".get_string("multianswer", "lesson");
479 $answerpage->grayout = 0;
480 break;
481 case LESSON_BRANCHTABLE :
482 $answerpage->qtype = get_string("branchtable", "lesson");
483 $answerpage->grayout = 1;
484 break;
485 case LESSON_ENDOFBRANCH :
486 $answerpage->qtype = get_string("endofbranch", "lesson");
487 $answerpage->grayout = 1;
488 break;
489 case LESSON_CLUSTER :
490 $answerpage->qtype = get_string("clustertitle", "lesson");
491 $answerpage->grayout = 1;
492 break;
493 case LESSON_ENDOFCLUSTER :
494 $answerpage->qtype = get_string("endofclustertitle", "lesson");
495 $answerpage->grayout = 1;
496 break;
500 if (empty($userid)) {
501 // there is no userid, so set these vars and display stats.
502 $answerpage->grayout = 0;
503 $useranswer = NULL;
504 $answerdata->score = NULL;
505 $answerdata->response = NULL;
506 } elseif ($useranswers = get_records_select("lesson_attempts",
507 "lessonid = $lesson->id AND userid = $userid AND retry = $try AND pageid = $page->id", "timeseen")) {
508 // get the user's answer for this page
509 // need to find the right one
510 $i = 0;
511 foreach ($useranswers as $userattempt) {
512 $useranswer = $userattempt;
513 $i++;
514 if ($lesson->maxattempts == $i) {
515 break; // reached maxattempts, break out
518 } else {
519 // user did not answer this page, gray it out and set some nulls
520 $answerpage->grayout = 1;
521 $useranswer = NULL;
522 $answerdata->score = NULL;
523 $answerdata->response = NULL;
526 // build up the answer data
527 if ($answers = get_records("lesson_answers", "pageid", $page->id, "id")) {
528 $i = 0;
529 $n = 0;
530 // go through each answer and display it properly with statistics, highlight if correct answer,
531 // and display what the user entered
532 foreach ($answers as $answer) {
533 switch ($page->qtype) {
534 case LESSON_MULTICHOICE:
535 case LESSON_TRUEFALSE:
536 if ($page->qoption) {
537 if ($useranswer == NULL) {
538 $userresponse = array();
539 } else {
540 $userresponse = explode(",", $useranswer->useranswer);
542 if (in_array($answer->id, $userresponse)) {
543 // make checked
544 $data = "<input readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
545 if (!isset($answerdata->response)) {
546 if ($answer->response == NULL) {
547 if ($useranswer->correct) {
548 $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
549 } else {
550 $answerdata->response = get_string("thatsthewronganswer", "lesson");
552 } else {
553 $answerdata->response = $answer->response;
556 if (!isset($answerdata->score)) {
557 if ($lesson->custom) {
558 $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
559 } elseif ($useranswer->correct) {
560 $answerdata->score = get_string("receivedcredit", "lesson");
561 } else {
562 $answerdata->score = get_string("didnotreceivecredit", "lesson");
565 } else {
566 // unchecked
567 $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
569 if (($answer->score > 0 && $lesson->custom) || (lesson_iscorrect($page->id, $answer->jumpto) && !$lesson->custom)) {
570 $data .= "<font class=highlight>".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</font>";
571 } else {
572 $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
574 } else {
575 if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
576 // make checked
577 $data = "<input readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
578 if ($answer->response == NULL) {
579 if ($useranswer->correct) {
580 $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
581 } else {
582 $answerdata->response = get_string("thatsthewronganswer", "lesson");
584 } else {
585 $answerdata->response = $answer->response;
587 if ($lesson->custom) {
588 $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
589 } elseif ($useranswer->correct) {
590 $answerdata->score = get_string("receivedcredit", "lesson");
591 } else {
592 $answerdata->score = get_string("didnotreceivecredit", "lesson");
594 } else {
595 // unchecked
596 $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
598 if (($answer->score > 0 && $lesson->custom) || (lesson_iscorrect($page->id, $answer->jumpto) && !$lesson->custom)) {
599 $data .= "<font class=\"highlight\">".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</font>";
600 } else {
601 $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
604 if (isset($pagestats[$page->id][$answer->id])) {
605 $percent = $pagestats[$page->id][$answer->id] / $pagestats[$page->id]["total"] * 100;
606 $percent = round($percent, 2);
607 $percent .= "% ".get_string("checkedthisone", "lesson");
608 } else {
609 $percent = get_string("noonecheckedthis", "lesson");
612 $answerdata->answers[] = array($data, $percent);
613 break;
614 case LESSON_SHORTANSWER:
615 case LESSON_NUMERICAL:
616 if ($useranswer == NULL && $i == 0) {
617 // I have the $i == 0 because it is easier to blast through it all at once.
618 if (isset($pagestats[$page->id])) {
619 $stats = $pagestats[$page->id];
620 $total = $stats["total"];
621 unset($stats["total"]);
622 foreach ($stats as $valentered => $ntimes) {
623 $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($valentered).'" />';
624 $percent = $ntimes / $total * 100;
625 $percent = round($percent, 2);
626 $percent .= "% ".get_string("enteredthis", "lesson");
627 $answerdata->answers[] = array($data, $percent);
629 } else {
630 $answerdata->answers[] = array(get_string("nooneansweredthisquestion", "lesson"), " ");
632 $i++;
633 } else if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
634 // get in here when a user answer matches one of the answers to the page
635 $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
636 if (isset($pagestats[$page->id][$useranswer->useranswer])) {
637 $percent = $pagestats[$page->id][$useranswer->useranswer] / $pagestats[$page->id]["total"] * 100;
638 $percent = round($percent, 2);
639 $percent .= "% ".get_string("enteredthis", "lesson");
640 } else {
641 $percent = get_string("nooneenteredthis", "lesson");
643 $answerdata->answers[] = array($data, $percent);
645 if ($answer->response == NULL) {
646 if ($useranswer->correct) {
647 $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
648 } else {
649 $answerdata->response = get_string("thatsthewronganswer", "lesson");
651 } else {
652 $answerdata->response = $answer->response;
654 if ($lesson->custom) {
655 $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
656 } elseif ($useranswer->correct) {
657 $answerdata->score = get_string("receivedcredit", "lesson");
658 } else {
659 $answerdata->score = get_string("didnotreceivecredit", "lesson");
661 } elseif ($answer == end($answers) && empty($answerdata) && $useranswer != NULL) {
662 // get in here when what the user entered is not one of the answers
663 $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
664 if (isset($pagestats[$page->id][$useranswer->useranswer])) {
665 $percent = $pagestats[$page->id][$useranswer->useranswer] / $pagestats[$page->id]["total"] * 100;
666 $percent = round($percent, 2);
667 $percent .= "% ".get_string("enteredthis", "lesson");
668 } else {
669 $percent = get_string("nooneenteredthis", "lesson");
671 $answerdata->answers[] = array($data, $percent);
673 $answerdata->response = get_string("thatsthewronganswer", "lesson");
674 if ($lesson->custom) {
675 $answerdata->score = get_string("pointsearned", "lesson").": 0";
676 } else {
677 $answerdata->score = get_string("didnotreceivecredit", "lesson");
680 break;
681 case LESSON_MATCHING:
682 if ($n == 0 && $useranswer->correct) {
683 if ($answer->response == NULL && $useranswer != NULL) {
684 $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
685 } else {
686 $answerdata->response = $answer->response;
688 } elseif ($n == 1 && !$useranswer->correct) {
689 if ($answer->response == NULL && $useranswer != NULL) {
690 $answerdata->response = get_string("thatsthewronganswer", "lesson");
691 } else {
692 $answerdata->response = $answer->response;
694 } elseif ($n > 1) {
695 if ($n == 2 && $useranswer->correct && $useranswer != NULL) {
696 if ($lesson->custom) {
697 $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
698 } else {
699 $answerdata->score = get_string("receivedcredit", "lesson");
701 } elseif ($n == 3 && !$useranswer->correct && $useranswer != NULL) {
702 if ($lesson->custom) {
703 $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
704 } else {
705 $answerdata->score = get_string("didnotreceivecredit", "lesson");
708 $data = "<select disabled=\"disabled\"><option selected>".strip_tags(format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions))."</option></select>";
709 if ($useranswer != NULL) {
710 $userresponse = explode(",", $useranswer->useranswer);
711 $data .= "<select disabled=\"disabled\"><option selected>".strip_tags(format_string($answers[$userresponse[$i]]->response,FORMAT_PLAIN,$formattextdefoptions))."</option></select>";
712 } else {
713 $data .= "<select disabled=\"disabled\"><option selected>".strip_tags(format_string($answer->response,FORMAT_PLAIN,$formattextdefoptions))."</option></select>";
716 if ($n == 2) {
717 if (isset($pagestats[$page->id])) {
718 $percent = $pagestats[$page->id]["correct"] / $pagestats[$page->id]["total"] * 100;
719 $percent = round($percent, 2);
720 $percent .= "% ".get_string("answeredcorrectly", "lesson");
721 } else {
722 $percent = get_string("nooneansweredthisquestion", "lesson");
724 } else {
725 $percent = "";
728 $answerdata->answers[] = array($data, $percent);
729 $i++;
731 $n++;
732 break;
733 case LESSON_ESSAY :
734 if ($useranswer != NULL) {
735 $essayinfo = unserialize($useranswer->useranswer);
736 if ($essayinfo->response == NULL) {
737 $answerdata->response = get_string("nocommentyet", "lesson");
738 } else {
739 $answerdata->response = s($essayinfo->response);
741 if (isset($pagestats[$page->id])) {
742 $percent = $pagestats[$page->id]->totalscore / $pagestats[$page->id]->total * 100;
743 $percent = round($percent, 2);
744 $percent = get_string("averagescore", "lesson").": ". $percent ."%";
745 } else {
746 // dont think this should ever be reached....
747 $percent = get_string("nooneansweredthisquestion", "lesson");
749 if ($essayinfo->graded) {
750 if ($lesson->custom) {
751 $answerdata->score = get_string("pointsearned", "lesson").": ".$essayinfo->score;
752 } elseif ($essayinfo->score) {
753 $answerdata->score = get_string("receivedcredit", "lesson");
754 } else {
755 $answerdata->score = get_string("didnotreceivecredit", "lesson");
757 } else {
758 $answerdata->score = get_string("havenotgradedyet", "lesson");
760 } else {
761 $essayinfo->answer = get_string("didnotanswerquestion", "lesson");
764 if (isset($pagestats[$page->id])) {
765 $avescore = $pagestats[$page->id]->totalscore / $pagestats[$page->id]->total;
766 $avescore = round($avescore, 2);
767 $avescore = get_string("averagescore", "lesson").": ". $avescore ;
768 } else {
769 // dont think this should ever be reached....
770 $avescore = get_string("nooneansweredthisquestion", "lesson");
772 $answerdata->answers[] = array(s(stripslashes_safe($essayinfo->answer)), $avescore);
773 break;
774 case LESSON_BRANCHTABLE :
775 $data = "<input type=\"button\" name=\"$answer->id\" value=\"".strip_tags(format_text($answer->answer, FORMAT_MOODLE,$formattextdefoptions))."\" disabled=\"disabled\"> ";
776 $data .= get_string('jumpsto', 'lesson', lesson_get_jump_name($answer->jumpto));
778 $answerdata->answers[] = array($data, "");
779 $answerpage->grayout = 1; // always grayed out
780 break;
781 case LESSON_ENDOFBRANCH :
782 case LESSON_CLUSTER :
783 case LESSON_ENDOFCLUSTER :
784 $data = get_string('jumpsto', 'lesson', lesson_get_jump_name($answer->jumpto));
786 $answerdata->answers[] = array($data, "");
787 $answerpage->grayout = 1; // always grayed out
788 break;
790 if (isset($answerdata)) {
791 $answerpage->answerdata = $answerdata;
794 $answerpages[] = $answerpage;
796 $pageid = $page->nextpageid;
799 /// actually start printing something
800 $table = new stdClass;
801 $table->wrap = array();
802 $table->width = "60%";
805 if (!empty($userid)) {
806 // if looking at a students try, print out some basic stats at the top
808 // print out users name
809 //$headingobject->lastname = $students[$userid]->lastname;
810 //$headingobject->firstname = $students[$userid]->firstname;
811 //$headingobject->attempt = $try + 1;
812 //print_heading(get_string("studentattemptlesson", "lesson", $headingobject));
813 print_heading(get_string('attempt', 'lesson', $try+1));
815 $table->head = array();
816 $table->align = array("right", "left");
817 $table->class = 'generaltable userinfotable';
819 if (!$grades = get_records_select("lesson_grades", "lessonid = $lesson->id and userid = $userid", "completed", "*", $try, 1)) {
820 $grade = -1;
821 $completed = -1;
822 } else {
823 $grade = current($grades);
824 $completed = $grade->completed;
825 $grade = round($grade->grade, 2);
827 if (!$times = get_records_select("lesson_timer", "lessonid = $lesson->id and userid = $userid", "starttime", "*", $try, 1)) {
828 $timetotake = -1;
829 } else {
830 $timetotake = current($times);
831 $timetotake = $timetotake->lessontime - $timetotake->starttime;
834 if ($timetotake == -1 || $completed == -1 || $grade == -1) {
835 $table->align = array("center");
837 $table->data[] = array(get_string("notcompleted", "lesson"));
838 } else {
839 $user = $students[$userid];
841 $gradeinfo = lesson_grade($lesson, $try, $user->id);
843 $table->data[] = array($course->student.':', print_user_picture($user->id, $course->id, $user->picture, 0, true).fullname($user, true));
844 $table->data[] = array(get_string("timetaken", "lesson").":", format_time($timetotake));
845 $table->data[] = array(get_string("completed", "lesson").":", userdate($completed));
846 $table->data[] = array(get_string('rawgrade', 'lesson').':', $gradeinfo->earned.'/'.$gradeinfo->total);
847 $table->data[] = array(get_string("grade", "lesson").":", $grade."%");
849 print_table($table);
851 // Don't want this class for later tables
852 unset($table->class);
853 echo "<br />";
857 $table->align = array("left", "left");
858 $table->size = array("70%", "*");
860 foreach ($answerpages as $page) {
861 unset($table->data);
862 if ($page->grayout) { // set the color of text
863 $fontstart = "<span class=\"dimmed\">";
864 $fontend = "</font>";
865 $fontstart2 = $fontstart;
866 $fontend2 = $fontend;
867 } else {
868 $fontstart = "";
869 $fontend = "";
870 $fontstart2 = "";
871 $fontend2 = "";
874 $table->head = array($fontstart2.$page->qtype.": ".format_string($page->title).$fontend2, $fontstart2.get_string("classstats", "lesson").$fontend2);
875 $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " ");
876 $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend);
877 // apply the font to each answer
878 foreach ($page->answerdata->answers as $answer){
879 $modified = array();
880 foreach ($answer as $single) {
881 // need to apply a font to each one
882 $modified[] = $fontstart2.$single.$fontend2;
884 $table->data[] = $modified;
886 if ($page->answerdata->response != NULL) {
887 $table->data[] = array($fontstart.get_string("response", "lesson").": <br />".$fontend.$fontstart2.format_text($page->answerdata->response,FORMAT_MOODLE,$formattextdefoptions).$fontend2, " ");
889 $table->data[] = array($page->answerdata->score, " ");
890 print_table($table);
891 echo "<br />";
895 else {
896 error("Fatal Error: Unknown Action: ".$action."\n");
899 /// Finish the page
900 print_footer($course);