[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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/>. 17 18 /** 19 * Displays the lesson statistics. 20 * 21 * @package mod_lesson 22 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late 24 **/ 25 26 require_once('../../config.php'); 27 require_once($CFG->dirroot.'/mod/lesson/locallib.php'); 28 require_once($CFG->dirroot.'/mod/lesson/pagetypes/branchtable.php'); // Needed for constant. 29 30 $id = required_param('id', PARAM_INT); // Course Module ID 31 $pageid = optional_param('pageid', null, PARAM_INT); // Lesson Page ID 32 $action = optional_param('action', 'reportoverview', PARAM_ALPHA); // action to take 33 $nothingtodisplay = false; 34 35 $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST); 36 $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); 37 $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST)); 38 39 require_login($course, false, $cm); 40 41 $currentgroup = groups_get_activity_group($cm, true); 42 43 $context = context_module::instance($cm->id); 44 require_capability('mod/lesson:viewreports', $context); 45 46 $url = new moodle_url('/mod/lesson/report.php', array('id'=>$id)); 47 $url->param('action', $action); 48 if ($pageid !== null) { 49 $url->param('pageid', $pageid); 50 } 51 $PAGE->set_url($url); 52 if ($action == 'reportoverview') { 53 $PAGE->navbar->add(get_string('reports', 'lesson')); 54 $PAGE->navbar->add(get_string('overview', 'lesson')); 55 } 56 57 $lessonoutput = $PAGE->get_renderer('mod_lesson'); 58 59 if ($action === 'delete') { 60 /// Process any form data before fetching attempts, grades and times 61 if (has_capability('mod/lesson:edit', $context) and $form = data_submitted() and confirm_sesskey()) { 62 /// Cycle through array of userids with nested arrays of tries 63 if (!empty($form->attempts)) { 64 foreach ($form->attempts as $userid => $tries) { 65 // Modifier IS VERY IMPORTANT! What does it do? 66 // Well, it is for when you delete multiple attempts for the same user. 67 // If you delete try 1 and 3 for a user, then after deleting try 1, try 3 then 68 // becomes try 2 (because try 1 is gone and all tries after try 1 get decremented). 69 // So, the modifier makes sure that the submitted try refers to the current try in the 70 // database - hope this all makes sense :) 71 $modifier = 0; 72 73 foreach ($tries as $try => $junk) { 74 $try -= $modifier; 75 76 /// Clean up the timer table by removing using the order - this is silly, it should be linked to specific attempt (skodak) 77 $params = array ("userid" => $userid, "lessonid" => $lesson->id); 78 $timers = $DB->get_records_sql("SELECT id FROM {lesson_timer} 79 WHERE userid = :userid AND lessonid = :lessonid 80 ORDER BY starttime", $params, $try, 1); 81 if ($timers) { 82 $timer = reset($timers); 83 $DB->delete_records('lesson_timer', array('id' => $timer->id)); 84 } 85 86 // Remove the grade from the grades tables - this is silly, it should be linked to specific attempt (skodak). 87 $grades = $DB->get_records_sql("SELECT id FROM {lesson_grades} 88 WHERE userid = :userid AND lessonid = :lessonid 89 ORDER BY completed", $params, $try, 1); 90 91 if ($grades) { 92 $grade = reset($grades); 93 $DB->delete_records('lesson_grades', array('id' => $grade->id)); 94 } 95 96 /// Remove attempts and update the retry number 97 $DB->delete_records('lesson_attempts', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try)); 98 $DB->execute("UPDATE {lesson_attempts} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try)); 99 100 /// Remove seen branches and update the retry number 101 $DB->delete_records('lesson_branch', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try)); 102 $DB->execute("UPDATE {lesson_branch} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try)); 103 104 /// update central gradebook 105 lesson_update_grades($lesson, $userid); 106 107 $modifier++; 108 } 109 } 110 } 111 } 112 redirect(new moodle_url($PAGE->url, array('action'=>'reportoverview'))); 113 114 } else if ($action === 'reportoverview') { 115 /************************************************************************** 116 this action is for default view and overview view 117 **************************************************************************/ 118 119 // Count the number of branch and question pages in this lesson. 120 $branchcount = $DB->count_records('lesson_pages', array('lessonid' => $lesson->id, 'qtype' => LESSON_PAGE_BRANCHTABLE)); 121 $questioncount = ($DB->count_records('lesson_pages', array('lessonid' => $lesson->id)) - $branchcount); 122 123 // Only load students if there attempts for this lesson. 124 $attempts = $DB->record_exists('lesson_attempts', array('lessonid' => $lesson->id)); 125 $branches = $DB->record_exists('lesson_branch', array('lessonid' => $lesson->id)); 126 $timer = $DB->record_exists('lesson_timer', array('lessonid' => $lesson->id)); 127 if ($attempts or $branches or $timer) { 128 list($esql, $params) = get_enrolled_sql($context, '', $currentgroup, true); 129 list($sort, $sortparams) = users_order_by_sql('u'); 130 131 $params['a1lessonid'] = $lesson->id; 132 $params['b1lessonid'] = $lesson->id; 133 $params['c1lessonid'] = $lesson->id; 134 $ufields = user_picture::fields('u'); 135 $sql = "SELECT DISTINCT $ufields 136 FROM {user} u 137 JOIN ( 138 SELECT userid, lessonid FROM {lesson_attempts} a1 139 WHERE a1.lessonid = :a1lessonid 140 UNION 141 SELECT userid, lessonid FROM {lesson_branch} b1 142 WHERE b1.lessonid = :b1lessonid 143 UNION 144 SELECT userid, lessonid FROM {lesson_timer} c1 145 WHERE c1.lessonid = :c1lessonid 146 ) a ON u.id = a.userid 147 JOIN ($esql) ue ON ue.id = a.userid 148 ORDER BY $sort"; 149 150 $students = $DB->get_recordset_sql($sql, $params); 151 if (!$students->valid()) { 152 $students->close(); 153 $nothingtodisplay = true; 154 } 155 } else { 156 $nothingtodisplay = true; 157 } 158 159 if ($nothingtodisplay) { 160 echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('nolessonattempts', 'lesson')); 161 if (!empty($currentgroup)) { 162 $groupname = groups_get_group_name($currentgroup); 163 echo $OUTPUT->notification(get_string('nolessonattemptsgroup', 'lesson', $groupname)); 164 } else { 165 echo $OUTPUT->notification(get_string('nolessonattempts', 'lesson')); 166 } 167 groups_print_activity_menu($cm, $url); 168 echo $OUTPUT->footer(); 169 exit(); 170 } 171 172 if (! $grades = $DB->get_records('lesson_grades', array('lessonid' => $lesson->id), 'completed')) { 173 $grades = array(); 174 } 175 176 if (! $times = $DB->get_records('lesson_timer', array('lessonid' => $lesson->id), 'starttime')) { 177 $times = array(); 178 } 179 180 echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('overview', 'lesson')); 181 groups_print_activity_menu($cm, $url); 182 183 $course_context = context_course::instance($course->id); 184 if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) { 185 $seeallgradeslink = new moodle_url('/grade/report/grader/index.php', array('id'=>$course->id)); 186 $seeallgradeslink = html_writer::link($seeallgradeslink, get_string('seeallcoursegrades', 'grades')); 187 echo $OUTPUT->box($seeallgradeslink, 'allcoursegrades'); 188 } 189 190 // Build an array for output. 191 $studentdata = array(); 192 193 $attempts = $DB->get_recordset('lesson_attempts', array('lessonid' => $lesson->id), 'timeseen'); 194 foreach ($attempts as $attempt) { 195 // 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. 196 if (empty($studentdata[$attempt->userid]) || empty($studentdata[$attempt->userid][$attempt->retry])) { 197 // restore/setup defaults 198 $n = 0; 199 $timestart = 0; 200 $timeend = 0; 201 $usergrade = null; 202 $eol = false; 203 204 // search for the grade record for this try. if not there, the nulls defined above will be used. 205 foreach($grades as $grade) { 206 // check to see if the grade matches the correct user 207 if ($grade->userid == $attempt->userid) { 208 // see if n is = to the retry 209 if ($n == $attempt->retry) { 210 // get grade info 211 $usergrade = round($grade->grade, 2); // round it here so we only have to do it once 212 break; 213 } 214 $n++; // if not equal, then increment n 215 } 216 } 217 $n = 0; 218 // search for the time record for this try. if not there, the nulls defined above will be used. 219 foreach($times as $time) { 220 // check to see if the grade matches the correct user 221 if ($time->userid == $attempt->userid) { 222 // see if n is = to the retry 223 if ($n == $attempt->retry) { 224 // get grade info 225 $timeend = $time->lessontime; 226 $timestart = $time->starttime; 227 $eol = $time->completed; 228 break; 229 } 230 $n++; // if not equal, then increment n 231 } 232 } 233 234 // build up the array. 235 // this array represents each student and all of their tries at the lesson 236 $studentdata[$attempt->userid][$attempt->retry] = array( "timestart" => $timestart, 237 "timeend" => $timeend, 238 "grade" => $usergrade, 239 "end" => $eol, 240 "try" => $attempt->retry, 241 "userid" => $attempt->userid); 242 } 243 } 244 $attempts->close(); 245 246 $branches = $DB->get_recordset('lesson_branch', array('lessonid' => $lesson->id), 'timeseen'); 247 foreach ($branches as $branch) { 248 // 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. 249 if (empty($studentdata[$branch->userid]) || empty($studentdata[$branch->userid][$branch->retry])) { 250 // Restore/setup defaults. 251 $n = 0; 252 $timestart = 0; 253 $timeend = 0; 254 $usergrade = null; 255 $eol = false; 256 // Search for the time record for this try. if not there, the nulls defined above will be used. 257 foreach ($times as $time) { 258 // Check to see if the grade matches the correct user. 259 if ($time->userid == $branch->userid) { 260 // See if n is = to the retry. 261 if ($n == $branch->retry) { 262 // Get grade info. 263 $timeend = $time->lessontime; 264 $timestart = $time->starttime; 265 $eol = $time->completed; 266 break; 267 } 268 $n++; // If not equal, then increment n. 269 } 270 } 271 272 // Build up the array. 273 // This array represents each student and all of their tries at the lesson. 274 $studentdata[$branch->userid][$branch->retry] = array( "timestart" => $timestart, 275 "timeend" => $timeend, 276 "grade" => $usergrade, 277 "end" => $eol, 278 "try" => $branch->retry, 279 "userid" => $branch->userid); 280 } 281 } 282 $branches->close(); 283 284 // Need the same thing for timed entries that were not completed. 285 foreach ($times as $time) { 286 $endoflesson = $time->completed; 287 // If the time start is the same with another record then we shouldn't be adding another item to this array. 288 if (isset($studentdata[$time->userid])) { 289 $foundmatch = false; 290 $n = 0; 291 foreach ($studentdata[$time->userid] as $key => $value) { 292 if ($value['timestart'] == $time->starttime) { 293 // Don't add this to the array. 294 $foundmatch = true; 295 break; 296 } 297 } 298 $n = count($studentdata[$time->userid]) + 1; 299 if (!$foundmatch) { 300 // Add a record. 301 $studentdata[$time->userid][] = array( 302 "timestart" => $time->starttime, 303 "timeend" => $time->lessontime, 304 "grade" => null, 305 "end" => $endoflesson, 306 "try" => $n, 307 "userid" => $time->userid 308 ); 309 } 310 } else { 311 $studentdata[$time->userid][] = array( 312 "timestart" => $time->starttime, 313 "timeend" => $time->lessontime, 314 "grade" => null, 315 "end" => $endoflesson, 316 "try" => 0, 317 "userid" => $time->userid 318 ); 319 } 320 } 321 // Determine if lesson should have a score. 322 if ($branchcount > 0 AND $questioncount == 0) { 323 // This lesson only contains content pages and is not graded. 324 $lessonscored = false; 325 } else { 326 // This lesson is graded. 327 $lessonscored = true; 328 } 329 // set all the stats variables 330 $numofattempts = 0; 331 $avescore = 0; 332 $avetime = 0; 333 $highscore = null; 334 $lowscore = null; 335 $hightime = null; 336 $lowtime = null; 337 338 $table = new html_table(); 339 340 // Set up the table object. 341 if ($lessonscored) { 342 $table->head = array(get_string('name'), get_string('attempts', 'lesson'), get_string('highscore', 'lesson')); 343 } else { 344 $table->head = array(get_string('name'), get_string('attempts', 'lesson')); 345 } 346 $table->align = array('center', 'left', 'left'); 347 $table->wrap = array('nowrap', 'nowrap', 'nowrap'); 348 $table->attributes['class'] = 'standardtable generaltable'; 349 $table->size = array(null, '70%', null); 350 351 // print out the $studentdata array 352 // going through each student that has attempted the lesson, so, each student should have something to be displayed 353 foreach ($students as $student) { 354 // check to see if the student has attempts to print out 355 if (array_key_exists($student->id, $studentdata)) { 356 // set/reset some variables 357 $attempts = array(); 358 // gather the data for each user attempt 359 $bestgrade = 0; 360 $bestgradefound = false; 361 // $tries holds all the tries/retries a student has done 362 $tries = $studentdata[$student->id]; 363 $studentname = fullname($student, true); 364 foreach ($tries as $try) { 365 // start to build up the checkbox and link 366 if (has_capability('mod/lesson:edit', $context)) { 367 $temp = '<input type="checkbox" id="attempts" name="attempts['.$try['userid'].']['.$try['try'].']" /> '; 368 } else { 369 $temp = ''; 370 } 371 372 $temp .= "<a href=\"report.php?id=$cm->id&action=reportdetail&userid=".$try['userid'] 373 .'&try='.$try['try'].'" class="lesson-attempt-link">'; 374 if ($try["grade"] !== null) { // if null then not done yet 375 // this is what the link does when the user has completed the try 376 $timetotake = $try["timeend"] - $try["timestart"]; 377 378 $temp .= $try["grade"]."%"; 379 $bestgradefound = true; 380 if ($try["grade"] > $bestgrade) { 381 $bestgrade = $try["grade"]; 382 } 383 $temp .= " ".userdate($try["timestart"]); 384 $temp .= ", (".format_time($timetotake).")</a>"; 385 } else { 386 if ($try["end"]) { 387 // User finished the lesson but has no grade. (Happens when there are only content pages). 388 $temp .= " ".userdate($try["timestart"]); 389 $timetotake = $try["timeend"] - $try["timestart"]; 390 $temp .= ", (".format_time($timetotake).")</a>"; 391 } else { 392 // This is what the link does/looks like when the user has not completed the attempt. 393 $temp .= get_string("notcompleted", "lesson"); 394 if ($try['timestart'] !== 0) { 395 // Teacher previews do not track time spent. 396 $temp .= " ".userdate($try["timestart"]); 397 } 398 $temp .= "</a>"; 399 $timetotake = null; 400 } 401 } 402 // build up the attempts array 403 $attempts[] = $temp; 404 405 // Run these lines for the stats only if the user finnished the lesson. 406 if ($try["end"]) { 407 // User has completed the lesson. 408 $numofattempts++; 409 $avetime += $timetotake; 410 if ($timetotake > $hightime || $hightime == null) { 411 $hightime = $timetotake; 412 } 413 if ($timetotake < $lowtime || $lowtime == null) { 414 $lowtime = $timetotake; 415 } 416 if ($try["grade"] !== null) { 417 // The lesson was scored. 418 $avescore += $try["grade"]; 419 if ($try["grade"] > $highscore || $highscore === null) { 420 $highscore = $try["grade"]; 421 } 422 if ($try["grade"] < $lowscore || $lowscore === null) { 423 $lowscore = $try["grade"]; 424 } 425 426 } 427 } 428 } 429 // get line breaks in after each attempt 430 $attempts = implode("<br />\n", $attempts); 431 432 if ($lessonscored) { 433 // Add the grade if the lesson is graded. 434 $bestgrade = $bestgrade."%"; 435 $table->data[] = array($studentname, $attempts, $bestgrade); 436 } else { 437 // This lesson does not have a grade. 438 $table->data[] = array($studentname, $attempts); 439 } 440 } 441 } 442 $students->close(); 443 // Print it all out! 444 if (has_capability('mod/lesson:edit', $context)) { 445 echo "<form id=\"theform\" method=\"post\" action=\"report.php\">\n 446 <input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n 447 <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n"; 448 } 449 echo html_writer::table($table); 450 if (has_capability('mod/lesson:edit', $context)) { 451 $checklinks = '<a href="javascript: checkall();">'.get_string('selectall').'</a> / '; 452 $checklinks .= '<a href="javascript: checknone();">'.get_string('deselectall').'</a>'; 453 $checklinks .= html_writer::label('action', 'menuaction', false, array('class' => 'accesshide')); 454 $checklinks .= html_writer::select(array('delete' => get_string('deleteselected')), 'action', 0, array(''=>'choosedots'), array('id'=>'actionid', 'class' => 'autosubmit')); 455 $PAGE->requires->yui_module('moodle-core-formautosubmit', 456 'M.core.init_formautosubmit', 457 array(array('selectid' => 'actionid', 'nothing' => false)) 458 ); 459 echo $OUTPUT->box($checklinks, 'center'); 460 echo '</form>'; 461 } 462 463 // Calculate the Statistics. 464 if ($avetime == null) { 465 $avetime = get_string("notcompleted", "lesson"); 466 } else { 467 $avetime = format_float($avetime/$numofattempts, 0); 468 $avetime = format_time($avetime); 469 } 470 if ($hightime == null) { 471 $hightime = get_string("notcompleted", "lesson"); 472 } else { 473 $hightime = format_time($hightime); 474 } 475 if ($lowtime == null) { 476 $lowtime = get_string("notcompleted", "lesson"); 477 } else { 478 $lowtime = format_time($lowtime); 479 } 480 481 if ($lessonscored) { 482 if ($numofattempts == 0) { 483 $avescore = get_string("notcompleted", "lesson"); 484 } else { 485 $avescore = format_float($avescore / $numofattempts, 2) . '%'; 486 } 487 if ($highscore === null) { 488 $highscore = get_string("notcompleted", "lesson"); 489 } else { 490 $highscore .= '%'; 491 } 492 if ($lowscore === null) { 493 $lowscore = get_string("notcompleted", "lesson"); 494 } else { 495 $lowscore .= '%'; 496 } 497 498 // Display the full stats for the lesson. 499 echo $OUTPUT->heading(get_string('lessonstats', 'lesson'), 3); 500 $stattable = new html_table(); 501 $stattable->head = array(get_string('averagescore', 'lesson'), get_string('averagetime', 'lesson'), 502 get_string('highscore', 'lesson'), get_string('lowscore', 'lesson'), 503 get_string('hightime', 'lesson'), get_string('lowtime', 'lesson')); 504 $stattable->align = array('center', 'center', 'center', 'center', 'center', 'center'); 505 $stattable->wrap = array('nowrap', 'nowrap', 'nowrap', 'nowrap', 'nowrap', 'nowrap'); 506 $stattable->attributes['class'] = 'standardtable generaltable'; 507 $stattable->data[] = array($avescore, $avetime, $highscore, $lowscore, $hightime, $lowtime); 508 509 } else { 510 // Display simple stats for the lesson. 511 echo $OUTPUT->heading(get_string('lessonstats', 'lesson'), 3); 512 $stattable = new html_table(); 513 $stattable->head = array(get_string('averagetime', 'lesson'), get_string('hightime', 'lesson'), 514 get_string('lowtime', 'lesson')); 515 $stattable->align = array('center', 'center', 'center'); 516 $stattable->wrap = array('nowrap', 'nowrap', 'nowrap'); 517 $stattable->attributes['class'] = 'standardtable generaltable'; 518 $stattable->data[] = array($avetime, $hightime, $lowtime); 519 } 520 521 echo html_writer::table($stattable); 522 } else if ($action === 'reportdetail') { 523 /************************************************************************** 524 this action is for a student detailed view and for the general detailed view 525 526 General flow of this section of the code 527 1. Generate a object which holds values for the statistics for each question/answer 528 2. Cycle through all the pages to create a object. Foreach page, see if the student actually answered 529 the page. Then process the page appropriatly. Display all info about the question, 530 Highlight correct answers, show how the user answered the question, and display statistics 531 about each page 532 3. Print out info about the try (if needed) 533 4. Print out the object which contains all the try info 534 535 **************************************************************************/ 536 echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('detailedstats', 'lesson')); 537 groups_print_activity_menu($cm, $url); 538 539 $course_context = context_course::instance($course->id); 540 if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) { 541 $seeallgradeslink = new moodle_url('/grade/report/grader/index.php', array('id'=>$course->id)); 542 $seeallgradeslink = html_writer::link($seeallgradeslink, get_string('seeallcoursegrades', 'grades')); 543 echo $OUTPUT->box($seeallgradeslink, 'allcoursegrades'); 544 } 545 546 $formattextdefoptions = new stdClass; 547 $formattextdefoptions->para = false; //I'll use it widely in this page 548 $formattextdefoptions->overflowdiv = true; 549 550 $userid = optional_param('userid', null, PARAM_INT); // if empty, then will display the general detailed view 551 $try = optional_param('try', null, PARAM_INT); 552 553 if (!empty($userid)) { 554 // Apply overrides. 555 $lesson->update_effective_access($userid); 556 } 557 558 $lessonpages = $lesson->load_all_pages(); 559 foreach ($lessonpages as $lessonpage) { 560 if ($lessonpage->prevpageid == 0) { 561 $pageid = $lessonpage->id; 562 } 563 } 564 565 // now gather the stats into an object 566 $firstpageid = $pageid; 567 $pagestats = array(); 568 while ($pageid != 0) { // EOL 569 $page = $lessonpages[$pageid]; 570 $params = array ("lessonid" => $lesson->id, "pageid" => $page->id); 571 if ($allanswers = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND pageid = :pageid", $params, "timeseen")) { 572 // get them ready for processing 573 $orderedanswers = array(); 574 foreach ($allanswers as $singleanswer) { 575 // ordering them like this, will help to find the single attempt record that we want to keep. 576 $orderedanswers[$singleanswer->userid][$singleanswer->retry][] = $singleanswer; 577 } 578 // this is foreach user and for each try for that user, keep one attempt record 579 foreach ($orderedanswers as $orderedanswer) { 580 foreach($orderedanswer as $tries) { 581 $page->stats($pagestats, $tries); 582 } 583 } 584 } else { 585 // no one answered yet... 586 } 587 //unset($orderedanswers); initialized above now 588 $pageid = $page->nextpageid; 589 } 590 591 $manager = lesson_page_type_manager::get($lesson); 592 $qtypes = $manager->get_page_type_strings(); 593 594 $answerpages = array(); 595 $answerpage = ""; 596 $pageid = $firstpageid; 597 // cycle through all the pages 598 // foreach page, add to the $answerpages[] array all the data that is needed 599 // from the question, the users attempt, and the statistics 600 // grayout pages that the user did not answer and Branch, end of branch, cluster 601 // and end of cluster pages 602 while ($pageid != 0) { // EOL 603 $page = $lessonpages[$pageid]; 604 $answerpage = new stdClass; 605 $data =''; 606 607 $answerdata = new stdClass; 608 // Set some defaults for the answer data. 609 $answerdata->score = null; 610 $answerdata->response = null; 611 $answerdata->responseformat = FORMAT_PLAIN; 612 613 $answerpage->title = format_string($page->title); 614 615 $options = new stdClass; 616 $options->noclean = true; 617 $options->overflowdiv = true; 618 $options->context = $context; 619 $answerpage->contents = format_text($page->contents, $page->contentsformat, $options); 620 621 $answerpage->qtype = $qtypes[$page->qtype].$page->option_description_string(); 622 $answerpage->grayout = $page->grayout; 623 $answerpage->context = $context; 624 625 if (empty($userid)) { 626 // there is no userid, so set these vars and display stats. 627 $answerpage->grayout = 0; 628 $useranswer = null; 629 } elseif ($useranswers = $DB->get_records("lesson_attempts",array("lessonid"=>$lesson->id, "userid"=>$userid, "retry"=>$try,"pageid"=>$page->id), "timeseen")) { 630 // get the user's answer for this page 631 // need to find the right one 632 $i = 0; 633 foreach ($useranswers as $userattempt) { 634 $useranswer = $userattempt; 635 $i++; 636 if ($lesson->maxattempts == $i) { 637 break; // reached maxattempts, break out 638 } 639 } 640 } else { 641 // user did not answer this page, gray it out and set some nulls 642 $answerpage->grayout = 1; 643 $useranswer = null; 644 } 645 $i = 0; 646 $n = 0; 647 $answerpages[] = $page->report_answers(clone($answerpage), clone($answerdata), $useranswer, $pagestats, $i, $n); 648 $pageid = $page->nextpageid; 649 } 650 651 /// actually start printing something 652 $table = new html_table(); 653 $table->wrap = array(); 654 $table->width = "60%"; 655 if (!empty($userid)) { 656 // if looking at a students try, print out some basic stats at the top 657 658 // print out users name 659 //$headingobject->lastname = $students[$userid]->lastname; 660 //$headingobject->firstname = $students[$userid]->firstname; 661 //$headingobject->attempt = $try + 1; 662 //print_heading(get_string("studentattemptlesson", "lesson", $headingobject)); 663 echo $OUTPUT->heading(get_string('attempt', 'lesson', $try+1), 3); 664 665 $table->head = array(); 666 $table->align = array('right', 'left'); 667 $table->attributes['class'] = 'compacttable generaltable'; 668 669 $params = array("lessonid"=>$lesson->id, "userid"=>$userid); 670 if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid and userid = :userid", $params, "completed", "*", $try, 1)) { 671 $grade = -1; 672 $completed = -1; 673 } else { 674 $grade = current($grades); 675 $completed = $grade->completed; 676 $grade = round($grade->grade, 2); 677 } 678 if (!$times = $DB->get_records_select("lesson_timer", "lessonid = :lessonid and userid = :userid", $params, "starttime", "*", $try, 1)) { 679 $timetotake = -1; 680 } else { 681 $timetotake = current($times); 682 $timetotake = $timetotake->lessontime - $timetotake->starttime; 683 } 684 685 if ($timetotake == -1 || $completed == -1 || $grade == -1) { 686 $table->align = array("center"); 687 688 $table->data[] = array(get_string("notcompleted", "lesson")); 689 } else { 690 $user = $DB->get_record('user', array('id' => $userid)); 691 692 $gradeinfo = lesson_grade($lesson, $try, $user->id); 693 694 $table->data[] = array(get_string('name').':', $OUTPUT->user_picture($user, array('courseid'=>$course->id)).fullname($user, true)); 695 $table->data[] = array(get_string("timetaken", "lesson").":", format_time($timetotake)); 696 $table->data[] = array(get_string("completed", "lesson").":", userdate($completed)); 697 $table->data[] = array(get_string('rawgrade', 'lesson').':', $gradeinfo->earned.'/'.$gradeinfo->total); 698 $table->data[] = array(get_string("grade", "lesson").":", $grade."%"); 699 } 700 echo html_writer::table($table); 701 702 // Don't want this class for later tables 703 $table->attributes['class'] = ''; 704 } 705 706 707 $table->align = array('left', 'left'); 708 $table->size = array('70%', null); 709 $table->attributes['class'] = 'compacttable generaltable'; 710 711 foreach ($answerpages as $page) { 712 unset($table->data); 713 if ($page->grayout) { // set the color of text 714 $fontstart = "<span class=\"dimmed\">"; 715 $fontend = "</font>"; 716 $fontstart2 = $fontstart; 717 $fontend2 = $fontend; 718 } else { 719 $fontstart = ""; 720 $fontend = ""; 721 $fontstart2 = ""; 722 $fontend2 = ""; 723 } 724 725 $table->head = array($fontstart2.$page->qtype.": ".format_string($page->title).$fontend2, $fontstart2.get_string("classstats", "lesson").$fontend2); 726 $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " "); 727 $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend, ' '); 728 // apply the font to each answer 729 if (!empty($page->answerdata)) { 730 foreach ($page->answerdata->answers as $answer){ 731 $modified = array(); 732 foreach ($answer as $single) { 733 // need to apply a font to each one 734 $modified[] = $fontstart2.$single.$fontend2; 735 } 736 $table->data[] = $modified; 737 } 738 if (isset($page->answerdata->response)) { 739 $table->data[] = array($fontstart.get_string("response", "lesson").": <br />".$fontend 740 .$fontstart2.$page->answerdata->response.$fontend2, " "); 741 } 742 $table->data[] = array($page->answerdata->score, " "); 743 } else { 744 $table->data[] = array(get_string('didnotanswerquestion', 'lesson'), " "); 745 } 746 echo html_writer::start_tag('div', array('class' => 'no-overflow')); 747 echo html_writer::table($table); 748 echo html_writer::end_tag('div'); 749 } 750 } else { 751 print_error('unknowaction'); 752 } 753 754 /// Finish the page 755 echo $OUTPUT->footer();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |