diff --git a/course/format/classes/base.php b/course/format/classes/base.php
index cc83f570698..c75c95946e2 100644
--- a/course/format/classes/base.php
+++ b/course/format/classes/base.php
@@ -1393,7 +1393,7 @@ abstract class base {
}
if (!is_object($section)) {
$section = $DB->get_record('course_sections', array('course' => $this->get_courseid(), 'section' => $section),
- 'id,course,section,sequence,summary');
+ 'id,section,sequence,summary');
}
if (!$section || !$section->section) {
// Not possible to delete 0-section.
diff --git a/course/lib.php b/course/lib.php
index dee093bbf48..e76d9145cc8 100644
--- a/course/lib.php
+++ b/course/lib.php
@@ -386,204 +386,6 @@ function course_integrity_check($courseid, $rawmods = null, $sections = null, $f
return $messages;
}
-/**
- * For a given course, returns an array of course activity objects
- * Each item in the array contains he following properties:
- *
- * @param int $courseid course id
- * @param bool $usecache get activities from cache if modinfo exists when $usecache is true
- * @return array list of activities
- */
-function get_array_of_activities(int $courseid, bool $usecache = false): array {
-// cm - course module id
-// mod - name of the module (eg forum)
-// section - the number of the section (eg week or topic)
-// name - the name of the instance
-// visible - is the instance visible or not
-// groupingid - grouping id
-// extra - contains extra string to include in any link
- global $CFG, $DB;
-
- $course = $DB->get_record('course', array('id'=>$courseid));
-
- if (empty($course)) {
- throw new moodle_exception('courseidnotfound');
- }
-
- $rawmods = get_course_mods($courseid);
- if (empty($rawmods)) {
- return [];
- }
-
- $mods = [];
- if ($usecache) {
- // Get existing cache.
- $cachecoursemodinfo = cache::make('core', 'coursemodinfo');
- $coursemodinfo = $cachecoursemodinfo->get($courseid);
- if ($coursemodinfo !== false) {
- $mods = $coursemodinfo->modinfo;
- }
- }
-
- $courseformat = course_get_format($course);
-
- if ($sections = $DB->get_records('course_sections', array('course' => $courseid),
- 'section ASC', 'id,section,sequence,visible')) {
- // First check and correct obvious mismatches between course_sections.sequence and course_modules.section.
- if ($errormessages = course_integrity_check($courseid, $rawmods, $sections)) {
- debugging(join('
', $errormessages));
- $rawmods = get_course_mods($courseid);
- $sections = $DB->get_records('course_sections', array('course' => $courseid),
- 'section ASC', 'id,section,sequence,visible');
- }
- // Build array of activities.
- foreach ($sections as $section) {
- if (!empty($section->sequence)) {
- $cmids = explode(",", $section->sequence);
- $numberofmods = count($cmids);
- for ($order = 0; $order < $numberofmods; $order++) {
- $cmid = $cmids[$order];
- // Activity does not exist in the database.
- $notexistindb = empty($rawmods[$cmid]);
- $activitycached = isset($mods[$cmid]);
- if ($activitycached || $notexistindb) {
- continue;
- }
- $modposition = ($order === 0) ? 0 : array_search($cmids[$order - 1], array_keys($mods)) + 1;
- $mods = array_slice($mods, 0, $modposition, true)
- + [$cmid => new stdClass()]
- + array_slice($mods, $modposition, null, true);
-
- // Adjust visibleoncoursepage, value in DB may not respect format availability.
- $rawmods[$cmid]->visibleoncoursepage = (!$rawmods[$cmid]->visible
- || $rawmods[$cmid]->visibleoncoursepage
- || empty($CFG->allowstealth)
- || !$courseformat->allow_stealth_module_visibility($rawmods[$cmid], $section)) ? 1 : 0;
-
- $mods[$cmid]->id = $rawmods[$cmid]->instance;
- $mods[$cmid]->cm = $rawmods[$cmid]->id;
- $mods[$cmid]->mod = $rawmods[$cmid]->modname;
-
- // Oh dear. Inconsistent names left here for backward compatibility.
- $mods[$cmid]->section = $section->section;
- $mods[$cmid]->sectionid = $rawmods[$cmid]->section;
-
- $mods[$cmid]->module = $rawmods[$cmid]->module;
- $mods[$cmid]->added = $rawmods[$cmid]->added;
- $mods[$cmid]->score = $rawmods[$cmid]->score;
- $mods[$cmid]->idnumber = $rawmods[$cmid]->idnumber;
- $mods[$cmid]->visible = $rawmods[$cmid]->visible;
- $mods[$cmid]->visibleoncoursepage = $rawmods[$cmid]->visibleoncoursepage;
- $mods[$cmid]->visibleold = $rawmods[$cmid]->visibleold;
- $mods[$cmid]->groupmode = $rawmods[$cmid]->groupmode;
- $mods[$cmid]->groupingid = $rawmods[$cmid]->groupingid;
- $mods[$cmid]->indent = $rawmods[$cmid]->indent;
- $mods[$cmid]->completion = $rawmods[$cmid]->completion;
- $mods[$cmid]->extra = "";
- $mods[$cmid]->completiongradeitemnumber =
- $rawmods[$cmid]->completiongradeitemnumber;
- $mods[$cmid]->completionpassgrade = $rawmods[$cmid]->completionpassgrade;
- $mods[$cmid]->completionview = $rawmods[$cmid]->completionview;
- $mods[$cmid]->completionexpected = $rawmods[$cmid]->completionexpected;
- $mods[$cmid]->showdescription = $rawmods[$cmid]->showdescription;
- $mods[$cmid]->availability = $rawmods[$cmid]->availability;
- $mods[$cmid]->deletioninprogress = $rawmods[$cmid]->deletioninprogress;
- $mods[$cmid]->downloadcontent = $rawmods[$cmid]->downloadcontent;
-
- $modname = $mods[$cmid]->mod;
- $functionname = $modname . "_get_coursemodule_info";
-
- if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
- continue;
- }
-
- include_once("$CFG->dirroot/mod/$modname/lib.php");
-
- if ($hasfunction = function_exists($functionname)) {
- if ($info = $functionname($rawmods[$cmid])) {
- if (!empty($info->icon)) {
- $mods[$cmid]->icon = $info->icon;
- }
- if (!empty($info->iconcomponent)) {
- $mods[$cmid]->iconcomponent = $info->iconcomponent;
- }
- if (!empty($info->name)) {
- $mods[$cmid]->name = $info->name;
- }
- if ($info instanceof cached_cm_info) {
- // When using cached_cm_info you can include three new fields.
- // That aren't available for legacy code.
- if (!empty($info->content)) {
- $mods[$cmid]->content = $info->content;
- }
- if (!empty($info->extraclasses)) {
- $mods[$cmid]->extraclasses = $info->extraclasses;
- }
- if (!empty($info->iconurl)) {
- // Convert URL to string as it's easier to store.
- // Also serialized object contains \0 byte,
- // ... and can not be written to Postgres DB.
- $url = new moodle_url($info->iconurl);
- $mods[$cmid]->iconurl = $url->out(false);
- }
- if (!empty($info->onclick)) {
- $mods[$cmid]->onclick = $info->onclick;
- }
- if (!empty($info->customdata)) {
- $mods[$cmid]->customdata = $info->customdata;
- }
- } else {
- // When using a stdclass, the (horrible) deprecated ->extra field,
- // ... that is available for BC.
- if (!empty($info->extra)) {
- $mods[$cmid]->extra = $info->extra;
- }
- }
- }
- }
- // When there is no modname_get_coursemodule_info function,
- // ... but showdescriptions is enabled, then we use the 'intro',
- // ... and 'introformat' fields in the module table.
- if (!$hasfunction && $rawmods[$cmid]->showdescription) {
- if ($modvalues = $DB->get_record($rawmods[$cmid]->modname,
- ['id' => $rawmods[$cmid]->instance], 'name, intro, introformat')) {
- // Set content from intro and introformat. Filters are disabled.
- // Because we filter it with format_text at display time.
- $mods[$cmid]->content = format_module_intro($rawmods[$cmid]->modname,
- $modvalues, $rawmods[$cmid]->id, false);
-
- // To save making another query just below, put name in here.
- $mods[$cmid]->name = $modvalues->name;
- }
- }
- if (!isset($mods[$cmid]->name)) {
- $mods[$cmid]->name = $DB->get_field($rawmods[$cmid]->modname, "name",
- ["id" => $rawmods[$cmid]->instance]);
- }
-
- // Minimise the database size by unsetting default options when they are 'empty'.
- // This list corresponds to code in the cm_info constructor.
- foreach (['idnumber', 'groupmode', 'groupingid',
- 'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content',
- 'icon', 'iconcomponent', 'customdata', 'availability', 'completionview',
- 'completionexpected', 'score', 'showdescription', 'deletioninprogress'] as $property) {
- if (property_exists($mods[$cmid], $property) &&
- empty($mods[$cmid]->{$property})) {
- unset($mods[$cmid]->{$property});
- }
- }
- // Special case: this value is usually set to null, but may be 0.
- if (property_exists($mods[$cmid], 'completiongradeitemnumber') &&
- is_null($mods[$cmid]->completiongradeitemnumber)) {
- unset($mods[$cmid]->completiongradeitemnumber);
- }
- }
- }
- }
- }
- return $mods;
-}
-
/**
* Returns an array where the key is the module name (component name without 'mod_')
* and the value is a lang_string object with a human-readable string.
diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php
index c75d8551880..f9c63c5aa02 100644
--- a/course/tests/courselib_test.php
+++ b/course/tests/courselib_test.php
@@ -1063,7 +1063,7 @@ class courselib_test extends advanced_testcase {
// Build course cache.
get_fast_modinfo($course->id);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
@@ -1077,7 +1077,7 @@ class courselib_test extends advanced_testcase {
// Move section.
move_section_to($course, 2, 3);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
diff --git a/course/upgrade.txt b/course/upgrade.txt
index e9267c4ded2..11dbd088635 100644
--- a/course/upgrade.txt
+++ b/course/upgrade.txt
@@ -92,6 +92,8 @@ course formats don't have their own renderer.
* The following functions have been deprecated in favour partial course cache rebuild:
- course_purge_section_cache (replaced by course_modinfo::purge_course_section_cache_by_id() and course_modinfo::purge_course_section_cache_by_number())
- course_purge_module_cache (replaced by course_modinfo::purge_course_module_cache())
+ - get_array_of_activities (replaced by course_modinfo::get_array_of_activities() for better performance)
+* New course_modinfo::purge_course_cache function was created to purge the cache of a given course.
=== 3.11 ===
* A new callback xxx_coursemodule_definition_after_data that allows plugins to extend activity forms after the data is set.
diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php
index 5d95ab6a96f..9d9208c882c 100644
--- a/lib/deprecatedlib.php
+++ b/lib/deprecatedlib.php
@@ -3729,3 +3729,18 @@ function print_grade_plugin_selector($plugin_info, $active_type, $active_plugin,
course_modinfo::purge_course_module_cache($courseid, $cmid);
}
}
+
+/**
+ * For a given course, returns an array of course activity objects
+ * Each item in the array contains he following properties:
+ *
+ * @param int $courseid course id
+ * @param bool $usecache get activities from cache if modinfo exists when $usecache is true
+ * @return array list of activities
+ * @deprecated since Moodle 4.0. Please use {@link course_modinfo::get_array_of_activities()} instead.
+ */
+function get_array_of_activities(int $courseid, bool $usecache = false): array {
+ debugging(__FUNCTION__ . '() is deprecated. ' . 'Please use course_modinfo::get_array_of_activities() instead.',
+ DEBUG_DEVELOPER);
+ return course_modinfo::get_array_of_activities(get_course($courseid), $usecache);
+}
diff --git a/lib/modinfolib.php b/lib/modinfolib.php
index 4a69dc8ef8f..bf20367db5d 100644
--- a/lib/modinfolib.php
+++ b/lib/modinfolib.php
@@ -476,13 +476,13 @@ class course_modinfo {
// Retrieve modinfo from cache. If not present or cacherev mismatches, call rebuild and retrieve again.
$coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
- if (!$coursemodinfo) {
+ if ($coursemodinfo === false || ($course->cacherev != $coursemodinfo->cacherev)) {
$lock = self::get_course_cache_lock($course->id);
try {
// Only actually do the build if it's still needed after getting the lock (not if
// somebody else, who might have been holding the lock, built it already).
$coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
- if (!$coursemodinfo) {
+ if ($coursemodinfo === false || ($course->cacherev != $coursemodinfo->cacherev)) {
$coursemodinfo = self::inner_build_course_cache($course, $lock);
}
} finally {
@@ -553,7 +553,6 @@ class course_modinfo {
$this->instances[$cm->modname] = array();
}
$this->instances[$cm->modname][$cm->instance] = $cm;
- ksort($this->instances[$cm->modname]);
$this->cms[$cm->id] = $cm;
// Reconstruct sections. This works because modules are stored in order
@@ -563,8 +562,6 @@ class course_modinfo {
$this->sections[$cm->sectionnum][] = $cm->id;
}
- ksort($this->cms);
- ksort($this->instances);
// Expand section objects
$this->sectioninfo = array();
foreach ($coursemodinfo->sectioncache as $number => $data) {
@@ -605,7 +602,7 @@ class course_modinfo {
if ($usecache) {
$cachecoursemodinfo = \cache::make('core', 'coursemodinfo');
- $coursemodinfo = $cachecoursemodinfo->get($course->id);
+ $coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
if ($coursemodinfo !== false) {
$compressedsections = $coursemodinfo->sectioncache;
}
@@ -709,7 +706,7 @@ class course_modinfo {
// Retrieve all information about activities and sections.
$coursemodinfo = new stdClass();
- $coursemodinfo->modinfo = get_array_of_activities($course->id, $partialrebuild);
+ $coursemodinfo->modinfo = self::get_array_of_activities($course, $partialrebuild);
$coursemodinfo->sectioncache = self::build_course_section_cache($course, $partialrebuild);
foreach (self::$cachedfields as $key) {
$coursemodinfo->$key = $course->$key;
@@ -727,20 +724,21 @@ class course_modinfo {
* @param int $sectionid The section _id_ to purge
*/
public static function purge_course_section_cache_by_id(int $courseid, int $sectionid): void {
+ $course = get_course($courseid);
$cache = cache::make('core', 'coursemodinfo');
- $cache->acquire_lock($courseid);
- $coursemodinfo = $cache->get($courseid);
+ $cache->acquire_lock($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
if ($coursemodinfo !== false) {
foreach ($coursemodinfo->sectioncache as $sectionno => $sectioncache) {
if ($sectioncache->id == $sectionid) {
$coursemodinfo->cacherev = -1;
unset($coursemodinfo->sectioncache[$sectionno]);
- $cache->set($courseid, $coursemodinfo);
+ $cache->set_versioned($course->id, $course->cacherev, $coursemodinfo);
break;
}
}
}
- $cache->release_lock($courseid);
+ $cache->release_lock($course->id);
}
/**
@@ -750,15 +748,16 @@ class course_modinfo {
* @param int $sectionno The section number to purge
*/
public static function purge_course_section_cache_by_number(int $courseid, int $sectionno): void {
+ $course = get_course($courseid);
$cache = cache::make('core', 'coursemodinfo');
- $cache->acquire_lock($courseid);
- $coursemodinfo = $cache->get($courseid);
+ $cache->acquire_lock($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
if ($coursemodinfo !== false && array_key_exists($sectionno, $coursemodinfo->sectioncache)) {
$coursemodinfo->cacherev = -1;
unset($coursemodinfo->sectioncache[$sectionno]);
- $cache->set($courseid, $coursemodinfo);
+ $cache->set_versioned($course->id, $course->cacherev, $coursemodinfo);
}
- $cache->release_lock($courseid);
+ $cache->release_lock($course->id);
}
/**
@@ -768,16 +767,212 @@ class course_modinfo {
* @param int $cmid Course module id
*/
public static function purge_course_module_cache(int $courseid, int $cmid): void {
+ $course = get_course($courseid);
$cache = cache::make('core', 'coursemodinfo');
- $cache->acquire_lock($courseid);
- $coursemodinfo = $cache->get($courseid);
+ $cache->acquire_lock($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
$hascache = ($coursemodinfo !== false) && array_key_exists($cmid, $coursemodinfo->modinfo);
if ($hascache) {
$coursemodinfo->cacherev = -1;
unset($coursemodinfo->modinfo[$cmid]);
- $cache->set($courseid, $coursemodinfo);
+ $cache->set_versioned($course->id, $course->cacherev, $coursemodinfo);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
}
- $cache->release_lock($courseid);
+ $cache->release_lock($course->id);
+ }
+
+ /**
+ * For a given course, returns an array of course activity objects
+ *
+ * @param stdClass $course Course object
+ * @param bool $usecache get activities from cache if modinfo exists when $usecache is true
+ * @return array list of activities
+ */
+ public static function get_array_of_activities(stdClass $course, bool $usecache = false): array {
+ global $CFG, $DB;
+
+ if (empty($course)) {
+ throw new moodle_exception('courseidnotfound');
+ }
+
+ $rawmods = get_course_mods($course->id);
+ if (empty($rawmods)) {
+ return [];
+ }
+
+ $mods = [];
+ if ($usecache) {
+ // Get existing cache.
+ $cachecoursemodinfo = cache::make('core', 'coursemodinfo');
+ $coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
+ if ($coursemodinfo !== false) {
+ $mods = $coursemodinfo->modinfo;
+ }
+ }
+
+ $courseformat = course_get_format($course);
+
+ if ($sections = $DB->get_records('course_sections', ['course' => $course->id],
+ 'section ASC', 'id,section,sequence,visible')) {
+ // First check and correct obvious mismatches between course_sections.sequence and course_modules.section.
+ if ($errormessages = course_integrity_check($course->id, $rawmods, $sections)) {
+ debugging(join('
', $errormessages));
+ $rawmods = get_course_mods($course->id);
+ $sections = $DB->get_records('course_sections', ['course' => $course->id],
+ 'section ASC', 'id,section,sequence,visible');
+ }
+ // Build array of activities.
+ foreach ($sections as $section) {
+ if (!empty($section->sequence)) {
+ $cmids = explode(",", $section->sequence);
+ $numberofmods = count($cmids);
+ foreach ($cmids as $cmid) {
+ // Activity does not exist in the database.
+ $notexistindb = empty($rawmods[$cmid]);
+ $activitycached = isset($mods[$cmid]);
+ if ($activitycached || $notexistindb) {
+ continue;
+ }
+
+ // Adjust visibleoncoursepage, value in DB may not respect format availability.
+ $rawmods[$cmid]->visibleoncoursepage = (!$rawmods[$cmid]->visible
+ || $rawmods[$cmid]->visibleoncoursepage
+ || empty($CFG->allowstealth)
+ || !$courseformat->allow_stealth_module_visibility($rawmods[$cmid], $section)) ? 1 : 0;
+
+ $mods[$cmid] = new stdClass();
+ $mods[$cmid]->id = $rawmods[$cmid]->instance;
+ $mods[$cmid]->cm = $rawmods[$cmid]->id;
+ $mods[$cmid]->mod = $rawmods[$cmid]->modname;
+
+ // Oh dear. Inconsistent names left here for backward compatibility.
+ $mods[$cmid]->section = $section->section;
+ $mods[$cmid]->sectionid = $rawmods[$cmid]->section;
+
+ $mods[$cmid]->module = $rawmods[$cmid]->module;
+ $mods[$cmid]->added = $rawmods[$cmid]->added;
+ $mods[$cmid]->score = $rawmods[$cmid]->score;
+ $mods[$cmid]->idnumber = $rawmods[$cmid]->idnumber;
+ $mods[$cmid]->visible = $rawmods[$cmid]->visible;
+ $mods[$cmid]->visibleoncoursepage = $rawmods[$cmid]->visibleoncoursepage;
+ $mods[$cmid]->visibleold = $rawmods[$cmid]->visibleold;
+ $mods[$cmid]->groupmode = $rawmods[$cmid]->groupmode;
+ $mods[$cmid]->groupingid = $rawmods[$cmid]->groupingid;
+ $mods[$cmid]->indent = $rawmods[$cmid]->indent;
+ $mods[$cmid]->completion = $rawmods[$cmid]->completion;
+ $mods[$cmid]->extra = "";
+ $mods[$cmid]->completiongradeitemnumber =
+ $rawmods[$cmid]->completiongradeitemnumber;
+ $mods[$cmid]->completionpassgrade = $rawmods[$cmid]->completionpassgrade;
+ $mods[$cmid]->completionview = $rawmods[$cmid]->completionview;
+ $mods[$cmid]->completionexpected = $rawmods[$cmid]->completionexpected;
+ $mods[$cmid]->showdescription = $rawmods[$cmid]->showdescription;
+ $mods[$cmid]->availability = $rawmods[$cmid]->availability;
+ $mods[$cmid]->deletioninprogress = $rawmods[$cmid]->deletioninprogress;
+ $mods[$cmid]->downloadcontent = $rawmods[$cmid]->downloadcontent;
+
+ $modname = $mods[$cmid]->mod;
+ $functionname = $modname . "_get_coursemodule_info";
+
+ if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
+ continue;
+ }
+
+ include_once("$CFG->dirroot/mod/$modname/lib.php");
+
+ if ($hasfunction = function_exists($functionname)) {
+ if ($info = $functionname($rawmods[$cmid])) {
+ if (!empty($info->icon)) {
+ $mods[$cmid]->icon = $info->icon;
+ }
+ if (!empty($info->iconcomponent)) {
+ $mods[$cmid]->iconcomponent = $info->iconcomponent;
+ }
+ if (!empty($info->name)) {
+ $mods[$cmid]->name = $info->name;
+ }
+ if ($info instanceof cached_cm_info) {
+ // When using cached_cm_info you can include three new fields.
+ // That aren't available for legacy code.
+ if (!empty($info->content)) {
+ $mods[$cmid]->content = $info->content;
+ }
+ if (!empty($info->extraclasses)) {
+ $mods[$cmid]->extraclasses = $info->extraclasses;
+ }
+ if (!empty($info->iconurl)) {
+ // Convert URL to string as it's easier to store.
+ // Also serialized object contains \0 byte,
+ // ... and can not be written to Postgres DB.
+ $url = new moodle_url($info->iconurl);
+ $mods[$cmid]->iconurl = $url->out(false);
+ }
+ if (!empty($info->onclick)) {
+ $mods[$cmid]->onclick = $info->onclick;
+ }
+ if (!empty($info->customdata)) {
+ $mods[$cmid]->customdata = $info->customdata;
+ }
+ } else {
+ // When using a stdclass, the (horrible) deprecated ->extra field,
+ // ... that is available for BC.
+ if (!empty($info->extra)) {
+ $mods[$cmid]->extra = $info->extra;
+ }
+ }
+ }
+ }
+ // When there is no modname_get_coursemodule_info function,
+ // ... but showdescriptions is enabled, then we use the 'intro',
+ // ... and 'introformat' fields in the module table.
+ if (!$hasfunction && $rawmods[$cmid]->showdescription) {
+ if ($modvalues = $DB->get_record($rawmods[$cmid]->modname,
+ ['id' => $rawmods[$cmid]->instance], 'name, intro, introformat')) {
+ // Set content from intro and introformat. Filters are disabled.
+ // Because we filter it with format_text at display time.
+ $mods[$cmid]->content = format_module_intro($rawmods[$cmid]->modname,
+ $modvalues, $rawmods[$cmid]->id, false);
+
+ // To save making another query just below, put name in here.
+ $mods[$cmid]->name = $modvalues->name;
+ }
+ }
+ if (!isset($mods[$cmid]->name)) {
+ $mods[$cmid]->name = $DB->get_field($rawmods[$cmid]->modname, "name",
+ ["id" => $rawmods[$cmid]->instance]);
+ }
+
+ // Minimise the database size by unsetting default options when they are 'empty'.
+ // This list corresponds to code in the cm_info constructor.
+ foreach (['idnumber', 'groupmode', 'groupingid',
+ 'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content',
+ 'icon', 'iconcomponent', 'customdata', 'availability', 'completionview',
+ 'completionexpected', 'score', 'showdescription', 'deletioninprogress'] as $property) {
+ if (property_exists($mods[$cmid], $property) &&
+ empty($mods[$cmid]->{$property})) {
+ unset($mods[$cmid]->{$property});
+ }
+ }
+ // Special case: this value is usually set to null, but may be 0.
+ if (property_exists($mods[$cmid], 'completiongradeitemnumber') &&
+ is_null($mods[$cmid]->completiongradeitemnumber)) {
+ unset($mods[$cmid]->completiongradeitemnumber);
+ }
+ }
+ }
+ }
+ }
+ return $mods;
+ }
+
+ /**
+ * Purge the cache of a given course
+ *
+ * @param int $courseid Course id
+ */
+ public static function purge_course_cache(int $courseid): void {
+ $cachemodinfo = cache::make('core', 'coursemodinfo');
+ $cachemodinfo->delete($courseid);
}
}
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index ee60a46c6e3..eb4c126f75a 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -5347,8 +5347,7 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
fulldelete($CFG->dataroot.'/'.$course->id);
// Delete from cache to reduce the cache size especially makes sense in case of bulk course deletion.
- $cachemodinfo = cache::make('core', 'coursemodinfo');
- $cachemodinfo->delete($courseid);
+ course_modinfo::purge_course_cache($courseid);
// Trigger a course content deleted event.
$event = \core\event\course_content_deleted::create(array(
diff --git a/lib/tests/modinfolib_test.php b/lib/tests/modinfolib_test.php
index 633676201b6..da19910af82 100644
--- a/lib/tests/modinfolib_test.php
+++ b/lib/tests/modinfolib_test.php
@@ -367,7 +367,7 @@ class modinfolib_test extends advanced_testcase {
$this->assertEquals($USER->id, $modinfo->userid);
$this->assertEquals(array(0 => array($forum0->cmid, $assign0->cmid),
1 => array($forum1->cmid, $assign1->cmid, $page1->cmid), 3 => array($page3->cmid)), $modinfo->sections);
- $this->assertEquals(array('assign', 'forum', 'page'), array_keys($modinfo->instances));
+ $this->assertEquals(array('forum', 'assign', 'page'), array_keys($modinfo->instances));
$this->assertEquals(array($assign0->id, $assign1->id), array_keys($modinfo->instances['assign']));
$this->assertEquals(array($forum0->id, $forum1->id), array_keys($modinfo->instances['forum']));
$this->assertEquals(array($page1->id, $page3->id), array_keys($modinfo->instances['page']));
@@ -1023,7 +1023,7 @@ class modinfolib_test extends advanced_testcase {
// Build course cache.
get_fast_modinfo($course->id);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
@@ -1037,7 +1037,7 @@ class modinfolib_test extends advanced_testcase {
// Purge cache for the section by id.
course_modinfo::purge_course_section_cache_by_id($course->id, $sectioncaches[1]->id);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
@@ -1069,7 +1069,7 @@ class modinfolib_test extends advanced_testcase {
// Build course cache.
get_fast_modinfo($course->id);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
@@ -1083,7 +1083,7 @@ class modinfolib_test extends advanced_testcase {
// Purge cache for the section with section number is 1.
course_modinfo::purge_course_section_cache_by_number($course->id, 1);
// Get the course modinfo cache.
- $coursemodinfo = $cache->get($course->id);
+ $coursemodinfo = $cache->get_versioned($course->id, $course->cacherev);
// Get the section cache.
$sectioncaches = $coursemodinfo->sectioncache;
diff --git a/mod/page/lib.php b/mod/page/lib.php
index dae27693bb7..bda4a4fd616 100644
--- a/mod/page/lib.php
+++ b/mod/page/lib.php
@@ -201,7 +201,7 @@ function page_delete_instance($id) {
* "extra" information that may be needed when printing
* this activity in a course listing.
*
- * See {@link get_array_of_activities()} in course/lib.php
+ * See {@link course_modinfo::get_array_of_activities()}
*
* @param stdClass $coursemodule
* @return cached_cm_info Info to customise main page display
diff --git a/mod/resource/lib.php b/mod/resource/lib.php
index 726fd47ca4d..563d2422bc5 100644
--- a/mod/resource/lib.php
+++ b/mod/resource/lib.php
@@ -192,7 +192,7 @@ function resource_delete_instance($id) {
* "extra" information that may be needed when printing
* this activity in a course listing.
*
- * See {@link get_array_of_activities()} in course/lib.php
+ * See {@link course_modinfo::get_array_of_activities()}
*
* @param stdClass $coursemodule
* @return cached_cm_info info
diff --git a/mod/url/lib.php b/mod/url/lib.php
index 169c8a6784d..dae393ac800 100644
--- a/mod/url/lib.php
+++ b/mod/url/lib.php
@@ -203,7 +203,7 @@ function url_delete_instance($id) {
* "extra" information that may be needed when printing
* this activity in a course listing.
*
- * See {@link get_array_of_activities()} in course/lib.php
+ * See {@link course_modinfo::get_array_of_activities()}
*
* @param object $coursemodule
* @return cached_cm_info info