MDL-68784 scorm: Removed limit on allowed scorm users in 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 100 $nostudents = false;
91f26b58 101 list($allowedlistsql, $params) = get_enrolled_sql($contextmodule, 'mod/scorm:savetrack', (int) $currentgroup);
8fb40a45 102 if (empty($currentgroup)) {
27b8872c 103 // All users who can attempt scoes.
91f26b58 104 if (!$DB->record_exists_sql($allowedlistsql, $params)) {
8fb40a45
AKA
105 echo $OUTPUT->notification(get_string('nostudentsyet'));
106 $nostudents = true;
8fb40a45
AKA
107 }
108 } else {
27b8872c 109 // All users who can attempt scoes and who are in the currently selected group.
91f26b58 110 if (!$DB->record_exists_sql($allowedlistsql, $params)) {
8fb40a45
AKA
111 echo $OUTPUT->notification(get_string('nostudentsingroup'));
112 $nostudents = true;
8fb40a45 113 }
8fb40a45 114 }
8fb40a45 115 if ( !$nostudents ) {
27b8872c 116 // Now check if asked download of data.
2eca9a23 117 $coursecontext = \context_course::instance($course->id);
8fb40a45 118 if ($download) {
27b8872c 119 $filename = clean_filename("$course->shortname ".format_string($scorm->name, true, $formattextoptions));
8fb40a45
AKA
120 }
121
27b8872c 122 // Define table columns.
8fb40a45
AKA
123 $columns = array();
124 $headers = array();
125 if (!$download && $candelete) {
b2f5ce35 126 $columns[] = 'checkbox';
0b88a8bc 127 $headers[] = $this->generate_master_checkbox();
8fb40a45
AKA
128 }
129 if (!$download && $CFG->grade_report_showuserimage) {
b2f5ce35
AKA
130 $columns[] = 'picture';
131 $headers[] = '';
8fb40a45 132 }
b2f5ce35
AKA
133 $columns[] = 'fullname';
134 $headers[] = get_string('name');
63480434
AKA
135
136 $extrafields = get_extra_user_fields($coursecontext);
137 foreach ($extrafields as $field) {
138 $columns[] = $field;
139 $headers[] = get_user_field_name($field);
8fb40a45 140 }
b2f5ce35
AKA
141 $columns[] = 'attempt';
142 $headers[] = get_string('attempt', 'scorm');
143 $columns[] = 'start';
144 $headers[] = get_string('started', 'scorm');
145 $columns[] = 'finish';
146 $headers[] = get_string('last', 'scorm');
147 $columns[] = 'score';
148 $headers[] = get_string('score', 'scorm');
b33e4665 149 $scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id');
b2f5ce35
AKA
150 foreach ($scoes as $sco) {
151 if ($sco->launch != '') {
152 $columns[] = 'scograde'.$sco->id;
27b8872c 153 $headers[] = format_string($sco->title, '', $formattextoptions);
8fb40a45 154 }
8fb40a45 155 }
b2f5ce35 156
27b8872c 157 // Construct the SQL.
c03d2b75
AKA
158 $select = 'SELECT DISTINCT '.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, ';
159 $select .= 'st.scormid AS scormid, st.attempt AS attempt, ' .
2eca9a23 160 \user_picture::fields('u', array('idnumber'), 'userid') .
f1e31687 161 get_extra_user_fields_sql($coursecontext, 'u', '', array('email', 'idnumber')) . ' ';
c03d2b75 162
27b8872c 163 // This part is the same for all cases - join users and scorm_scoes_track tables.
c03d2b75
AKA
164 $from = 'FROM {user} u ';
165 $from .= 'LEFT JOIN {scorm_scoes_track} st ON st.userid = u.id AND st.scormid = '.$scorm->id;
166 switch ($attemptsmode) {
167 case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH:
27b8872c 168 // Show only students with attempts.
91f26b58 169 $where = " WHERE u.id IN ({$allowedlistsql}) AND st.userid IS NOT NULL";
c03d2b75
AKA
170 break;
171 case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO:
27b8872c 172 // Show only students without attempts.
91f26b58 173 $where = " WHERE u.id IN ({$allowedlistsql}) AND st.userid IS NULL";
c03d2b75
AKA
174 break;
175 case SCORM_REPORT_ATTEMPTS_ALL_STUDENTS:
27b8872c 176 // Show all students with or without attempts.
91f26b58 177 $where = " WHERE u.id IN ({$allowedlistsql}) AND (st.userid IS NOT NULL OR st.userid IS NULL)";
c03d2b75
AKA
178 break;
179 }
180
181 $countsql = 'SELECT COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').')) AS nbresults, ';
182 $countsql .= 'COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'st.attempt').')) AS nbattempts, ';
183 $countsql .= 'COUNT(DISTINCT(u.id)) AS nbusers ';
184 $countsql .= $from.$where;
3ab853fa 185 $questioncount = get_scorm_question_count($scorm->id);
f007c032 186 $nbmaincolumns = count($columns);
27b8872c 187 for ($id = 0; $id < $questioncount; $id++) {
8fb40a45
AKA
188 if ($displayoptions['qtext']) {
189 $columns[] = 'question' . $id;
190 $headers[] = get_string('questionx', 'scormreport_interactions', $id);
191 }
192 if ($displayoptions['resp']) {
193 $columns[] = 'response' . $id;
194 $headers[] = get_string('responsex', 'scormreport_interactions', $id);
195 }
196 if ($displayoptions['right']) {
197 $columns[] = 'right' . $id;
198 $headers[] = get_string('rightanswerx', 'scormreport_interactions', $id);
199 }
3ef6e460
HN
200 if ($displayoptions['result']) {
201 $columns[] = 'result' . $id;
202 $headers[] = get_string('resultx', 'scormreport_interactions', $id);
203 }
8fb40a45
AKA
204 }
205
206 if (!$download) {
2eca9a23 207 $table = new \flexible_table('mod-scorm-report');
8fb40a45
AKA
208
209 $table->define_columns($columns);
210 $table->define_headers($headers);
211 $table->define_baseurl($PAGE->url);
212
213 $table->sortable(true);
214 $table->collapsible(true);
215
27b8872c 216 // This is done to prevent redundant data, when a user has multiple attempts.
8fb40a45
AKA
217 $table->column_suppress('picture');
218 $table->column_suppress('fullname');
63480434
AKA
219 foreach ($extrafields as $field) {
220 $table->column_suppress($field);
221 }
8fb40a45
AKA
222
223 $table->no_sorting('start');
224 $table->no_sorting('finish');
225 $table->no_sorting('score');
e205a159
SC
226 $table->no_sorting('checkbox');
227 $table->no_sorting('picture');
e7ec46fc 228
27b8872c 229 for ($id = 0; $id < $questioncount; $id++) {
1868607a
AA
230 if ($displayoptions['qtext']) {
231 $table->no_sorting('question'.$id);
232 }
233 if ($displayoptions['resp']) {
234 $table->no_sorting('response'.$id);
235 }
236 if ($displayoptions['right']) {
237 $table->no_sorting('right'.$id);
238 }
3ef6e460
HN
239 if ($displayoptions['result']) {
240 $table->no_sorting('result'.$id);
241 }
1868607a
AA
242 }
243
b2f5ce35
AKA
244 foreach ($scoes as $sco) {
245 if ($sco->launch != '') {
246 $table->no_sorting('scograde'.$sco->id);
8fb40a45
AKA
247 }
248 }
249
250 $table->column_class('picture', 'picture');
251 $table->column_class('fullname', 'bold');
252 $table->column_class('score', 'bold');
253
254 $table->set_attribute('cellspacing', '0');
255 $table->set_attribute('id', 'attempts');
256 $table->set_attribute('class', 'generaltable generalbox');
257
27b8872c 258 // Start working -- this is necessary as soon as the niceties are over.
8fb40a45 259 $table->setup();
b2f5ce35 260 } else if ($download == 'ODS') {
8fb40a45
AKA
261 require_once("$CFG->libdir/odslib.class.php");
262
263 $filename .= ".ods";
27b8872c 264 // Creating a workbook.
2eca9a23 265 $workbook = new \MoodleODSWorkbook("-");
27b8872c 266 // Sending HTTP headers.
8fb40a45 267 $workbook->send($filename);
27b8872c 268 // Creating the first worksheet.
8fb40a45 269 $sheettitle = get_string('report', 'scorm');
75427a82 270 $myxls = $workbook->add_worksheet($sheettitle);
27b8872c 271 // Format types.
75427a82 272 $format = $workbook->add_format();
8fb40a45 273 $format->set_bold(0);
75427a82 274 $formatbc = $workbook->add_format();
8fb40a45
AKA
275 $formatbc->set_bold(1);
276 $formatbc->set_align('center');
75427a82 277 $formatb = $workbook->add_format();
8fb40a45 278 $formatb->set_bold(1);
75427a82 279 $formaty = $workbook->add_format();
8fb40a45 280 $formaty->set_bg_color('yellow');
75427a82 281 $formatc = $workbook->add_format();
8fb40a45 282 $formatc->set_align('center');
75427a82 283 $formatr = $workbook->add_format();
8fb40a45
AKA
284 $formatr->set_bold(1);
285 $formatr->set_color('red');
286 $formatr->set_align('center');
75427a82 287 $formatg = $workbook->add_format();
8fb40a45
AKA
288 $formatg->set_bold(1);
289 $formatg->set_color('green');
290 $formatg->set_align('center');
27b8872c 291 // Here starts workshhet headers.
8fb40a45
AKA
292
293 $colnum = 0;
294 foreach ($headers as $item) {
295 $myxls->write(0, $colnum, $item, $formatbc);
296 $colnum++;
297 }
b2f5ce35 298 $rownum = 1;
27b8872c 299 } else if ($download == 'Excel') {
8fb40a45
AKA
300 require_once("$CFG->libdir/excellib.class.php");
301
302 $filename .= ".xls";
27b8872c 303 // Creating a workbook.
2eca9a23 304 $workbook = new \MoodleExcelWorkbook("-");
27b8872c 305 // Sending HTTP headers.
8fb40a45 306 $workbook->send($filename);
27b8872c 307 // Creating the first worksheet.
8fb40a45 308 $sheettitle = get_string('report', 'scorm');
75427a82 309 $myxls = $workbook->add_worksheet($sheettitle);
27b8872c 310 // Format types.
75427a82 311 $format = $workbook->add_format();
8fb40a45 312 $format->set_bold(0);
75427a82 313 $formatbc = $workbook->add_format();
8fb40a45
AKA
314 $formatbc->set_bold(1);
315 $formatbc->set_align('center');
75427a82 316 $formatb = $workbook->add_format();
8fb40a45 317 $formatb->set_bold(1);
75427a82 318 $formaty = $workbook->add_format();
8fb40a45 319 $formaty->set_bg_color('yellow');
75427a82 320 $formatc = $workbook->add_format();
8fb40a45 321 $formatc->set_align('center');
75427a82 322 $formatr = $workbook->add_format();
8fb40a45
AKA
323 $formatr->set_bold(1);
324 $formatr->set_color('red');
325 $formatr->set_align('center');
75427a82 326 $formatg = $workbook->add_format();
8fb40a45
AKA
327 $formatg->set_bold(1);
328 $formatg->set_color('green');
329 $formatg->set_align('center');
330
331 $colnum = 0;
332 foreach ($headers as $item) {
333 $myxls->write(0, $colnum, $item, $formatbc);
334 $colnum++;
335 }
b2f5ce35
AKA
336 $rownum = 1;
337 } else if ($download == 'CSV') {
2eca9a23 338 $csvexport = new \csv_export_writer("tab");
75427a82 339 $csvexport->set_filename($filename, ".txt");
0253b260 340 $csvexport->add_data($headers);
8fb40a45 341 }
8fb40a45
AKA
342
343 if (!$download) {
344 $sort = $table->get_sql_sort();
345 } else {
346 $sort = '';
347 }
27b8872c 348 // Fix some wired sorting.
8fb40a45
AKA
349 if (empty($sort)) {
350 $sort = ' ORDER BY uniqueid';
351 } else {
352 $sort = ' ORDER BY '.$sort;
353 }
354
355 if (!$download) {
27b8872c 356 // Add extra limits due to initials bar.
8fb40a45
AKA
357 list($twhere, $tparams) = $table->get_sql_where();
358 if ($twhere) {
27b8872c 359 $where .= ' AND '.$twhere; // Initial bar.
8fb40a45
AKA
360 $params = array_merge($params, $tparams);
361 }
362
363 if (!empty($countsql)) {
27b8872c 364 $count = $DB->get_record_sql($countsql, $params);
8fb40a45
AKA
365 $totalinitials = $count->nbresults;
366 if ($twhere) {
367 $countsql .= ' AND '.$twhere;
368 }
369 $count = $DB->get_record_sql($countsql, $params);
370 $total = $count->nbresults;
371 }
372
373 $table->pagesize($pagesize, $total);
374
2eca9a23 375 echo \html_writer::start_div('scormattemptcounts');
8fb40a45
AKA
376 if ( $count->nbresults == $count->nbattempts ) {
377 echo get_string('reportcountattempts', 'scorm', $count);
27b8872c 378 } else if ( $count->nbattempts > 0 ) {
8fb40a45
AKA
379 echo get_string('reportcountallattempts', 'scorm', $count);
380 } else {
381 echo $count->nbusers.' '.get_string('users');
382 }
2eca9a23 383 echo \html_writer::end_div();
8fb40a45
AKA
384 }
385
27b8872c 386 // Fetch the attempts.
8fb40a45
AKA
387 if (!$download) {
388 $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params,
389 $table->get_page_start(), $table->get_page_size());
2eca9a23 390 echo \html_writer::start_div('', array('id' => 'scormtablecontainer'));
8fb40a45 391 if ($candelete) {
27b8872c 392 // Start form.
8fb40a45 393 $strreallydel = addslashes_js(get_string('deleteattemptcheck', 'scorm'));
2eca9a23 394 echo \html_writer::start_tag('form', array('id' => 'attemptsform', 'method' => 'post',
27b8872c
N
395 'action' => $PAGE->url->out(false),
396 'onsubmit' => 'return confirm("'.$strreallydel.'");'));
2eca9a23
AA
397 echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'action', 'value' => 'delete'));
398 echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
399 echo \html_writer::start_div('', array('style' => 'display: none;'));
400 echo \html_writer::input_hidden_params($PAGE->url);
401 echo \html_writer::end_div();
402 echo \html_writer::start_div();
8fb40a45 403 }
27b8872c 404 $table->initialbars($totalinitials > 20); // Build table rows.
8fb40a45
AKA
405 } else {
406 $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params);
407 }
8fb40a45
AKA
408 if ($attempts) {
409 foreach ($attempts as $scouser) {
410 $row = array();
411 if (!empty($scouser->attempt)) {
412 $timetracks = scorm_get_sco_runtime($scorm->id, false, $scouser->userid, $scouser->attempt);
49ff0cf3
DM
413 } else {
414 $timetracks = '';
8fb40a45
AKA
415 }
416 if (in_array('checkbox', $columns)) {
417 if ($candelete && !empty($timetracks->start)) {
0b88a8bc 418 $row[] = $this->generate_row_checkbox('attemptid[]', "{$scouser->userid}:{$scouser->attempt}");
8fb40a45
AKA
419 } else if ($candelete) {
420 $row[] = '';
421 }
422 }
423 if (in_array('picture', $columns)) {
2eca9a23
AA
424 $user = new \stdClass();
425 $additionalfields = explode(',', \user_picture::fields());
5b1944bb 426 $user = username_load_fields_from_object($user, $scouser, null, $additionalfields);
e351bed5 427 $user->id = $scouser->userid;
27b8872c 428 $row[] = $OUTPUT->user_picture($user, array('courseid' => $course->id));
8fb40a45
AKA
429 }
430 if (!$download) {
2eca9a23
AA
431 $url = new \moodle_url('/user/view.php', array('id' => $scouser->userid, 'course' => $course->id));
432 $row[] = \html_writer::link($url, fullname($scouser));
8fb40a45
AKA
433 } else {
434 $row[] = fullname($scouser);
435 }
63480434
AKA
436 foreach ($extrafields as $field) {
437 $row[] = s($scouser->{$field});
8fb40a45
AKA
438 }
439 if (empty($timetracks->start)) {
440 $row[] = '-';
441 $row[] = '-';
442 $row[] = '-';
443 $row[] = '-';
444 } else {
445 if (!$download) {
2eca9a23 446 $url = new \moodle_url('/mod/scorm/report/userreport.php',
4cb25b36 447 array('id' => $cm->id,
448 'user' => $scouser->userid,
449 'attempt' => $scouser->attempt));
2eca9a23 450 $row[] = \html_writer::link($url, $scouser->attempt);
8fb40a45
AKA
451 } else {
452 $row[] = $scouser->attempt;
453 }
27b8872c 454 if ($download == 'ODS' || $download == 'Excel' ) {
8fb40a45
AKA
455 $row[] = userdate($timetracks->start, get_string("strftimedatetime", "langconfig"));
456 } else {
457 $row[] = userdate($timetracks->start);
458 }
27b8872c 459 if ($download == 'ODS' || $download == 'Excel' ) {
8fb40a45
AKA
460 $row[] = userdate($timetracks->finish, get_string('strftimedatetime', 'langconfig'));
461 } else {
462 $row[] = userdate($timetracks->finish);
463 }
464 $row[] = scorm_grade_user_attempt($scorm, $scouser->userid, $scouser->attempt);
465 }
27b8872c 466 // Print out all scores of attempt.
2f673d8b 467 $emptyrow = $download ? '' : '&nbsp;';
b2f5ce35
AKA
468 foreach ($scoes as $sco) {
469 if ($sco->launch != '') {
470 if ($trackdata = scorm_get_tracks($sco->id, $scouser->userid, $scouser->attempt)) {
471 if ($trackdata->status == '') {
472 $trackdata->status = 'notattempted';
473 }
474 $strstatus = get_string($trackdata->status, 'scorm');
27b8872c 475 // If raw score exists, print it.
b2f5ce35
AKA
476 if ($trackdata->score_raw != '') {
477 $score = $trackdata->score_raw;
27b8872c 478 // Add max score if it exists.
9381c280
AA
479 if (isset($trackdata->score_max)) {
480 $score .= '/'.$trackdata->score_max;
8fb40a45 481 }
27b8872c 482 } else { // Else print out status.
b2f5ce35
AKA
483 $score = $strstatus;
484 }
485 if (!$download) {
2eca9a23 486 $url = new \moodle_url('/mod/scorm/report/userreporttracks.php', array('id' => $cm->id,
e2cd4f5b 487 'scoid' => $sco->id, 'user' => $scouser->userid, 'attempt' => $scouser->attempt));
663640f5 488 $row[] = $OUTPUT->pix_icon($trackdata->status, $strstatus, 'scorm') . '<br>' .
2eca9a23 489 \html_writer::link($url, $score, array('title' => get_string('details', 'scorm')));
b2f5ce35
AKA
490 } else {
491 $row[] = $score;
492 }
27b8872c
N
493 // Interaction data.
494 for ($i = 0; $i < $questioncount; $i++) {
b2f5ce35 495 if ($displayoptions['qtext']) {
27b8872c 496 $element = 'cmi.interactions_'.$i.'.id';
b2f5ce35
AKA
497 if (isset($trackdata->$element)) {
498 $row[] = s($trackdata->$element);
499 } else {
2f673d8b 500 $row[] = $emptyrow;
11359796 501 }
b2f5ce35
AKA
502 }
503 if ($displayoptions['resp']) {
27b8872c 504 $element = 'cmi.interactions_'.$i.'.student_response';
b2f5ce35
AKA
505 if (isset($trackdata->$element)) {
506 $row[] = s($trackdata->$element);
507 } else {
2f673d8b 508 $row[] = $emptyrow;
11359796 509 }
b2f5ce35
AKA
510 }
511 if ($displayoptions['right']) {
27b8872c 512 $j = 0;
b2f5ce35
AKA
513 $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern';
514 $rightans = '';
515 if (isset($trackdata->$element)) {
27b8872c
N
516 while (isset($trackdata->$element)) {
517 if ($j > 0) {
b2f5ce35 518 $rightans .= ',';
11359796 519 }
b2f5ce35
AKA
520 $rightans .= s($trackdata->$element);
521 $j++;
522 $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern';
11359796 523 }
b2f5ce35
AKA
524 $row[] = $rightans;
525 } else {
2f673d8b 526 $row[] = $emptyrow;
11359796 527 }
11359796 528 }
3ef6e460
HN
529 if ($displayoptions['result']) {
530 $element = 'cmi.interactions_'.$i.'.result';
531 if (isset($trackdata->$element)) {
532 $row[] = s($trackdata->$element);
533 } else {
2f673d8b 534 $row[] = $emptyrow;
3ef6e460
HN
535 }
536 }
b2f5ce35 537 }
27b8872c 538 // End of interaction data.
b2f5ce35 539 } else {
27b8872c 540 // If we don't have track data, we haven't attempted yet.
b2f5ce35
AKA
541 $strstatus = get_string('notattempted', 'scorm');
542 if (!$download) {
663640f5 543 $row[] = $OUTPUT->pix_icon('notattempted', $strstatus, 'scorm') . '<br>' . $strstatus;
8fb40a45 544 } else {
b2f5ce35 545 $row[] = $strstatus;
8fb40a45 546 }
27b8872c
N
547 // Complete the empty cells.
548 for ($i = 0; $i < count($columns) - $nbmaincolumns; $i++) {
2f673d8b 549 $row[] = $emptyrow;
f007c032 550 }
8fb40a45
AKA
551 }
552 }
553 }
554
555 if (!$download) {
556 $table->add_data($row);
557 } else if ($download == 'Excel' or $download == 'ODS') {
558 $colnum = 0;
559 foreach ($row as $item) {
560 $myxls->write($rownum, $colnum, $item, $format);
561 $colnum++;
562 }
563 $rownum++;
b2f5ce35 564 } else if ($download == 'CSV') {
0253b260 565 $csvexport->add_data($row);
8fb40a45
AKA
566 }
567 }
568 if (!$download) {
569 $table->finish_output();
570 if ($candelete) {
2eca9a23
AA
571 echo \html_writer::start_tag('table', array('id' => 'commands'));
572 echo \html_writer::start_tag('tr').\html_writer::start_tag('td');
0b88a8bc 573 echo $this->generate_delete_selected_button();
2eca9a23 574 echo \html_writer::end_tag('td').\html_writer::end_tag('tr').\html_writer::end_tag('table');
27b8872c 575 // Close form.
2eca9a23
AA
576 echo \html_writer::end_tag('div');
577 echo \html_writer::end_tag('form');
8fb40a45 578 }
2eca9a23 579 echo \html_writer::end_div();
8fb40a45 580 if (!empty($attempts)) {
2eca9a23
AA
581 echo \html_writer::start_tag('table', array('class' => 'boxaligncenter')).\html_writer::start_tag('tr');
582 echo \html_writer::start_tag('td');
583 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 584 array('download' => 'ODS') + $displayoptions),
1d9356d7
SL
585 get_string('downloadods'),
586 'post',
5cac5fa4 587 ['class' => 'mt-1']);
2eca9a23
AA
588 echo \html_writer::end_tag('td');
589 echo \html_writer::start_tag('td');
590 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 591 array('download' => 'Excel') + $displayoptions),
1d9356d7
SL
592 get_string('downloadexcel'),
593 'post',
5cac5fa4 594 ['class' => 'mt-1']);
2eca9a23
AA
595 echo \html_writer::end_tag('td');
596 echo \html_writer::start_tag('td');
597 echo $OUTPUT->single_button(new \moodle_url($PAGE->url,
27b8872c 598 array('download' => 'CSV') + $displayoptions),
1d9356d7
SL
599 get_string('downloadtext'),
600 'post',
5cac5fa4 601 ['class' => 'mt-1']);
2eca9a23
AA
602 echo \html_writer::end_tag('td');
603 echo \html_writer::start_tag('td');
604 echo \html_writer::end_tag('td');
605 echo \html_writer::end_tag('tr').\html_writer::end_tag('table');
8fb40a45
AKA
606 }
607 }
8fb40a45 608 } else {
769a621d 609 if ($candelete && !$download) {
2eca9a23
AA
610 echo \html_writer::end_div();
611 echo \html_writer::end_tag('form');
85e976e5 612 $table->finish_output();
769a621d 613 }
2eca9a23 614 echo \html_writer::end_div();
85e976e5 615 }
27b8872c 616 // Show preferences form irrespective of attempts are there to report or not.
85e976e5 617 if (!$download) {
6f6ea8c3 618 $mform->set_data(compact('pagesize', 'attemptsmode'));
85e976e5 619 $mform->display();
8fb40a45
AKA
620 }
621 if ($download == 'Excel' or $download == 'ODS') {
622 $workbook->close();
623 exit;
624 } else if ($download == 'CSV') {
0253b260 625 $csvexport->download_file();
8fb40a45
AKA
626 exit;
627 }
628 } else {
629 echo $OUTPUT->notification(get_string('noactivity', 'scorm'));
630 }
27b8872c 631 }// Function ends.
8fb40a45 632}