MDL-17556: Improve performance of get_fast_modinfo when courses have many activities
This commit is contained in:
+7
-11
@@ -1088,15 +1088,8 @@ function &get_fast_modinfo(&$course, $userid=0) {
|
||||
|
||||
$modlurals = array();
|
||||
|
||||
$cmids = array();
|
||||
$contexts = null;
|
||||
foreach ($info as $mod) {
|
||||
$cmids[$mod->cm] = $mod->cm;
|
||||
}
|
||||
if ($cmids) {
|
||||
// preload all module contexts with one query
|
||||
$contexts = get_context_instance(CONTEXT_MODULE, $cmids);
|
||||
}
|
||||
// If we haven't already preloaded contexts for the course, do it now
|
||||
preload_course_contexts($course->id);
|
||||
|
||||
foreach ($info as $mod) {
|
||||
if (empty($mod->name)) {
|
||||
@@ -1128,11 +1121,14 @@ function &get_fast_modinfo(&$course, $userid=0) {
|
||||
}
|
||||
$cm->modplural = $modlurals[$cm->modname];
|
||||
|
||||
if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $contexts[$cm->id], $userid)) {
|
||||
$modcontext = get_context_instance(CONTEXT_MODULE,$cm->id);
|
||||
|
||||
if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities',
|
||||
$modcontext, $userid)) {
|
||||
$cm->uservisible = false;
|
||||
|
||||
} else if (!empty($CFG->enablegroupings) and !empty($cm->groupmembersonly)
|
||||
and !has_capability('moodle/site:accessallgroups', $contexts[$cm->id], $userid)) {
|
||||
and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
|
||||
if (is_null($modinfo->groups)) {
|
||||
$modinfo->groups = groups_get_user_groups($course->id, $userid);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
preload_course_contexts($course->id);
|
||||
if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) {
|
||||
print_error('nocontext');
|
||||
}
|
||||
|
||||
@@ -2422,6 +2422,56 @@ function cleanup_contexts() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloads all contexts relating to a course: course, modules, and blocks.
|
||||
*
|
||||
* @param int $courseid Course ID
|
||||
*/
|
||||
function preload_course_contexts($courseid) {
|
||||
global $context_cache, $context_cache_id, $CFG;
|
||||
|
||||
// Users can call this multiple times without doing any harm
|
||||
static $preloadedcourses=array();
|
||||
if(array_key_exists($courseid,$preloadedcourses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rs=get_recordset_sql("
|
||||
SELECT
|
||||
x.instanceid, x.id, x.contextlevel, x.path, x.depth
|
||||
FROM
|
||||
{$CFG->prefix}course_modules cm
|
||||
INNER JOIN {$CFG->prefix}context x ON x.instanceid=cm.id
|
||||
WHERE
|
||||
cm.course={$courseid}
|
||||
AND x.contextlevel=".CONTEXT_MODULE."
|
||||
UNION ALL
|
||||
SELECT
|
||||
x.instanceid, x.id, x.contextlevel, x.path, x.depth
|
||||
FROM
|
||||
{$CFG->prefix}block_instance bi
|
||||
INNER JOIN {$CFG->prefix}context x ON x.instanceid=bi.id
|
||||
WHERE
|
||||
bi.pageid={$courseid}
|
||||
AND bi.pagetype='course-view'
|
||||
AND x.contextlevel=".CONTEXT_BLOCK."
|
||||
UNION ALL
|
||||
SELECT
|
||||
x.instanceid, x.id, x.contextlevel, x.path, x.depth
|
||||
FROM
|
||||
{$CFG->prefix}context x
|
||||
WHERE
|
||||
x.instanceid={$courseid}
|
||||
AND x.contextlevel=".CONTEXT_COURSE."
|
||||
");
|
||||
while($context=rs_fetch_next_record($rs)) {
|
||||
$context_cache[$context->contextlevel][$context->instanceid] = $context;
|
||||
$context_cache_id[$context->id] = $context;
|
||||
}
|
||||
rs_close($rs);
|
||||
$preloadedcourses[$courseid]=true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context instance as an object. This function will create the
|
||||
* context instance if it does not exist yet.
|
||||
|
||||
Reference in New Issue
Block a user