MDL-59931 mod_quiz: Fixing incorrect pagination count.
[moodle.git] / mod / quiz / report / responses / report.php
CommitLineData
aeb15530 1<?php
9b40c540
TH
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
7f29a7db 17/**
9b40c540 18 * This file defines the quiz responses report class.
7f29a7db 19 *
8d76124c
TH
20 * @package quiz_responses
21 * @copyright 2006 Jean-Michel Vedrine
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
9b40c540
TH
23 */
24
7f29a7db 25
a17b297d
TH
26defined('MOODLE_INTERNAL') || die();
27
6b4e2d76 28require_once($CFG->dirroot . '/mod/quiz/report/attemptsreport.php');
dcd65f1b
TH
29require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_options.php');
30require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_form.php');
99caa248
JP
31require_once($CFG->dirroot . '/mod/quiz/report/responses/last_responses_table.php');
32require_once($CFG->dirroot . '/mod/quiz/report/responses/first_or_all_responses_table.php');
7f29a7db 33
7f29a7db 34
9b40c540
TH
35/**
36 * Quiz report subclass for the responses report.
37 *
38 * This report lists some combination of
39 * * what question each student saw (this makes sense if random questions were used).
40 * * the response they gave,
41 * * and what the right answer is.
42 *
43 * Like the overview report, there are options for showing students with/without
44 * attempts, and for deleting selected attempts.
45 *
8d76124c
TH
46 * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
47 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
9b40c540 48 */
ac4d9157 49class quiz_responses_report extends quiz_attempts_report {
9b40c540 50
c7df5006 51 public function display($quiz, $cm, $course) {
10c4fce5
JB
52 global $OUTPUT, $DB;
53
54 list($currentgroup, $studentsjoins, $groupstudentsjoins, $allowedjoins) = $this->init(
55 'responses', 'quiz_responses_settings_form', $quiz, $cm, $course);
7f29a7db 56
e97d60ad 57 $options = new quiz_responses_options('responses', $quiz, $cm, $course);
7f29a7db 58
303aa3b8 59 if ($fromform = $this->form->get_data()) {
dcd65f1b 60 $options->process_settings_from_form($fromform);
9b40c540 61
7f29a7db 62 } else {
dcd65f1b 63 $options->process_settings_from_params();
7f29a7db 64 }
9b40c540 65
dcd65f1b 66 $this->form->set_data($options->get_initial_form_data());
9b40c540 67
9b40c540
TH
68 // Load the required questions.
69 $questions = quiz_report_get_significant_questions($quiz);
70
4747c788 71 // Prepare for downloading, if applicable.
0eafc988 72 $courseshortname = format_string($course->shortname, true,
26aded55 73 array('context' => context_course::instance($course->id)));
99caa248
JP
74 if ($options->whichtries === question_attempt::LAST_TRY) {
75 $tableclassname = 'quiz_last_responses_table';
76 } else {
77 $tableclassname = 'quiz_first_or_all_responses_table';
78 }
79 $table = new $tableclassname($quiz, $this->context, $this->qmsubselect,
10c4fce5 80 $options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url());
9b40c540 81 $filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'),
8ebbb06a 82 $courseshortname, $quiz->name);
9e67e357 83 $table->is_downloading($options->download, $filename,
26aded55 84 $courseshortname . ' ' . format_string($quiz->name, true));
9b40c540
TH
85 if ($table->is_downloading()) {
86 raise_memory_limit(MEMORY_EXTRA);
87 }
7f29a7db 88
10c4fce5
JB
89 $this->hasgroupstudents = false;
90 if (!empty($groupstudentsjoins->joins)) {
91 $sql = "SELECT DISTINCT u.id
92 FROM {user} u
93 $groupstudentsjoins->joins
94 WHERE $groupstudentsjoins->wheres";
95 $this->hasgroupstudents = $DB->record_exists_sql($sql, $groupstudentsjoins->params);
96 }
97 $hasstudents = false;
98 if (!empty($studentsjoins->joins)) {
99 $sql = "SELECT DISTINCT u.id
100 FROM {user} u
101 $studentsjoins->joins
102 WHERE $studentsjoins->wheres";
103 $hasstudents = $DB->record_exists_sql($sql, $studentsjoins->params);
104 }
105 if ($options->attempts == self::ALL_WITH) {
106 // This option is only available to users who can access all groups in
107 // groups mode, so setting allowed to empty (which means all quiz attempts
108 // are accessible, is not a security problem.
6c45e525 109 $allowedjoins = new \core\dml\sql_join();
10c4fce5
JB
110 }
111
112 $this->process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $options->get_url());
4747c788
TH
113
114 // Start output.
7f29a7db 115 if (!$table->is_downloading()) {
768a7588 116 // Only print headers if not asked to download data.
361cf27d 117 $this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
7f29a7db 118 }
119
768a7588
TH
120 if ($groupmode = groups_get_activity_groupmode($cm)) {
121 // Groups are being used, so output the group selector if we are not downloading.
7f29a7db 122 if (!$table->is_downloading()) {
e97d60ad 123 groups_print_activity_menu($cm, $options->get_url());
7f29a7db 124 }
125 }
f6c7f158 126
768a7588
TH
127 // Print information on the number of existing attempts.
128 if (!$table->is_downloading()) {
129 // Do not print notices when downloading.
9b40c540
TH
130 if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
131 echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
132 }
133 }
3c6185e9 134
ccba5b88 135 $hasquestions = quiz_has_questions($quiz->id);
3c6185e9
TH
136 if (!$table->is_downloading()) {
137 if (!$hasquestions) {
138 echo quiz_no_questions_message($quiz, $cm, $this->context);
10c4fce5 139 } else if (!$hasstudents) {
414e7276 140 echo $OUTPUT->notification(get_string('nostudentsyet'));
10c4fce5 141 } else if ($currentgroup && !$this->hasgroupstudents) {
414e7276
TH
142 echo $OUTPUT->notification(get_string('nostudentsingroup'));
143 }
3c6185e9 144
768a7588 145 // Print the display options.
303aa3b8 146 $this->form->display();
7f29a7db 147 }
148
10c4fce5 149 $hasstudents = $hasstudents && (!$currentgroup || $this->hasgroupstudents);
863872e3 150 if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {
aeb15530 151
10c4fce5 152 list($fields, $from, $where, $params) = $table->base_sql($allowedjoins);
aeb15530 153
43f122d3 154 $table->set_count_sql("SELECT COUNT(1) FROM (SELECT $fields FROM $from WHERE $where) temp", $params);
aeb15530 155
7f29a7db 156 $table->set_sql($fields, $from, $where, $params);
aeb15530 157
c0270961
TH
158 if (!$table->is_downloading()) {
159 // Print information on the grading method.
160 if ($strattempthighlight = quiz_report_highlighting_grading_method(
161 $quiz, $this->qmsubselect, $options->onlygraded)) {
162 echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
163 }
164 }
165
768a7588 166 // Define table columns.
7f29a7db 167 $columns = array();
168 $headers = array();
aeb15530 169
9e67e357 170 if (!$table->is_downloading() && $options->checkboxcolumn) {
9b40c540 171 $columns[] = 'checkbox';
55ca80ed 172 $headers[] = null;
7f29a7db 173 }
aeb15530 174
9b40c540 175 $this->add_user_columns($table, $columns, $headers);
c547514a 176 $this->add_state_column($columns, $headers);
aeb15530 177
24f17d75 178 if ($table->is_downloading()) {
9b40c540 179 $this->add_time_columns($columns, $headers);
d71226a4 180 }
6559096f 181
9e67e357 182 $this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers);
aeb15530 183
d71226a4 184 foreach ($questions as $id => $question) {
dcd65f1b 185 if ($options->showqtext) {
9b40c540
TH
186 $columns[] = 'question' . $id;
187 $headers[] = get_string('questionx', 'question', $question->number);
188 }
dcd65f1b 189 if ($options->showresponses) {
9b40c540
TH
190 $columns[] = 'response' . $id;
191 $headers[] = get_string('responsex', 'quiz_responses', $question->number);
192 }
dcd65f1b 193 if ($options->showright) {
9b40c540
TH
194 $columns[] = 'right' . $id;
195 $headers[] = get_string('rightanswerx', 'quiz_responses', $question->number);
196 }
d71226a4 197 }
aeb15530 198
d71226a4 199 $table->define_columns($columns);
200 $table->define_headers($headers);
9b40c540 201 $table->sortable(true, 'uniqueid');
aeb15530 202
768a7588 203 // Set up the table.
e97d60ad 204 $table->define_baseurl($options->get_url());
aeb15530 205
9b40c540 206 $this->configure_user_columns($table);
aeb15530 207
d71226a4 208 $table->no_sorting('feedbacktext');
d71226a4 209 $table->column_class('sumgrades', 'bold');
aeb15530 210
99caa248 211 $table->set_attribute('id', 'responses');
aeb15530 212
9b40c540
TH
213 $table->collapsible(true);
214
dcd65f1b 215 $table->out($options->pagesize, true);
d71226a4 216 }
7f29a7db 217 return true;
218 }
7f29a7db 219}