[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/lesson/ -> report.php (source)

   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&amp;action=reportdetail&amp;userid=".$try['userid']
 373                          .'&amp;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 .= "&nbsp;".userdate($try["timestart"]);
 384                      $temp .= ",&nbsp;(".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 .= "&nbsp;".userdate($try["timestart"]);
 389                          $timetotake = $try["timeend"] - $try["timestart"];
 390                          $temp .= ",&nbsp;(".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 .= "&nbsp;".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();


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1