MDL-63818 core: Add all relevant module context caps

This change ensures that all capabilities at module context level are
shown within a module, only filtering out those which belong to another
module or the subplugins of another module.

This has the effect that module-level capabilities are included
providing they relate to
- the module being queried
- any subplugin of that module
- any capability at module level which does not belong to another module
  or its subplugin
- any other explicitly included capability

This allows permissions to be defined on a capability at a context
level.
This commit is contained in:
Andrew Nicols 2018-11-01 08:22:48 +08:00
parent 8b019fb709
commit 74a938c353

View File

@ -6821,12 +6821,39 @@ class context_module extends context {
if (!empty($extra)) {
$extra = "OR name $extra";
}
// Fetch the list of modules, and remove this one.
$components = \core_component::get_component_list();
$componentnames = $components['mod'];
unset($componentnames["mod_{$module->name}"]);
$componentnames = array_keys($componentnames);
// Exclude all other modules.
list($notcompsql, $notcompparams) = $DB->get_in_or_equal($componentnames, SQL_PARAMS_NAMED, 'notcomp', false);
$params = array_merge($params, $notcompparams);
// Exclude other component submodules.
$i = 0;
$ignorecomponents = [];
foreach ($componentnames as $mod) {
if ($subplugins = \core_component::get_subplugins($mod)) {
foreach (array_keys($subplugins) as $subplugintype) {
$paramname = "notlike{$i}";
$ignorecomponents[] = $DB->sql_like('component', ":{$paramname}", true, true, true);
$params[$paramname] = "{$subplugintype}_%";
$i++;
}
}
}
$notlikesql = "(" . implode(' AND ', $ignorecomponents) . ")";
$sql = "SELECT *
FROM {capabilities}
WHERE (contextlevel = ".CONTEXT_MODULE."
AND (component = :component OR component = 'moodle'))
AND component {$notcompsql}
AND {$notlikesql})
$extra";
$params['component'] = "mod_$module->name";
return $DB->get_records_sql($sql.' '.$sort, $params);
}