MDL-60494 mod_lti: Invalid </img>, example context
[moodle.git] / mod / scorm / report / graphs / classes / report.php
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  */
24 namespace scormreport_graphs;
26 defined('MOODLE_INTERNAL') || die();
28 use context_module;
29 use core\chart_bar;
30 use core\chart_series;
31 use moodle_url;
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  */
41 class report extends \mod_scorm\report {
43     /** Number of bars. */
44     const BANDS = 11;
46     /** Range of each bar. */
47     const BANDWIDTH = 10;
49     /**
50      * Get the data for the report.
51      *
52      * @param int $scoid The sco ID.
53      * @param array $allowedlist The list of user IDs allowed to be displayed.
54      * @return array of data indexed per bar.
55      */
56     protected function get_data($scoid, $allowedlist = []) {
57         global $DB;
58         $data = array_fill(0, self::BANDS, 0);
59         if (empty($allowedlist)) {
60             return $data;
61         }
63         list($usql, $params) = $DB->get_in_or_equal($allowedlist);
64         $params[] = $scoid;
66         // Construct the SQL.
67         $sql = "SELECT DISTINCT " . $DB->sql_concat('st.userid', '\'#\'', 'COALESCE(st.attempt, 0)') . " AS uniqueid,
68                        st.userid AS userid,
69                        st.scormid AS scormid,
70                        st.attempt AS attempt,
71                        st.scoid AS scoid
72                   FROM {scorm_scoes_track} st
73                  WHERE st.userid $usql AND st.scoid = ?";
74         $attempts = $DB->get_records_sql($sql, $params);
76         $usergrades = [];
77         foreach ($attempts as $attempt) {
78             if ($trackdata = scorm_get_tracks($scoid, $attempt->userid, $attempt->attempt)) {
79                 if (isset($trackdata->score_raw)) {
80                     $score = (int) $trackdata->score_raw;
81                     if (empty($trackdata->score_min)) {
82                         $minmark = 0;
83                     } else {
84                         $minmark = $trackdata->score_min;
85                     }
86                     // TODO MDL-55004: Get this value from elsewhere?
87                     if (empty($trackdata->score_max)) {
88                         $maxmark = 100;
89                     } else {
90                         $maxmark = $trackdata->score_max;
91                     }
92                     $range = ($maxmark - $minmark);
93                     if (empty($range)) {
94                         continue;
95                     }
96                     $percent = round((($score * 100) / $range), 2);
97                     if (empty($usergrades[$attempt->userid]) || !isset($usergrades[$attempt->userid])
98                             || ($percent > $usergrades[$attempt->userid]) || ($usergrades[$attempt->userid] === '*')) {
99                         $usergrades[$attempt->userid] = $percent;
100                     }
101                     unset($percent);
102                 } else {
103                     // User has made an attempt but either SCO was not able to record the score or something else is broken in SCO.
104                     if (!isset($usergrades[$attempt->userid])) {
105                         $usergrades[$attempt->userid] = '*';
106                     }
107                 }
108             }
109         }
111         // Recording all users who attempted the SCO, but resulting data was invalid.
112         foreach ($usergrades as $userpercent) {
113             if ($userpercent === '*') {
114                 $data[0]++;
115             } else {
116                 $gradeband = floor($userpercent / self::BANDWIDTH);
117                 if ($gradeband != (self::BANDS - 1)) {
118                     $gradeband++;
119                 }
120                 $data[$gradeband]++;
121             }
122         }
124         return $data;
125     }
127     /**
128      * Displays the full report.
129      *
130      * @param \stdClass $scorm full SCORM object
131      * @param \stdClass $cm - full course_module object
132      * @param \stdClass $course - full course object
133      * @param string $download - type of download being requested
134      * @return void
135      */
136     public function display($scorm, $cm, $course, $download) {
137         global $DB, $OUTPUT, $PAGE;
139         $contextmodule = context_module::instance($cm->id);
141         if ($groupmode = groups_get_activity_groupmode($cm)) {   // Groups are being used.
142             groups_print_activity_menu($cm, new moodle_url($PAGE->url));
143         }
145         // Find out current restriction.
146         $group = groups_get_activity_group($cm, true);
147         if (empty($group)) {
148             // All users who can attempt scoes.
149             $students = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', 'u.id' , '', '', '', '', '', false);
150             $allowedlist = empty($students) ? array() : array_keys($students);
151         } else {
152             // All users who can attempt scoes and who are in the currently selected group.
153             $groupstudents = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', 'u.id', '', '', '', $group, '', false);
154             $allowedlist = empty($groupstudents) ? array() : array_keys($groupstudents);
155         }
157         // Labels.
158         $labels = [get_string('invaliddata', 'scormreport_graphs')];
159         for ($i = 1; $i <= self::BANDS - 1; $i++) {
160             $labels[] = ($i - 1) * self::BANDWIDTH . ' - ' . $i * self::BANDWIDTH;
161         }
163         if ($scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id')) {
164             foreach ($scoes as $sco) {
165                 if ($sco->launch != '') {
167                     $data = $this->get_data($sco->id, $allowedlist);
168                     $series = new chart_series($sco->title, $data);
170                     $chart = new chart_bar();
171                     $chart->set_labels($labels);
172                     $chart->add_series($series);
173                     $chart->get_xaxis(0, true)->set_label(get_string('percent', 'scormreport_graphs'));
174                     $yaxis = $chart->get_yaxis(0, true);
175                     $yaxis->set_label(get_string('participants', 'scormreport_graphs'));
176                     $yaxis->set_stepsize(max(1, round(max($data) / 10)));
178                     echo $OUTPUT->heading($sco->title, 3);
179                     echo $OUTPUT->render($chart);
180                 }
181             }
182         }
183     }