MDL-45712 mod_scorm: add results column to interactions report.
[moodle.git] / mod / scorm / report / interactions / classes / report.php
CommitLineData
8fb40a45
AKA
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 basic reporting plugin
b2f5ce35
AKA
18 * @package scormreport
19 * @subpackage interactions
8fb40a45
AKA
20 * @author Dan Marsden and Ankit Kumar Agarwal
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
2eca9a23
AA
24namespace scormreport_interactions;
25
8fb40a45
AKA
26defined('MOODLE_INTERNAL') || die();
27
28require_once($CFG->dirroot.'/mod/scorm/report/interactions/responsessettings_form.php');
29
2eca9a23 30class report extends \mod_scorm\report {
8fb40a45
AKA
31 /**
32 * displays the full report
2eca9a23
AA
33 * @param \stdClass $scorm full SCORM object
34 * @param \stdClass $cm - full course_module object
35 * @param \stdClass $course - full course object
8fb40a45
AKA
36 * @param string $download - type of download being requested
37 */
27b8872c 38 public function display($scorm, $cm, $course, $download) {
8fb40a45 39 global $CFG, $DB, $OUTPUT, $PAGE;
f1e31687 40
2eca9a23 41 $contextmodule = \context_module::instance($cm->id);
8fb40a45 42 $action = optional_param('action', '', PARAM_ALPHA);
f9ab70a9 43 $attemptids = optional_param_array('attemptid', array(), PARAM_RAW);
b27917ee 44 $attemptsmode = optional_param('attemptsmode', SCORM_REPORT_ATTEMPTS_ALL_STUDENTS, PARAM_INT);
2eca9a23 45 $PAGE->set_url(new \moodle_url($PAGE->url, array('attemptsmode' => $attemptsmode)));
8fb40a45
AKA
46
47 if ($action == 'delete' && has_capability('mod/scorm:deleteresponses', $contextmodule) && confirm_sesskey()) {
27b8872c 48 if (scorm_delete_responses($attemptids, $scorm)) { // Delete responses.
8fb40a45
AKA
49 echo $OUTPUT->notification(get_string('scormresponsedeleted', 'scorm'), 'notifysuccess');
50 }
51 }
27b8872c 52 // Find out current groups mode.
6073fcbe 53 $currentgroup = groups_get_activity_group($cm, true);
8fb40a45 54
27b8872c 55 // Detailed report.
2eca9a23 56 $mform = new \mod_scorm_report_interactions_settings($PAGE->url, compact('currentgroup'));
8fb40a45 57 if ($fromform = $mform->get_data()) {
8fb40a45
AKA
58 $pagesize = $fromform->pagesize;
59 $includeqtext = $fromform->qtext;
60 $includeresp = $fromform->resp;
61 $includeright = $fromform->right;
3ef6e460 62 $includeresult = $fromform->result;
8fb40a45
AKA
63 set_user_preference('scorm_report_pagesize', $pagesize);
64 set_user_preference('scorm_report_interactions_qtext', $includeqtext);
65 set_user_preference('scorm_report_interactions_resp', $includeresp);
66 set_user_preference('scorm_report_interactions_right', $includeright);
3ef6e460 67 set_user_preference('scorm_report_interactions_result', $includeresult);
8fb40a45 68 } else {
8fb40a45 69 $pagesize = get_user_preferences('scorm_report_pagesize', 0);
8fb40a45
AKA
70 $includeqtext = get_user_preferences('scorm_report_interactions_qtext', 0);
71 $includeresp = get_user_preferences('scorm_report_interactions_resp', 1);
72 $includeright = get_user_preferences('scorm_report_interactions_right', 0);
3ef6e460 73 $includeresult = get_user_preferences('scorm_report_interactions_result', 0);
8fb40a45
AKA
74 }
75 if ($pagesize < 1) {
76 $pagesize = SCORM_REPORT_DEFAULT_PAGE_SIZE;
77 }
78
27b8872c 79 // Select group menu.
8fb40a45
AKA
80 $displayoptions = array();
81 $displayoptions['attemptsmode'] = $attemptsmode;
82 $displayoptions['qtext'] = $includeqtext;
83 $displayoptions['resp'] = $includeresp;
84 $displayoptions['right'] = $includeright;
3ef6e460 85 $displayoptions['result'] = $includeresult;
3297bb1a 86
11359796 87 $mform->set_data($displayoptions + array('pagesize' => $pagesize));
27b8872c 88 if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used.
8fb40a45 89 if (!$download) {
2eca9a23 90 groups_print_activity_menu($cm, new \moodle_url($PAGE->url, $displayoptions));
8fb40a45
AKA
91 }
92 }
2eca9a23 93 $formattextoptions = array('context' => \context_course::instance($course->id));
8fb40a45
AKA
94
95 // We only want to show the checkbox to delete attempts
96 // if the user has permissions and if the report mode is showing attempts.
97 $candelete = has_capability('mod/scorm:deleteresponses', $contextmodule)
b2f5ce35 98 && ($attemptsmode != SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO);
27b8872c 99 // Select the students.
8fb40a45
AKA
100 $nostudents = false;
101
102 if (empty($currentgroup)) {
27b8872c 103 // All users who can attempt scoes.
74816ad8 104 if (!$students = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', 'u.id', '', '', '', '', '', false)) {
8fb40a45
AKA
105 echo $OUTPUT->notification(get_string('nostudentsyet'));
106 $nostudents = true;
107 $allowedlist = '';
108 } else {
7def307d 109 $allowedlist = array_keys($students);
8fb40a45 110 }
74816ad8 111 unset($students);
8fb40a45 112 } else {
27b8872c
N
113 // All users who can attempt scoes and who are in the currently selected group.
114 if (!$groupstudents = get_users_by_capability($contextmodule,
115 'mod/scorm:savetrack', 'u.id', '', '', '',
116 $currentgroup, '', false)) {
8fb40a45
AKA
117 echo $OUTPUT->notification(get_string('nostudentsingroup'));
118 $nostudents = true;
119 $groupstudents = array();
120 }
6073fcbe 121 $allowedlist = array_keys($groupstudents);
74816ad8 122 unset($groupstudents);
8fb40a45 123 }
8fb40a45 124 if ( !$nostudents ) {
27b8872c 125 // Now check if asked download of data.
2eca9a23 126 $coursecontext = \context_course::instance($course->id);
8fb40a45 127 if ($download) {
27b8872c 128 $filename = clean_filename("$course->shortname ".format_string($scorm->name, true, $formattextoptions));
8fb40a45
AKA
129 }
130
27b8872c 131 // Define table columns.
8fb40a45
AKA
132 $columns = array();
133 $headers = array();
134 if (!$download && $candelete) {
b2f5ce35
AKA
135 $columns[] = 'checkbox';
136 $headers[] = null;
8fb40a45
AKA
137 }
138 if (!$download && $CFG->grade_report_showuserimage) {
b2f5ce35
AKA
139 $columns[] = 'picture';
140 $headers[] = '';
8fb40a45 141 }
b2f5ce35
AKA
142 $columns[] = 'fullname';
143 $headers[] = get_string('name');
63480434
AKA
144
145 $extrafields = get_extra_user_fields($coursecontext);
146 foreach ($extrafields as $field) {
147 $columns[] = $field;
148 $headers[] = get_user_field_name($field);
8fb40a45 149 }
b2f5ce35
AKA
150 $columns[] = 'attempt';
151 $headers[] = get_string('attempt', 'scorm');
152 $columns[] = 'start';
153 $headers[] = get_string('started', 'scorm');
154 $columns[] = 'finish';
155 $headers[] = get_string('last', 'scorm');
156 $columns[] = 'score';
157 $headers[] = get_string('score', 'scorm');
b33e4665 158 $scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id');
b2f5ce35
AKA
159 foreach ($scoes as $sco) {
160 if ($sco->launch != '') {
161 $columns[] = 'scograde'.$sco->id;
27b8872c 162 $headers[] = format_string($sco->title, '', $formattextoptions);
8fb40a45 163 }
8fb40a45 164 }
b2f5ce35 165
7def307d 166 $params = array();
bbe5bad5 167 list($usql, $params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED);
27b8872c 168 // Construct the SQL.
c03d2b75
AKA
169 $select = 'SELECT DISTINCT '.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, ';
170 $select .= 'st.scormid AS scormid, st.attempt AS attempt, ' .
2eca9a23 171 \user_picture::fields('u', array('idnumber'), 'userid') .
f1e31687 172 get_extra_user_fields_sql($coursecontext, 'u', '', array('email', 'idnumber')) . ' ';
c03d2b75 173
27b8872c 174 // This part is the same for all cases - join users and scorm_scoes_track tables.
c03d2b75
AKA
175 $from = 'FROM {user} u ';
176 $from .= 'LEFT JOIN {scorm_scoes_track} st ON st.userid = u.id AND st.scormid = '.$scorm->id;
177 switch ($attemptsmode) {
178 case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH:
27b8872c 179 // Show only students with attempts.
7def307d 180 $where = ' WHERE u.id ' .$usql. ' AND st.userid IS NOT NULL';
c03d2b75
AKA
181 break;
182 case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO:
27b8872c 183 // Show only students without attempts.
7def307d 184 $where = ' WHERE u.id ' .$usql. ' AND st.userid IS NULL';
c03d2b75
AKA
185 break;
186 case SCORM_REPORT_ATTEMPTS_ALL_STUDENTS:
27b8872c 187 // Show all students with or without attempts.
7def307d 188 $where = ' WHERE u.id ' .$usql. ' AND (st.userid IS NOT NULL OR st.userid IS NULL)';
c03d2b75
AKA
189 break;
190 }
191
192 $countsql = 'SELECT COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').')) AS nbresults, ';
193 $countsql .= 'COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'st.attempt').')) AS nbattempts, ';
194 $countsql .= 'COUNT(DISTINCT(u.id)) AS nbusers ';
195 $countsql .= $from.$where;
3ab853fa 196 $questioncount = get_scorm_question_count($scorm->id);
f007c032 197 $nbmaincolumns = count($columns);
27b8872c 198 for ($id = 0; $id < $questioncount; $id++) {
8fb40a45
AKA
199 if ($displayoptions['qtext']) {
200 $columns[] = 'question' . $id;
201 $headers[] = get_string('questionx', 'scormreport_interactions', $id);
202 }
203 if ($displayoptions['resp']) {
204 $columns[] = 'response' . $id;
205 $headers[] = get_string('responsex', 'scormreport_interactions', $id);
206 }
207 if ($displayoptions['right']) {
208 $columns[] = 'right' . $id;
209 $headers[] = get_string('rightanswerx', 'scormreport_interactions', $id);
210 }
3ef6e460
HN
211 if ($displayoptions['result']) {
212 $columns[] = 'result' . $id;
213 $headers[] = get_string('resultx', 'scormreport_interactions', $id);
214 }
8fb40a45
AKA
215 }
216
217 if (!$download) {
2eca9a23 218 $table = new \flexible_table('mod-scorm-report');
8fb40a45
AKA
219
220 $table->define_columns($columns);
221 $table->define_headers($headers);
222 $table->define_baseurl($PAGE->url);
223
224 $table->sortable(true);
225 $table->collapsible(true);
226
27b8872c 227 // This is done to prevent redundant data, when a user has multiple attempts.
8fb40a45
AKA
228 $table->column_suppress('picture');
229 $table->column_suppress('fullname');
63480434
AKA
230 foreach ($extrafields as $field) {
231 $table->column_suppress($field);
232 }
8fb40a45
AKA
233
234 $table->no_sorting('start');
235 $table->no_sorting('finish');
236 $table->no_sorting('score');
e205a159
SC
237 $table->no_sorting('checkbox');
238 $table->no_sorting('picture');
e7ec46fc 239
27b8872c 240 for ($id = 0; $id < $questioncount; $id++) {
1868607a
AA
241 if ($displayoptions['qtext']) {
242 $table->no_sorting('question'.$id);
243 }
244 if ($displayoptions['resp']) {
245 $table->no_sorting('response'.$id);
246 }
247 if ($displayoptions['right']) {
248 $table->no_sorting('right'.$id);
249 }
3ef6e460
HN
250 if ($displayoptions['result']) {
251 $table->no_sorting('result'.$id);
252 }
1868607a
AA
253 }
254
b2f5ce35
AKA
255 foreach ($scoes as $sco) {
256 if ($sco->launch != '') {
257 $table->no_sorting('scograde'.$sco->id);
8fb40a45
AKA
258 }
259 }
260
261 $table->column_class('picture', 'picture');
262 $table->column_class('fullname', 'bold');
263 $table->column_class('score', 'bold');
264
265 $table->set_attribute('cellspacing', '0');
266 $table->set_attribute('id', 'attempts');
267 $table->set_attribute('class', 'generaltable generalbox');
268
27b8872c 269 // Start working -- this is necessary as soon as the niceties are over.
8fb40a45 270 $table->setup();
b2f5ce35 271 } else if ($download == 'ODS') {
8fb40a45
AKA
272 require_once("$CFG->libdir/odslib.class.php");
273
274 $filename .= ".ods";
27b8872c 275 // Creating a workbook.
2eca9a23 276 $workbook = new \MoodleODSWorkbook("-");
27b8872c 277 // Sending HTTP headers.
8fb40a45 278 $workbook->send($filename);
27b8872c 279 // Creating the first worksheet.
8fb40a45 280 $sheettitle = get_string('report', 'scorm');
75427a82 281 $myxls = $workbook->add_worksheet($sheettitle);
27b8872c 282 // Format types.
75427a82 283 $format = $workbook->add_format();
8fb40a45 284 $format->set_bold(0);
75427a82 285 $formatbc = $workbook->add_format();
8fb40a45
AKA
286 $formatbc->set_bold(1);
287 $formatbc->set_align('center');
75427a82 288 $formatb = $workbook->add_format();
8fb40a45 289 $formatb->set_bold(1);
75427a82 290 $formaty = $workbook->add_format();
8fb40a45 291 $formaty->set_bg_color('yellow');
75427a82 292 $formatc = $workbook->add_format();
8fb40a45 293 $formatc->set_align('center');
75427a82 294 $formatr = $workbook->add_format();
8fb40a45
AKA
295 $formatr->set_bold(1);
296 $formatr->set_color('red');
297 $formatr->set_align('center');
75427a82 298 $formatg = $workbook->add_format();
8fb40a45
AKA
299 $formatg->set_bold(1);
300 $formatg->set_color('green');
301 $formatg->set_align('center');
27b8872c 302 // Here starts workshhet headers.
8fb40a45
AKA
303
304 $colnum = 0;
305 foreach ($headers as $item) {
306 $myxls->write(0, $colnum, $item, $formatbc);
307 $colnum++;
308 }
b2f5ce35 309 $rownum = 1;
27b8872c 310 } else if ($download == 'Excel') {
8fb40a45
AKA
311 require_once("$CFG->libdir/excellib.class.php");
312
313 $filename .= ".xls";
27b8872c 314 // Creating a workbook.
2eca9a23 315 $workbook = new \MoodleExcelWorkbook("-");
27b8872c 316 // Sending HTTP headers.
8fb40a45 317 $workbook->send($filename);
27b8872c 318 // Creating the first worksheet.
8fb40a45 319 $sheettitle = get_string('report', 'scorm');
75427a82 320 $myxls = $workbook->add_worksheet($sheettitle);
27b8872c 321 // Format types.
75427a82 322 $format = $workbook->add_format();
8fb40a45 323 $format->set_bold(0);
75427a82 324 $formatbc = $workbook->add_format();
8fb40a45
AKA
325 $formatbc->set_bold(1);
326 $formatbc->set_align('center');
75427a82 327 $formatb = $workbook->add_format();
8fb40a45 328 $formatb->set_bold(1);
75427a82 329 $formaty = $workbook->add_format();
8fb40a45 330 $formaty->set_bg_color('yellow');
75427a82 331 $formatc = $workbook->add_format();
8fb40a45 332 $formatc->set_align('center');
75427a82 333 $formatr = $workbook->add_format();
8fb40a45
AKA
334 $formatr->set_bold(1);
335 $formatr->set_color('red');
336 $formatr->set_align('center');
75427a82 337 $formatg = $workbook->add_format();
8fb40a45
AKA
338 $formatg->set_bold(1);
339 $formatg->set_color('green');
340 $formatg->set_align('center');
341
342 $colnum = 0;
343 foreach ($headers as $item) {
344 $myxls->write(0, $colnum, $item, $formatbc);
345 $colnum++;
346 }
b2f5ce35
AKA
347 $rownum = 1;
348 } else if ($download == 'CSV') {
2eca9a23 349 $csvexport = new \csv_export_writer("tab");
75427a82 350 $csvexport->set_filename($filename, ".txt");
0253b260 351 $csvexport->add_data($headers);
8fb40a45 352 }
8fb40a45
AKA
353
354 if (!$download) {
355 $sort = $table->get_sql_sort();
356 } else {
357 $sort = '';
358 }
27b8872c 359 // Fix some wired sorting.
8fb40a45
AKA
360 if (empty($sort)) {
361 $sort = ' ORDER BY uniqueid';
362 } else {
363 $sort = ' ORDER BY '.$sort;
364 }
365
366 if (!$download) {
27b8872c 367 // Add extra limits due to initials bar.
8fb40a45
AKA
368 list($twhere, $tparams) = $table->get_sql_where();
369 if ($twhere) {
27b8872c 370 $where .= ' AND '.$twhere; // Initial bar.
8fb40a45
AKA
371 $params = array_merge($params, $tparams);
372 }
373
374 if (!empty($countsql)) {
27b8872c 375 $count = $DB->get_record_sql($countsql, $params);
8fb40a45
AKA
376 $totalinitials = $count->nbresults;
377 if ($twhere) {
378 $countsql .= ' AND '.$twhere;
379 }
380 $count = $DB->get_record_sql($countsql, $params);
381 $total = $count->nbresults;
382 }
383
384 $table->pagesize($pagesize, $total);
385
2eca9a23 386 echo \html_writer::start_div('scormattemptcounts');
8fb40a45
AKA
387 if ( $count->nbresults == $count->nbattempts ) {
388 echo get_string('reportcountattempts', 'scorm', $count);
27b8872c 389 } else if ( $count->nbattempts > 0 ) {
8fb40a45
AKA
390 echo get_string('reportcountallattempts', 'scorm', $count);
391 } else {
392 echo $count->nbusers.' '.get_string('users');
393 }
2eca9a23 394 echo \html_writer::end_div();
8fb40a45
AKA
395 }
396
27b8872c 397 // Fetch the attempts.
8fb40a45
AKA
398 if (!$download) {
399 $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params,
400 $table->get_page_start(), $table->get_page_size());
2eca9a23 401 echo \html_writer::start_div('', array('id' => 'scormtablecontainer'));
8fb40a45 402 if ($candelete) {
27b8872c 403 // Start form.
8fb40a45 404 $strreallydel = addslashes_js(get_string('deleteattemptcheck', 'scorm'));
2eca9a23 405 echo \html_writer::start_tag('form', array('id' => 'attemptsform', 'method' => 'post',
27b8872c
N
406 'action' => $PAGE->url->out(false),
407 'onsubmit' => 'return confirm("'.$strreallydel.'");'));
2eca9a23
AA
408 echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'action', 'value' => 'delete'));
409 echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
410 echo \html_writer::start_div('', array('style' => 'display: none;'));
411 echo \html_writer::input_hidden_params($PAGE->url);
412 echo \html_writer::end_div();
413 echo \html_writer::start_div();
8fb40a45 414 }
27b8872c 415 $table->initialbars($totalinitials > 20); // Build table rows.
8fb40a45
AKA
416 } else {
417 $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params);
418 }
8fb40a45
AKA
419 if ($attempts) {
420 foreach ($attempts as $scouser) {
421 $row = array();
422 if (!empty($scouser->attempt)) {
423 $timetracks = scorm_get_sco_runtime($scorm->id, false, $scouser->userid, $scouser->attempt);
49ff0cf3
DM
424 } else {
425 $timetracks = '';
8fb40a45
AKA
426 }
427 if (in_array('checkbox', $columns)) {
428 if ($candelete && !empty($timetracks->start)) {
2eca9a23 429 $row[] = \html_writer::checkbox('attemptid[]', $scouser->userid . ':' . $scouser->attempt, false);
8fb40a45
AKA
430 } else if ($candelete) {
431 $row[] = '';
432 }
433 }
434 if (in_array('picture', $columns)) {
2eca9a23
AA
435 $user = new \stdClass();
436 $additionalfields = explode(',', \user_picture::fields());
5b1944bb 437 $user = username_load_fields_from_object($user, $scouser, null, $additionalfields);
e351bed5 438 $user->id = $scouser->userid;
27b8872c 439 $row[] = $OUTPUT->user_picture($user, array('courseid' => $course->id));
8fb40a45
AKA
440 }
441 if (!$download) {
2eca9a23
AA
442 $url = new \moodle_url('/user/view.php', array('id' => $scouser->userid, 'course' => $course->id));
443 $row[] = \html_writer::link($url, fullname($scouser));
8fb40a45
AKA
444 } else {
445 $row[] = fullname($scouser);
446 }
63480434
AKA
447 foreach ($extrafields as $field) {
448 $row[] = s($scouser->{$field});
8fb40a45
AKA
449 }
450 if (empty($timetracks->start)) {
451 $row[] = '-';
452 $row[] = '-';
453 $row[] = '-';
454 $row[] = '-';
455 } else {
456 if (!$download) {
2eca9a23 457 $url = new \moodle_url('/mod/scorm/report/userreport.php',
4cb25b36 458 array('id' => $cm->id,
459 'user' => $scouser->userid,
460 'attempt' => $scouser->attempt));
2eca9a23 461 $row[] = \html_writer::link($url, $scouser->attempt);
8fb40a45
AKA
462 } else {
463 $row[] = $scouser->attempt;
464 }
27b8872c 465 if ($download == 'ODS' || $download == 'Excel' ) {
8fb40a45
AKA
466 $row[] = userdate($timetracks->start, get_string("strftimedatetime", "langconfig"));
467 } else {
468 $row[] = userdate($timetracks->start);
469 }
27b8872c 470 if ($download == 'ODS' || $download == 'Excel' ) {
8fb40a45
AKA
471 $row[] = userdate($timetracks->finish, get_string('strftimedatetime', 'langconfig'));
472 } else {
473 $row[] = userdate($timetracks->finish);
474 }
475 $row[] = scorm_grade_user_attempt($scorm, $scouser->userid, $scouser->attempt);
476 }
27b8872c 477 // Print out all scores of attempt.
b2f5ce35
AKA
478 foreach ($scoes as $sco) {
479 if ($sco->launch != '') {
480 if ($trackdata = scorm_get_tracks($sco->id, $scouser->userid, $scouser->attempt)) {
481 if ($trackdata->status == '') {
482 $trackdata->status = 'notattempted';
483 }
484 $strstatus = get_string($trackdata->status, 'scorm');
27b8872c 485 // If raw score exists, print it.
b2f5ce35
AKA
486 if ($trackdata->score_raw != '') {
487 $score = $trackdata->score_raw;
27b8872c 488 // Add max score if it exists.
9381c280
AA
489 if (isset($trackdata->score_max)) {
490 $score .= '/'.$trackdata->score_max;
8fb40a45 491 }
27b8872c 492 } else { // Else print out status.
b2f5ce35
AKA
493 $score = $strstatus;
494 }
495 if (!$download) {
2eca9a23 496 $url = new \moodle_url('/mod/scorm/report/userreporttracks.php', array('id' => $cm->id,
e2cd4f5b 497 'scoid' => $sco->id, 'user' => $scouser->userid, 'attempt' => $scouser->attempt));
2eca9a23
AA
498 $row[] = \html_writer::img($OUTPUT->pix_url($trackdata->status, 'scorm'), $strstatus,
499 array('title' => $strstatus)) . \html_writer::empty_tag('br') .
500 \html_writer::link($url, $score, array('title' => get_string('details', 'scorm')));
b2f5ce35
AKA
501 } else {
502 $row[] = $score;
503 }
27b8872c
N
504 // Interaction data.
505 for ($i = 0; $i < $questioncount; $i++) {
b2f5ce35 506 if ($displayoptions['qtext']) {
27b8872c 507 $element = 'cmi.interactions_'.$i.'.id';
b2f5ce35
AKA
508 if (isset($trackdata->$element)) {
509 $row[] = s($trackdata->$element);
510 } else {
511 $row[] = '&nbsp;';
11359796 512 }
b2f5ce35
AKA
513 }
514 if ($displayoptions['resp']) {
27b8872c 515 $element = 'cmi.interactions_'.$i.'.student_response';
b2f5ce35
AKA
516 if (isset($trackdata->$element)) {
517 $row[] = s($trackdata->$element);
518 } else {
519 $row[] = '&nbsp;';
11359796 520 }
b2f5ce35
AKA
521 }
522 if ($displayoptions['right']) {
27b8872c 523 $j = 0;
b2f5ce35
AKA
524 $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern';
525 $rightans = '';
526 if (isset($trackdata->$element)) {
27b8872c
N
527 while (isset($trackdata->$element)) {
528 if ($j > 0) {
b2f5ce35 529 $rightans .= ',';
11359796 530 }
b2f5ce35
AKA
531 $rightans .= s($trackdata->$element);
532 $j++;
533 $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern';
11359796 534 }
b2f5ce35
AKA
535 $row[] = $rightans;
536 } else {
537 $row[] = '&nbsp;';
11359796 538 }
11359796 539 }
3ef6e460
HN
540 if ($displayoptions['result']) {
541 $element = 'cmi.interactions_'.$i.'.result';
542 if (isset($trackdata->$element)) {
543 $row[] = s($trackdata->$element);
544 } else {
545 $row[] = '&nbsp;';
546 }
547 }
b2f5ce35 548 }
27b8872c 549 // End of interaction data.
b2f5ce35 550 } else {
27b8872c 551 // If we don't have track data, we haven't attempted yet.
b2f5ce35
AKA
552 $strstatus = get_string('notattempted', 'scorm');
553 if (!$download) {
2eca9a23
AA
554 $row[] = \html_writer::img($OUTPUT->pix_url('notattempted', 'scorm'), $strstatus,
555 array('title' => $strstatus)).\html_writer::empty_tag('br').$strstatus;
8fb40a45 556 } else {
b2f5ce35 557 $row[] = $strstatus;
8fb40a45 558 }
27b8872c
N
559 // Complete the empty cells.
560 for ($i = 0; $i < count($columns) - $nbmaincolumns; $i++) {
f007c032
GPL
561 $row[] = '&nbsp;';
562 }
8fb40a45
AKA
563 }
564 }
565 }
566
567 if (!$download) {
568 $table->add_data($row);
569 } else if ($download == 'Excel' or $download == 'ODS') {
570 $colnum = 0;
571 foreach ($row as $item) {
572 $myxls->write($rownum, $colnum, $item, $format);
573 $colnum++;
574 }
575 $rownum++;
b2f5ce35 576 } else if ($download == 'CSV') {
0253b260 577 $csvexport->add_data($row);
8fb40a45
AKA
578 }
579 }
580 if (!$download) {
581 $table->finish_output();
582 if ($candelete) {
2eca9a23
AA
583 echo \html_writer::start_tag('table', array('id' => 'commands'));
584 echo \html_writer::start_tag('tr').\html_writer::start_tag('td');
585 echo \html_writer::link('javascript:select_all_in(\'DIV\', null, \'scormtablecontainer\');',
27b8872c 586 get_string('selectall', 'scorm')).' / ';
2eca9a23 587 echo \html_writer::link('javascript:deselect_all_in(\'DIV\', null, \'scormtablecontainer\');',
27b8872c 588 get_string('selectnone', 'scorm'));
8fb40a45 589 echo '&nbsp;&nbsp;';
2eca9a23 590 echo \html_writer::empty_tag('input', array('type' => 'submit',
5639baa8 591 'value' => get_string('deleteselected', 'scorm')));
2eca9a23 592 echo \html_writer::end_tag('td').\html_writer::end_tag('tr').\html_writer::end_tag('table');
27b8872c 593 // Close form.
2eca9a23
AA
594 echo \html_writer::end_tag('div');
595 echo \html_writer::end_tag('form');
8fb40a45 596 }
2eca9a23 597 echo \html_writer::end_div();
8fb40a45 598 if (!empty($attempts)) {
2eca9a23
AA
599 echo \html_writer::start_tag('table', array('class' => 'boxaligncenter')).\html_writer::start_tag('tr');
600 echo \html_writer::start_tag('td');
601 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 602 array('download' => 'ODS') + $displayoptions),
8fb40a45 603 get_string('downloadods'));
2eca9a23
AA
604 echo \html_writer::end_tag('td');
605 echo \html_writer::start_tag('td');
606 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 607 array('download' => 'Excel') + $displayoptions),
8fb40a45 608 get_string('downloadexcel'));
2eca9a23
AA
609 echo \html_writer::end_tag('td');
610 echo \html_writer::start_tag('td');
611 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 612 array('download' => 'CSV') + $displayoptions),
8fb40a45 613 get_string('downloadtext'));
2eca9a23
AA
614 echo \html_writer::end_tag('td');
615 echo \html_writer::start_tag('td');
616 echo \html_writer::end_tag('td');
617 echo \html_writer::end_tag('tr').\html_writer::end_tag('table');
8fb40a45
AKA
618 }
619 }
8fb40a45 620 } else {
769a621d 621 if ($candelete && !$download) {
2eca9a23
AA
622 echo \html_writer::end_div();
623 echo \html_writer::end_tag('form');
85e976e5 624 $table->finish_output();
769a621d 625 }
2eca9a23 626 echo \html_writer::end_div();
85e976e5 627 }
27b8872c 628 // Show preferences form irrespective of attempts are there to report or not.
85e976e5
AKA
629 if (!$download) {
630 $mform->set_data(compact('detailedrep', 'pagesize', 'attemptsmode'));
631 $mform->display();
8fb40a45
AKA
632 }
633 if ($download == 'Excel' or $download == 'ODS') {
634 $workbook->close();
635 exit;
636 } else if ($download == 'CSV') {
0253b260 637 $csvexport->download_file();
8fb40a45
AKA
638 exit;
639 }
640 } else {
641 echo $OUTPUT->notification(get_string('noactivity', 'scorm'));
642 }
27b8872c 643 }// Function ends.
8fb40a45 644}