From 031cf251c11ed6ee3017d151a38df61958729636 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Thu, 21 Feb 2019 16:21:58 +0800 Subject: [PATCH] MDL-64878 grades: Rebuild cache on import When the course module cache is out of date during a gradebook re-calculcation it throws throws exceptions because the module cannot be found. This prevents access to gradebook or any type of grading functions until the cache is rebuilt. When the cache still has no module record we log an error and return the course context. --- backup/moodle2/restore_stepslib.php | 3 +++ lib/grade/grade_item.php | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index b3d5322f70d..149f606ce46 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -485,6 +485,9 @@ class restore_gradebook_structure_step extends restore_structure_step { // Freeze gradebook calculations if needed. $this->gradebook_calculation_freeze(); + // Ensure the module cache is current when recalculating grades. + rebuild_course_cache($this->get_courseid(), true); + // Restore marks items as needing update. Update everything now. grade_regrade_final_grades($this->get_courseid()); } diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 60edaf60b92..769f69dfd3c 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -2495,8 +2495,22 @@ class grade_item extends grade_object { */ public function get_context() { if ($this->itemtype == 'mod') { - $cm = get_fast_modinfo($this->courseid)->instances[$this->itemmodule][$this->iteminstance]; - $context = \context_module::instance($cm->id); + $modinfo = get_fast_modinfo($this->courseid); + // Sometimes the course module cache is out of date and needs to be rebuilt. + if (!isset($modinfo->instances[$this->itemmodule][$this->iteminstance])) { + rebuild_course_cache($this->courseid, true); + $modinfo = get_fast_modinfo($this->courseid); + } + // Even with a rebuilt cache the module does not exist. This means the + // database is in an invalid state - we will log an error and return + // the course context but the calling code should be updated. + if (!isset($modinfo->instances[$this->itemmodule][$this->iteminstance])) { + mtrace(get_string('moduleinstancedoesnotexist', 'error')); + $context = \context_course::instance($this->courseid); + } else { + $cm = $modinfo->instances[$this->itemmodule][$this->iteminstance]; + $context = \context_module::instance($cm->id); + } } else { $context = \context_course::instance($this->courseid); }