mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 08:26:37 +02:00
MDL-76174 core_course: get_nearest_editable_subcategory performance fix
This commit is contained in:
parent
1b1a15a308
commit
7d09932365
1 changed files with 44 additions and 6 deletions
|
@ -3182,20 +3182,58 @@ class core_course_category implements renderable, cacheable_object, IteratorAggr
|
||||||
*/
|
*/
|
||||||
public static function get_nearest_editable_subcategory(core_course_category $parentcat,
|
public static function get_nearest_editable_subcategory(core_course_category $parentcat,
|
||||||
array $permissionstocheck): ?core_course_category {
|
array $permissionstocheck): ?core_course_category {
|
||||||
|
global $USER, $DB;
|
||||||
|
|
||||||
// First, check the parent category.
|
// First, check the parent category.
|
||||||
if ($parentcat->has_capabilities($permissionstocheck)) {
|
if ($parentcat->has_capabilities($permissionstocheck)) {
|
||||||
return $parentcat;
|
return $parentcat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the child categories.
|
// Get all course category contexts that are children of the parent category's context where
|
||||||
$subcategoryids = $parentcat->get_all_children_ids();
|
// a) there is a role assignment for the current user or
|
||||||
foreach ($subcategoryids as $subcategoryid) {
|
// b) there are role capability overrides for a role that the user has in this context.
|
||||||
$subcategory = static::get($subcategoryid, MUST_EXIST, true);
|
// We never need to return the system context because it cannot be a child of another context.
|
||||||
|
$fields = array_keys(array_filter(self::$coursecatfields));
|
||||||
|
$ctxselect = context_helper::get_preload_record_columns_sql('ctx');
|
||||||
|
$rs = $DB->get_recordset_sql("
|
||||||
|
SELECT cc.". join(',cc.', $fields). ", $ctxselect
|
||||||
|
FROM {course_categories} cc
|
||||||
|
JOIN {context} ctx ON cc.id = ctx.instanceid AND ctx.contextlevel = :contextcoursecat
|
||||||
|
LEFT JOIN {role_assignments} ra ON ra.contextid = ctx.id
|
||||||
|
LEFT JOIN {role_capabilities} rc ON rc.contextid = ctx.id
|
||||||
|
LEFT JOIN {role_assignments} rc_ra ON rc_ra.roleid = rc.roleid
|
||||||
|
LEFT JOIN {context} rc_ra_ctx ON rc_ra_ctx.id = rc_ra.contextid
|
||||||
|
WHERE ctx.path LIKE :parentpath
|
||||||
|
AND (
|
||||||
|
ra.userid = :userid1
|
||||||
|
OR (
|
||||||
|
rc_ra.userid = :userid2
|
||||||
|
AND (ctx.path = rc_ra_ctx.path OR ctx.path LIKE " . $DB->sql_concat("rc_ra_ctx.path", "'/%'") . ")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
", [
|
||||||
|
'contextcoursecat' => CONTEXT_COURSECAT,
|
||||||
|
'parentpath' => $parentcat->get_context()->path . '/%',
|
||||||
|
'userid1' => $USER->id,
|
||||||
|
'userid2' => $USER->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check if user has required capabilities in any of the contexts.
|
||||||
|
$tocache = [];
|
||||||
|
$result = null;
|
||||||
|
foreach ($rs as $record) {
|
||||||
|
$subcategory = new self($record);
|
||||||
|
$tocache[$subcategory->id] = $subcategory;
|
||||||
if ($subcategory->has_capabilities($permissionstocheck)) {
|
if ($subcategory->has_capabilities($permissionstocheck)) {
|
||||||
return $subcategory;
|
$result = $subcategory;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$rs->close();
|
||||||
|
|
||||||
return null;
|
$coursecatrecordcache = cache::make('core', 'coursecatrecords');
|
||||||
|
$coursecatrecordcache->set_many($tocache);
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue