Merge branch 'MDL-77094_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE

This commit is contained in:
Andrew Nicols 2023-03-07 12:10:18 +08:00
commit 7a5f859f08

View File

@ -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) {