MDL-20636 fix upgrade issue.
[moodle.git] / mod / quiz / report / overview / report.php
CommitLineData
2c3968c4 1<?php
e24ee794
TH
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
2c3968c4 18/**
e24ee794 19 * This file defines the quiz overview report class.
2c3968c4 20 *
e24ee794
TH
21 * @package quiz
22 * @subpackage overview
23 * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
98f38217 25 */
2c3968c4 26
e24ee794 27
a17b297d
TH
28defined('MOODLE_INTERNAL') || die();
29
e24ee794 30require_once($CFG->dirroot.'/mod/quiz/report/attemptsreport.php');
0217f932 31require_once($CFG->dirroot.'/mod/quiz/report/overview/overviewsettings_form.php');
c35f3afc 32require_once($CFG->dirroot.'/mod/quiz/report/overview/overview_table.php');
7bbe08a2 33
7bbe08a2 34
e24ee794
TH
35/**
36 * Quiz report subclass for the overview (grades) report.
37 *
f7970e3c
TH
38 * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
e24ee794
TH
40 */
41class quiz_overview_report extends quiz_attempt_report {
42
c7df5006 43 public function display($quiz, $cm, $course) {
90cd54cb 44 global $CFG, $COURSE, $DB, $OUTPUT;
7bbe08a2 45
98f38217 46 $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
07a7d859 47
c35f3afc 48 $download = optional_param('download', '', PARAM_ALPHA);
aeb15530 49
e24ee794
TH
50 list($currentgroup, $students, $groupstudents, $allowed) =
51 $this->load_relevant_students($cm);
aeb15530 52
0217f932 53 $pageoptions = array();
54 $pageoptions['id'] = $cm->id;
0217f932 55 $pageoptions['mode'] = 'overview';
56
a6855934 57 $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);
334edb71 58 $qmsubselect = quiz_report_qm_filter_select($quiz);
59
e24ee794 60 $mform = new mod_quiz_report_overview_settings($reporturl,
2daffca5
TH
61 array('qmsubselect' => $qmsubselect, 'quiz' => $quiz,
62 'currentgroup' => $currentgroup, 'context' => $this->context));
e24ee794 63
07a2b2f0 64 if ($fromform = $mform->get_data()) {
98f38217 65 $regradeall = false;
66 $regradealldry = false;
67 $regradealldrydo = false;
0217f932 68 $attemptsmode = $fromform->attemptsmode;
07a2b2f0 69 if ($qmsubselect) {
4469159e 70 $qmfilter = $fromform->qmfilter;
71 } else {
72 $qmfilter = 0;
73 }
e24ee794 74 $regradefilter = !empty($fromform->regradefilter);
0217f932 75 set_user_preference('quiz_report_overview_detailedmarks', $fromform->detailedmarks);
76 set_user_preference('quiz_report_pagesize', $fromform->pagesize);
77 $detailedmarks = $fromform->detailedmarks;
78 $pagesize = $fromform->pagesize;
e24ee794 79
0217f932 80 } else {
98f38217 81 $regradeall = optional_param('regradeall', 0, PARAM_BOOL);
82 $regradealldry = optional_param('regradealldry', 0, PARAM_BOOL);
83 $regradealldrydo = optional_param('regradealldrydo', 0, PARAM_BOOL);
7660aa80 84 $attemptsmode = optional_param('attemptsmode', null, PARAM_INT);
07a2b2f0 85 if ($qmsubselect) {
98f38217 86 $qmfilter = optional_param('qmfilter', 0, PARAM_INT);
87 } else {
88 $qmfilter = 0;
89 }
90 $regradefilter = optional_param('regradefilter', 0, PARAM_INT);
0217f932 91 $detailedmarks = get_user_preferences('quiz_report_overview_detailedmarks', 1);
92 $pagesize = get_user_preferences('quiz_report_pagesize', 0);
93 }
e24ee794
TH
94
95 $this->validate_common_options($attemptsmode, $pagesize, $course, $currentgroup);
96 $displayoptions = array();
97 $displayoptions['attemptsmode'] = $attemptsmode;
98 $displayoptions['qmfilter'] = $qmfilter;
99 $displayoptions['regradefilter'] = $regradefilter;
100
101 $mform->set_data($displayoptions + array('detailedmarks' => $detailedmarks, 'pagesize' => $pagesize));
102
103 if (!$this->should_show_grades($quiz)) {
ca359748 104 $detailedmarks = 0;
105 }
e24ee794 106
2fecd85b 107 // We only want to show the checkbox to delete attempts
108 // if the user has permissions and if the report mode is showing attempts.
98f38217 109 $candelete = has_capability('mod/quiz:deleteattempts', $this->context)
f05fedc8 110 && ($attemptsmode != QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO);
2fecd85b 111
f05fedc8 112 if ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
e24ee794
TH
113 // This option is only available to users who can access all groups in
114 // groups mode, so setting allowed to empty (which means all quiz attempts
115 // are accessible, is not a security porblem.
f05fedc8
TH
116 $allowed = array();
117 }
118
e24ee794
TH
119 // Load the required questions.
120 if ($detailedmarks) {
121 $questions = quiz_report_get_significant_questions($quiz);
122 } else {
123 $questions = array();
124 }
125
126 $table = new quiz_report_overview_table($quiz, $this->context, $qmsubselect,
127 $groupstudents, $students, $detailedmarks, $questions, $candelete,
128 $reporturl, $displayoptions);
129 $filename = quiz_report_download_filename(get_string('overviewfilename', 'quiz_overview'),
130 $course->shortname, $quiz->name);
131 $table->is_downloading($download, $filename,
132 $COURSE->shortname . ' ' . format_string($quiz->name, true));
133 if ($table->is_downloading()) {
134 raise_memory_limit(MEMORY_EXTRA);
135 }
136
137 // Process actions.
db77f410
TH
138 if (empty($currentgroup) || $groupstudents) {
139 if (optional_param('delete', 0, PARAM_BOOL) && confirm_sesskey()) {
140 if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
141 require_capability('mod/quiz:deleteattempts', $this->context);
e24ee794 142 $this->delete_selected_attempts($quiz, $cm, $attemptids, $allowed);
db77f410
TH
143 redirect($reporturl->out(false, $displayoptions));
144 }
e24ee794 145
db77f410
TH
146 } else if (optional_param('regrade', 0, PARAM_BOOL) && confirm_sesskey()) {
147 if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
e24ee794
TH
148 require_capability('mod/quiz:regrade', $this->context);
149 $this->regrade_attempts($quiz, false, $groupstudents, $attemptids);
db77f410
TH
150 redirect($reporturl->out(false, $displayoptions));
151 }
152 }
153 }
154
db77f410 155 if ($regradeall && confirm_sesskey()) {
e24ee794
TH
156 require_capability('mod/quiz:regrade', $this->context);
157 $this->regrade_attempts($quiz, false, $groupstudents);
158 redirect($reporturl->out(false, $displayoptions), '', 5);
159
db77f410 160 } else if ($regradealldry && confirm_sesskey()) {
e24ee794
TH
161 require_capability('mod/quiz:regrade', $this->context);
162 $this->regrade_attempts($quiz, true, $groupstudents);
163 redirect($reporturl->out(false, $displayoptions), '', 5);
164
db77f410 165 } else if ($regradealldrydo && confirm_sesskey()) {
e24ee794
TH
166 require_capability('mod/quiz:regrade', $this->context);
167 $this->regrade_attempts_needing_it($quiz, $groupstudents);
b9bc2019 168 redirect($reporturl->out(false, $displayoptions), '', 5);
98f38217 169 }
aeb15530 170
e24ee794
TH
171 // Start output.
172 if (!$table->is_downloading()) {
173 // Only print headers if not asked to download data
174 $this->print_header_and_tabs($cm, $course, $quiz, 'overview');
175 }
176
5ada3c8e 177 if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used
c35f3afc 178 if (!$table->is_downloading()) {
ef770037 179 groups_print_activity_menu($cm, $reporturl->out(true, $displayoptions));
970d0fe0 180 }
2d7617c6 181 }
98f38217 182
e24ee794
TH
183 // Print information on the number of existing attempts
184 if (!$table->is_downloading()) { //do not print notices when downloading
185 if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
186 echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
187 }
188 }
189
3c6185e9
TH
190 $hasquestions = quiz_questions_in_quiz($quiz->questions);
191 if (!$table->is_downloading()) {
192 if (!$hasquestions) {
193 echo quiz_no_questions_message($quiz, $cm, $this->context);
194 } else if (!$students) {
414e7276 195 echo $OUTPUT->notification(get_string('nostudentsyet'));
3c6185e9 196 } else if ($currentgroup && !$groupstudents) {
414e7276
TH
197 echo $OUTPUT->notification(get_string('nostudentsingroup'));
198 }
e24ee794 199
95758992 200 // Print display options
95758992 201 $mform->display();
f6c7f158 202 }
39790bd8 203
3c6185e9
TH
204 $hasstudents = $students && (!$currentgroup || $groupstudents);
205 if ($hasquestions && ($hasstudents || ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL))) {
abe67b24 206 // Construct the SQL
e24ee794 207 $fields = $DB->sql_concat('u.id', "'#'", 'COALESCE(quiza.attempt, 0)') . ' AS uniqueid, ';
55caa1d5 208 if ($qmsubselect) {
209 $fields .=
210 "(CASE " .
211 " WHEN $qmsubselect THEN 1" .
212 " ELSE 0 " .
213 "END) AS gradedattempt, ";
214 }
aeb15530 215
e24ee794
TH
216 list($fields, $from, $where, $params) =
217 $this->base_sql($quiz, $qmsubselect, $qmfilter, $attemptsmode, $allowed);
aeb15530 218
abe67b24 219 $table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where", $params);
98f38217 220
e24ee794
TH
221 // Test to see if there are any regraded attempts to be listed.
222 $fields .= ", COALESCE((SELECT MAX(qqr.regraded) FROM {quiz_overview_regrades} qqr WHERE qqr.questionusageid = quiza.uniqueid), -1) AS regraded";
07a2b2f0 223 if ($regradefilter) {
e24ee794 224 $where .= " AND COALESCE((SELECT MAX(qqr.regraded) FROM {quiz_overview_regrades} qqr WHERE qqr.questionusageid = quiza.uniqueid), -1) <> -1";
98f38217 225 }
abe67b24 226 $table->set_sql($fields, $from, $where, $params);
aeb15530 227
e24ee794
TH
228 if (!$table->is_downloading()) {
229 // Regrade buttons
07a2b2f0 230 if (has_capability('mod/quiz:regrade', $this->context)) {
e24ee794
TH
231 $regradesneeded = $this->count_question_attempts_needing_regrade(
232 $quiz, $groupstudents);
07a2b2f0 233 if ($currentgroup) {
39790bd8 234 $a= new stdClass();
f29e6691 235 $a->groupname = groups_get_group_name($currentgroup);
9101efd3 236 $a->coursestudents = get_string('participants');
e24ee794 237 $a->countregradeneeded = $regradesneeded;
f29e6691 238 $regradealldrydolabel = get_string('regradealldrydogroup', 'quiz_overview', $a);
239 $regradealldrylabel = get_string('regradealldrygroup', 'quiz_overview', $a);
240 $regradealllabel = get_string('regradeallgroup', 'quiz_overview', $a);
241 } else {
e24ee794 242 $regradealldrydolabel = get_string('regradealldrydo', 'quiz_overview', $regradesneeded);
f29e6691 243 $regradealldrylabel = get_string('regradealldry', 'quiz_overview');
244 $regradealllabel = get_string('regradeall', 'quiz_overview');
245 }
e24ee794 246 $displayurl = new moodle_url($reporturl, $displayoptions + array('sesskey' => sesskey()));
f29e6691 247 echo '<div class="mdl-align">';
eb788065 248 echo '<form action="'.$displayurl->out_omit_querystring().'">';
f29e6691 249 echo '<div>';
6ea66ff3 250 echo html_writer::input_hidden_params($displayurl);
f29e6691 251 echo '<input type="submit" name="regradeall" value="'.$regradealllabel.'"/>';
252 echo '<input type="submit" name="regradealldry" value="'.$regradealldrylabel.'"/>';
e24ee794 253 if ($regradesneeded) {
f29e6691 254 echo '<input type="submit" name="regradealldrydo" value="'.$regradealldrydolabel.'"/>';
255 }
256 echo '</div>';
257 echo '</form>';
258 echo '</div>';
259 }
260 // Print information on the grading method
261 if ($strattempthighlight = quiz_report_highlighting_grading_method($quiz, $qmsubselect, $qmfilter)) {
262 echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
263 }
264 }
aeb15530 265
e24ee794
TH
266 // Define table columns
267 $columns = array();
268 $headers = array();
aeb15530 269
e24ee794
TH
270 if (!$table->is_downloading() && $candelete) {
271 $columns[] = 'checkbox';
272 $headers[] = NULL;
abe67b24 273 }
aeb15530 274
e24ee794 275 $this->add_user_columns($table, $columns, $headers);
aeb15530 276
e24ee794 277 $this->add_time_columns($columns, $headers);
aeb15530 278
abe67b24 279 if ($detailedmarks) {
e24ee794 280 foreach ($questions as $slot => $question) {
abe67b24 281 // Ignore questions of zero length
e24ee794
TH
282 $columns[] = 'qsgrade' . $slot;
283 $header = get_string('qbrief', 'quiz', $question->number);
98f38217 284 if (!$table->is_downloading()) {
e24ee794 285 $header .= '<br />';
98f38217 286 } else {
e24ee794 287 $header .= ' ';
98f38217 288 }
e24ee794 289 $header .= '/' . quiz_rescale_grade($question->maxmark, $quiz, 'question');
98f38217 290 $headers[] = $header;
eacb462e 291 }
abe67b24 292 }
e24ee794
TH
293
294 if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) &&
295 $this->has_regraded_questions($from, $where, $params)) {
98f38217 296 $columns[] = 'regraded';
297 $headers[] = get_string('regrade', 'quiz_overview');
298 }
aeb15530 299
e24ee794 300 $this->add_grade_columns($quiz, $columns, $headers);
aeb15530 301
e24ee794
TH
302 $this->set_up_table_columns($table, $columns, $headers, $reporturl, $displayoptions, false);
303 $table->set_attribute('class', 'generaltable generalbox grades');
aeb15530 304
abe67b24 305 $table->out($pagesize, true);
7bbe08a2 306 }
e24ee794
TH
307
308 if (!$table->is_downloading() && $this->should_show_grades($quiz)) {
07a2b2f0 309 if ($currentgroup && $groupstudents) {
f29e6691 310 list($usql, $params) = $DB->get_in_or_equal($groupstudents);
311 $params[] = $quiz->id;
739b0711 312 if ($DB->record_exists_select('quiz_grades', "userid $usql AND quiz = ?", $params)) {
f29e6691 313 $imageurl = "{$CFG->wwwroot}/mod/quiz/report/overview/overviewgraph.php?id={$quiz->id}&amp;groupid=$currentgroup";
314 $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', groups_get_group_name($currentgroup));
90cd54cb 315 echo $OUTPUT->heading($graphname);
367a75fa 316 echo '<div class="graph"><img src="'.$imageurl.'" alt="'.$graphname.'" /></div>';
f29e6691 317 }
318 }
e24ee794 319
07a2b2f0 320 if ($DB->record_exists('quiz_grades', array('quiz'=> $quiz->id))) {
f29e6691 321 $graphname = get_string('overviewreportgraph', 'quiz_overview');
c35f3afc 322 $imageurl = $CFG->wwwroot.'/mod/quiz/report/overview/overviewgraph.php?id='.$quiz->id;
90cd54cb 323 echo $OUTPUT->heading($graphname);
367a75fa 324 echo '<div class="graph"><img src="'.$imageurl.'" alt="'.$graphname.'" /></div>';
aad5b0fc 325 }
78517b5a 326 }
7bbe08a2 327 return true;
328 }
e24ee794 329
98f38217 330 /**
e24ee794
TH
331 * Regrade a particular quiz attempt. Either for real ($dryrun = false), or
332 * as a pretend regrade to see which fractions would change. The outcome is
333 * stored in the quiz_overview_regrades table.
334 *
335 * Note, $attempt is not upgraded in the database. The caller needs to do that.
336 * However, $attempt->sumgrades is updated, if this is not a dry run.
337 *
338 * @param object $attempt the quiz attempt to regrade.
f7970e3c 339 * @param bool $dryrun if true, do a pretend regrade, otherwise do it for real.
e24ee794
TH
340 * @param array $slots if null, regrade all questions, otherwise, just regrade
341 * the quetsions with those slots.
98f38217 342 */
e24ee794
TH
343 protected function regrade_attempt($attempt, $dryrun = false, $slots = null) {
344 global $DB;
98f38217 345
e24ee794 346 $transaction = $DB->start_delegated_transaction();
98f38217 347
e24ee794
TH
348 $quba = question_engine::load_questions_usage_by_activity($attempt->uniqueid);
349
350 if (is_null($slots)) {
351 $slots = $quba->get_slots();
98f38217 352 }
e24ee794
TH
353
354 $finished = $attempt->timefinish > 0;
355 foreach ($slots as $slot) {
0ff4bd08 356 $qqr = new stdClass();
e24ee794
TH
357 $qqr->oldfraction = $quba->get_question_fraction($slot);
358
359 $quba->regrade_question($slot, $finished);
360
361 $qqr->newfraction = $quba->get_question_fraction($slot);
362
363 if (abs($qqr->oldfraction - $qqr->newfraction) > 1e-7) {
364 $qqr->questionusageid = $quba->get_id();
365 $qqr->slot = $slot;
366 $qqr->regraded = empty($dryrun);
367 $qqr->timemodified = time();
368 $DB->insert_record('quiz_overview_regrades', $qqr, false);
98f38217 369 }
98f38217 370 }
371
e24ee794
TH
372 if (!$dryrun) {
373 question_engine::save_questions_usage_by_activity($quba);
98f38217 374 }
e24ee794
TH
375
376 $transaction->allow_commit();
98f38217 377 }
e24ee794
TH
378
379 /**
380 * Regrade attempts for this quiz, exactly which attempts are regraded is
381 * controlled by the parameters.
382 * @param object $quiz the quiz settings.
f7970e3c 383 * @param bool $dryrun if true, do a pretend regrade, otherwise do it for real.
e24ee794
TH
384 * @param array $groupstudents blank for all attempts, otherwise regrade attempts
385 * for these users.
386 * @param array $attemptids blank for all attempts, otherwise only regrade
387 * attempts whose id is in this list.
388 */
389 protected function regrade_attempts($quiz, $dryrun = false,
390 $groupstudents = array(), $attemptids = array()) {
98f38217 391 global $DB;
e24ee794
TH
392
393 $where = "quiz = ? AND preview = 0";
394 $params = array($quiz->id);
395
07a2b2f0 396 if ($groupstudents) {
e24ee794
TH
397 list($usql, $uparams) = $DB->get_in_or_equal($groupstudents);
398 $where .= " AND userid $usql";
399 $params = array_merge($params, $uparams);
98f38217 400 }
e24ee794
TH
401
402 if ($attemptids) {
403 list($asql, $aparams) = $DB->get_in_or_equal($attemptids);
404 $where .= " AND id $asql";
405 $params = array_merge($params, $aparams);
98f38217 406 }
98f38217 407
e24ee794
TH
408 $attempts = $DB->get_records_select('quiz_attempts', $where, $params);
409 if (!$attempts) {
410 return;
411 }
98f38217 412
e24ee794 413 $this->clear_regrade_table($quiz, $groupstudents);
98f38217 414
98f38217 415 foreach ($attempts as $attempt) {
e24ee794
TH
416 set_time_limit(30);
417 $this->regrade_attempt($attempt, $dryrun);
418 }
419
420 if (!$dryrun) {
421 $this->update_overall_grades($quiz);
98f38217 422 }
98f38217 423 }
424
e24ee794
TH
425 /**
426 * Regrade those questions in those attempts that are marked as needing regrading
427 * in the quiz_overview_regrades table.
428 * @param object $quiz the quiz settings.
429 * @param array $groupstudents blank for all attempts, otherwise regrade attempts
430 * for these users.
431 */
432 protected function regrade_attempts_needing_it($quiz, $groupstudents) {
98f38217 433 global $DB;
e24ee794
TH
434
435 $where = "quiza.quiz = ? AND quiza.preview = 0 AND qqr.regraded = 0";
436 $params = array($quiz->id);
437
98f38217 438 // Fetch all attempts that need regrading
07a2b2f0 439 if ($groupstudents) {
e24ee794
TH
440 list($usql, $uparams) = $DB->get_in_or_equal($groupstudents);
441 $where .= " AND quiza.userid $usql";
442 $params += $uparams;
98f38217 443 }
23277af8 444
e24ee794
TH
445 $toregrade = $DB->get_records_sql("
446 SELECT quiza.uniqueid, qqr.slot
447 FROM {quiz_attempts} quiza
448 JOIN {quiz_overview_regrades} qqr ON qqr.questionusageid = quiza.uniqueid
449 WHERE $where", $params);
450
451 if (!$toregrade) {
452 return;
98f38217 453 }
454
e24ee794
TH
455 $attemptquestions = array();
456 foreach ($toregrade as $row) {
457 $attemptquestions[$row->uniqueid][] = $row->slot;
98f38217 458 }
e24ee794
TH
459 $attempts = $DB->get_records_list('quiz_attempts', 'uniqueid', array_keys($attemptquestions));
460
461 $this->clear_regrade_table($quiz, $groupstudents);
462
463 foreach ($attempts as $attempt) {
464 set_time_limit(30);
465 $this->regrade_attempt($attempt, false, $attemptquestions[$attempt->uniqueid]);
98f38217 466 }
e24ee794
TH
467
468 $this->update_overall_grades($quiz);
98f38217 469 }
f05fedc8 470
e24ee794
TH
471 /**
472 * Count the number of attempts in need of a regrade.
473 * @param object $quiz the quiz settings.
474 * @param array $groupstudents user ids. If this is given, only data relating
475 * to these users is cleared.
476 */
477 protected function count_question_attempts_needing_regrade($quiz, $groupstudents) {
478 global $DB;
479
480 $usertest = '';
481 $params = array();
482 if ($groupstudents) {
483 list($usql, $params) = get_in_or_equal($groupstudents);
484 $usertest = "quiza.userid $usql AND ";
98f38217 485 }
e24ee794
TH
486
487 $params[] = $quiz->id;
488 $sql = "SELECT COUNT(DISTINCT quiza.id)
489 FROM {quiz_attempts} quiza
490 JOIN {quiz_overview_regrades} qqr ON quiza.uniqueid = qqr.questionusageid
491 WHERE
492 $usertest
493 quiza.quiz = ? AND
494 quiza.preview = 0 AND
495 qqr.regraded = 0";
496 return $DB->count_records_sql($sql, $params);
497 }
498
499 /**
500 * Are there any pending regrades in the table we are going to show?
501 * @param string $from tables used by the main query.
502 * @param string $where where clause used by the main query.
503 * @param array $params required by the SQL.
504 * @return bool whether there are pending regrades.
505 */
506 protected function has_regraded_questions($from, $where, $params) {
507 global $DB;
508 $qubaids = new qubaid_join($from, 'uniqueid', $where, $params);
509 return $DB->record_exists_select('quiz_overview_regrades',
510 'questionusageid ' . $qubaids->usage_id_in(), $qubaids->usage_id_in_params());
98f38217 511 }
f05fedc8 512
e24ee794
TH
513 /**
514 * Remove all information about pending/complete regrades from the database.
515 * @param object $quiz the quiz settings.
516 * @param array $groupstudents user ids. If this is given, only data relating
517 * to these users is cleared.
518 */
519 protected function clear_regrade_table($quiz, $groupstudents) {
98f38217 520 global $DB;
e24ee794
TH
521
522 // Fetch all attempts that need regrading
523 $where = '';
524 $params = array();
07a2b2f0 525 if ($groupstudents) {
98f38217 526 list($usql, $params) = $DB->get_in_or_equal($groupstudents);
e24ee794 527 $where = "userid $usql AND ";
98f38217 528 }
aeb15530 529
98f38217 530 $params[] = $quiz->id;
e24ee794
TH
531 $DB->delete_records_select('quiz_overview_regrades',
532 "questionusageid IN (
533 SELECT uniqueid
534 FROM {quiz_attempts}
535 WHERE $where quiz = ?
536 )", $params);
537 }
98f38217 538
e24ee794
TH
539 /**
540 * Update the final grades for all attempts. This method is used following
541 * a regrade.
542 * @param object $quiz the quiz settings.
543 * @param array $userids only update scores for these userids.
544 * @param array $attemptids attemptids only update scores for these attempt ids.
545 */
546 protected function update_overall_grades($quiz) {
547 quiz_update_all_attempt_sumgrades($quiz);
548 quiz_update_all_final_grades($quiz);
549 quiz_update_grades($quiz);
98f38217 550 }
7bbe08a2 551}