diff --git a/mod/quiz/report/statistics/classes/task/recalculate.php b/mod/quiz/report/statistics/classes/task/recalculate.php index 4d59537f0e6..a8d9df68b86 100644 --- a/mod/quiz/report/statistics/classes/task/recalculate.php +++ b/mod/quiz/report/statistics/classes/task/recalculate.php @@ -16,6 +16,7 @@ namespace quiz_statistics\task; +use core\dml\sql_join; use quiz_attempt; use quiz; use quiz_statistics_report; @@ -50,59 +51,61 @@ class recalculate extends \core\task\scheduled_task { // TODO: MDL-75197, add quizid in quiz_statistics so that it is simpler to find quizzes for stats calculation. // Only calculate stats for quizzes which have recently finished attempt. - $sql = " - SELECT q.id AS quizid, - q.name AS quizname, - c.id AS courseid, - c.shortname AS courseshortname, - MAX(qa.timefinish) AS mostrecentattempttime, - COUNT(1) AS numberofattempts - FROM {quiz_attempts} qa - JOIN {quiz} q ON q.id = qa.quiz - JOIN {course} c ON c.id = q.course - WHERE qa.preview = 0 - AND qa.state = :quizstatefinished - GROUP BY q.id, q.name, c.id, c.shortname - "; + $latestattempts = $DB->get_records_sql(" + SELECT q.id AS quizid, + q.name AS quizname, + q.grademethod AS quizgrademethod, + c.id AS courseid, + c.shortname AS courseshortname, + MAX(quiza.timefinish) AS mostrecentattempttime, + COUNT(1) AS numberofattempts - $params = [ - "quizstatefinished" => quiz_attempt::FINISHED, - ]; + FROM {quiz_attempts} quiza + JOIN {quiz} q ON q.id = quiza.quiz + JOIN {course} c ON c.id = q.course - $latestattempts = $DB->get_records_sql($sql, $params); + WHERE quiza.preview = 0 + AND quiza.state = :quizstatefinished + + GROUP BY q.id, q.name, q.grademethod, c.id, c.shortname + ORDER BY MAX(quiza.timefinish) DESC + ", ["quizstatefinished" => quiz_attempt::FINISHED]); $anyexception = null; - foreach ($latestattempts as $attempt) { + foreach ($latestattempts as $latestattempt) { if (time() >= $stoptime) { mtrace("This task has been running for more than " . format_time(self::TIME_LIMIT) . " so stopping this execution."); break; } - mtrace(" Examining quiz '$attempt->quizname' ($attempt->quizid) in course " . - "$attempt->courseshortname ($attempt->courseid) with most recent attempt at " . - userdate($attempt->mostrecentattempttime, $dateformat) . "."); - $quizobj = quiz::create($attempt->quizid); - $quiz = $quizobj->get_quiz(); - // Hash code for question stats option in question bank. - $qubaids = quiz_statistics_qubaids_condition($quiz->id, new \core\dml\sql_join(), $quiz->grademethod); - // Check if there is any existing question stats, and it has been calculated after latest quiz attempt. + $qubaids = quiz_statistics_qubaids_condition($latestattempt->quizid, + new sql_join(), $latestattempt->quizgrademethod); $lateststatstime = $DB->get_field('quiz_statistics', 'COALESCE(MAX(timemodified), 0)', ['hashcode' => $qubaids->get_hash_code()]); - if ($lateststatstime >= $attempt->mostrecentattempttime) { - mtrace(" Statistics already calculated at " . userdate($lateststatstime, $dateformat) . - " so nothing to do for this quiz."); + $quizinfo = "'$latestattempt->quizname' ($latestattempt->quizid) in course " . + "$latestattempt->courseshortname ($latestattempt->courseid) has most recent attempt finished at " . + userdate($latestattempt->mostrecentattempttime, $dateformat); + if ($lateststatstime) { + $quizinfo .= " and statistics from " . userdate($lateststatstime, $dateformat); + } + + if ($lateststatstime >= $latestattempt->mostrecentattempttime) { + mtrace(" " . $quizinfo . " so nothing to do."); continue; } - mtrace(" Calculating statistics for $attempt->numberofattempts attempts, starting at " . + // OK, so we need to calculate for this quiz. + mtrace(" " . $quizinfo . " so re-calculating statistics for $latestattempt->numberofattempts attempts, start time " . userdate(time(), $dateformat) . " ..."); + try { + $quizobj = quiz::create($latestattempt->quizid); $report = new quiz_statistics_report(); $report->clear_cached_data($qubaids); - $report->calculate_questions_stats_for_question_bank($quiz->id); + $report->calculate_questions_stats_for_question_bank($quizobj->get_quizid()); mtrace(" Calculations completed at " . userdate(time(), $dateformat) . "."); } catch (\Throwable $e) {