Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  /**
  17   * Core Report class of graphs reporting plugin
  18   *
  19   * @package    scormreport_graphs
  20   * @copyright  2012 Ankit Kumar Agarwal
  21   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22   */
  23  
  24  namespace scormreport_graphs;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use context_module;
  29  use core\chart_bar;
  30  use core\chart_series;
  31  use moodle_url;
  32  
  33  /**
  34   * Main class to control the graphs reporting
  35   *
  36   * @package    scormreport_graphs
  37   * @copyright  2012 Ankit Kumar Agarwal
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  
  41  class report extends \mod_scorm\report {
  42  
  43      /** Number of bars. */
  44      const BANDS = 11;
  45  
  46      /** Range of each bar. */
  47      const BANDWIDTH = 10;
  48  
  49      /**
  50       * Get the data for the report.
  51       *
  52       * @param int $scoid The sco ID.
  53       * @param array $allowedlist The SQL and params to get the userlist.
  54       * @return array of data indexed per bar.
  55       */
  56      protected function get_data($scoid, $allowedlistsql) {
  57          global $DB;
  58          $data = array_fill(0, self::BANDS, 0);
  59  
  60          list($allowedlist, $params) = $allowedlistsql;
  61          $params = array_merge($params, ['scoid' => $scoid]);
  62  
  63          // Construct the SQL.
  64          $sql = "SELECT DISTINCT " . $DB->sql_concat('a.userid', '\'#\'', 'COALESCE(a.attempt, 0)') . " AS uniqueid,
  65                         a.userid AS userid,
  66                         a.scormid AS scormid,
  67                         a.attempt AS attempt,
  68                         v.scoid AS scoid
  69                    FROM {scorm_attempt} a
  70                    JOIN {scorm_scoes_value} v ON v.attemptid = a.id
  71                   WHERE a.userid IN ({$allowedlist}) AND v.scoid = :scoid";
  72          $attempts = $DB->get_records_sql($sql, $params);
  73  
  74          $usergrades = [];
  75          foreach ($attempts as $attempt) {
  76              if ($trackdata = scorm_get_tracks($scoid, $attempt->userid, $attempt->attempt)) {
  77                  if (isset($trackdata->score_raw)) {
  78                      $score = (int) $trackdata->score_raw;
  79                      if (empty($trackdata->score_min)) {
  80                          $minmark = 0;
  81                      } else {
  82                          $minmark = $trackdata->score_min;
  83                      }
  84                      // TODO MDL-55004: Get this value from elsewhere?
  85                      if (empty($trackdata->score_max)) {
  86                          $maxmark = 100;
  87                      } else {
  88                          $maxmark = $trackdata->score_max;
  89                      }
  90                      $range = ($maxmark - $minmark);
  91                      if (empty($range)) {
  92                          continue;
  93                      }
  94                      $percent = round((($score * 100) / $range), 2);
  95                      if (empty($usergrades[$attempt->userid]) || !isset($usergrades[$attempt->userid])
  96                              || ($percent > $usergrades[$attempt->userid]) || ($usergrades[$attempt->userid] === '*')) {
  97                          $usergrades[$attempt->userid] = $percent;
  98                      }
  99                      unset($percent);
 100                  } else {
 101                      // User has made an attempt but either SCO was not able to record the score or something else is broken in SCO.
 102                      if (!isset($usergrades[$attempt->userid])) {
 103                          $usergrades[$attempt->userid] = '*';
 104                      }
 105                  }
 106              }
 107          }
 108  
 109          // Recording all users who attempted the SCO, but resulting data was invalid.
 110          foreach ($usergrades as $userpercent) {
 111              if ($userpercent === '*') {
 112                  $data[0]++;
 113              } else {
 114                  $gradeband = floor($userpercent / self::BANDWIDTH);
 115                  if ($gradeband != (self::BANDS - 1)) {
 116                      $gradeband++;
 117                  }
 118                  $data[$gradeband]++;
 119              }
 120          }
 121  
 122          return $data;
 123      }
 124  
 125      /**
 126       * Displays the full report.
 127       *
 128       * @param \stdClass $scorm full SCORM object
 129       * @param \stdClass $cm - full course_module object
 130       * @param \stdClass $course - full course object
 131       * @param string $download - type of download being requested
 132       * @return void
 133       */
 134      public function display($scorm, $cm, $course, $download) {
 135          global $DB, $OUTPUT, $PAGE;
 136  
 137          $contextmodule = context_module::instance($cm->id);
 138  
 139          $actionbar = new \mod_scorm\output\actionbar($cm->id, false, 0);
 140          $renderer = $PAGE->get_renderer('mod_scorm');
 141          echo $renderer->report_actionbar($actionbar);
 142  
 143          if ($groupmode = groups_get_activity_groupmode($cm)) {   // Groups are being used.
 144              groups_print_activity_menu($cm, new moodle_url($PAGE->url));
 145          }
 146  
 147          // Find out current restriction.
 148          $group = groups_get_activity_group($cm, true);
 149          $allowedlistsql = get_enrolled_sql($contextmodule, 'mod/scorm:savetrack', (int) $group);
 150  
 151          // Labels.
 152          $labels = [get_string('invaliddata', 'scormreport_graphs')];
 153          for ($i = 1; $i <= self::BANDS - 1; $i++) {
 154              $labels[] = ($i - 1) * self::BANDWIDTH . ' - ' . $i * self::BANDWIDTH;
 155          }
 156  
 157          if ($scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id')) {
 158              foreach ($scoes as $sco) {
 159                  if ($sco->launch != '') {
 160  
 161                      $data = $this->get_data($sco->id, $allowedlistsql);
 162                      $series = new chart_series($sco->title, $data);
 163  
 164                      $chart = new chart_bar();
 165                      $chart->set_labels($labels);
 166                      $chart->add_series($series);
 167                      $chart->get_xaxis(0, true)->set_label(get_string('percent', 'scormreport_graphs'));
 168                      $yaxis = $chart->get_yaxis(0, true);
 169                      $yaxis->set_label(get_string('participants', 'scormreport_graphs'));
 170                      $yaxis->set_stepsize(max(1, round(max($data) / 10)));
 171  
 172                      echo $OUTPUT->heading($sco->title, 3);
 173                      echo $OUTPUT->render($chart);
 174                  }
 175              }
 176          }
 177      }
 178  }