| 1 | efrain | 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 | }
 |