MDL-85431 questions: Fix access checks on Question banks page

Users who could not manage activities on a course, but did have
permission to access particular question banks, could not access the
Question banks page.

This modifies the permission checks on that page to allow access if the
user can either manage activities, or has access to at least one
activity that publishes questions. Some additional changes to the output
were required to prevent non-editing users adding banks.

It also modifies the navigation hook to add the Question banks
navigation node if the user can access any activitiy that publishes
questions on the course. This is all based on cached modinfo and
permissions data so should remain performant.
This commit is contained in:
Mark Johnson
2026-01-05 15:20:51 +00:00
parent 6e82b46a48
commit fbf2963387
5 changed files with 68 additions and 17 deletions
+27 -8
View File
@@ -1416,14 +1416,33 @@ function question_extend_settings_navigation(navigation_node $navigationnode, $c
$iscourse = $context->contextlevel === CONTEXT_COURSE;
if ($iscourse && has_capability('moodle/course:manageactivities', $context)) {
return $navigationnode->add(
get_string('questionbank_plural', 'question'),
new moodle_url($baseurl, ['courseid' => $context->instanceid]),
navigation_node::TYPE_CONTAINER,
null,
'questionbank'
);
if ($iscourse) {
$viewquestionbanks = has_capability('moodle/course:manageactivities', $context);
if (!$viewquestionbanks) {
// If the user can view any activities with shared questions, display the Question banks node.
// If they can access activities with private questions (such as quiz) they can be accessed elsewhere on the course.
$modtypes = \core_question\local\bank\question_bank_helper::get_activity_types_with_shareable_questions();
$modinfo = get_fast_modinfo($context->instanceid);
foreach ($modtypes as $modtype) {
foreach ($modinfo->get_instances_of($modtype) as $mod) {
if (has_capability("mod/{$modtype}:view", $mod->context)) {
$viewquestionbanks = true;
break 2;
}
}
}
}
if ($viewquestionbanks) {
return $navigationnode->add(
get_string('questionbank_plural', 'question'),
new moodle_url($baseurl, ['courseid' => $context->instanceid]),
navigation_node::TYPE_CONTAINER,
null,
'questionbank',
);
} else {
return;
}
} else if ($context->contextlevel == CONTEXT_MODULE) {
$params = ['cmid' => $context->instanceid];
} else {