This commit is contained in:
Mihail Geshoski
2025-07-16 23:54:38 +08:00
3 changed files with 46 additions and 13 deletions
+20 -9
View File
@@ -1480,13 +1480,14 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw
* @param string $capability the name of the capability
* @param int $roleid the role id
* @param int|context $contextid null means all contexts
* @param bool $showdebug if true, will show debugging messages
* @return boolean true or exception
*/
function unassign_capability($capability, $roleid, $contextid = null) {
function unassign_capability($capability, $roleid, $contextid = null, bool $showdebug = true) {
global $DB, $USER;
// Capability must exist.
if (!$capinfo = get_capability_info($capability)) {
if (!get_capability_info($capability, $showdebug)) {
throw new coding_exception("Capability '{$capability}' was not found! This has to be fixed in code.");
}
@@ -2460,7 +2461,11 @@ function capabilities_cleanup($component, $newcapdef = null) {
// Delete from roles.
if ($roles = get_roles_with_capability($cachedcap->name)) {
foreach ($roles as $role) {
if (!unassign_capability($cachedcap->name, $role->id)) {
if (!unassign_capability(
capability: $cachedcap->name,
roleid: $role->id,
showdebug: false, // Suppress debugging messages in the get_capability_info().
)) {
throw new \moodle_exception('cannotunassigncap', 'error', '',
(object)array('cap' => $cachedcap->name, 'role' => $role->name));
}
@@ -2595,10 +2600,11 @@ function is_inside_frontpage(context $context) {
/**
* Returns capability information (cached)
*
* @param string $capabilityname
* @param string $capabilityname the capability name.
* @param bool $showdebug if true, will show debugging messages.
* @return ?stdClass object or null if capability not found
*/
function get_capability_info($capabilityname) {
function get_capability_info(string $capabilityname, bool $showdebug = true): ?stdClass {
$caps = get_all_capabilities();
// Check for deprecated capability.
@@ -2608,12 +2614,17 @@ function get_capability_info($capabilityname) {
if (isset($caps[$deprecatedinfo['replacement']])) {
$capabilityname = $deprecatedinfo['replacement'];
} else {
debugging("Capability '{$capabilityname}' was supposed to be replaced with ".
"'{$deprecatedinfo['replacement']}', which does not exist !");
if ($showdebug) {
debugging("Capability '{$capabilityname}' was supposed to be replaced with ".
"'{$deprecatedinfo['replacement']}', which does not exist !");
}
}
}
$fullmessage = $deprecatedinfo['fullmessage'];
debugging($fullmessage, DEBUG_DEVELOPER);
if ($showdebug) {
$fullmessage = $deprecatedinfo['fullmessage'];
debugging($fullmessage, DEBUG_DEVELOPER);
}
}
if (!isset($caps[$capabilityname])) {
return null;
+1 -1
View File
@@ -1189,7 +1189,7 @@ enum param: string {
* @return string
*/
protected function clean_param_value_capability(mixed $param): string {
if (get_capability_info($param)) {
if (!empty($param) && get_capability_info($param)) {
return $param;
} else {
return '';
+25 -3
View File
@@ -2248,7 +2248,7 @@ final class accesslib_test extends advanced_testcase {
$this->expectException('coding_exception');
$this->expectExceptionMessage("Capability '{$capability}' was not found! This has to be fixed in code.");
unassign_capability($capability, CAP_ALLOW, $teacherrole->id, $coursecontext);
unassign_capability($capability, $teacherrole->id, $coursecontext);
}
/**
@@ -3597,10 +3597,10 @@ final class accesslib_test extends advanced_testcase {
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
$this->assertFalse($rc);
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext);
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true);
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext);
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
$this->assertFalse($rc);
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true);
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id);
unset($rc);
accesslib_clear_all_caches_for_unit_testing(); // Must be done after assign_capability().
@@ -5316,6 +5316,28 @@ final class accesslib_test extends advanced_testcase {
$this->assertTrue(has_capability('fake/fullfeatured:fakecapability', \core\context\system::instance(), $user));
$this->assertEquals('Fullfeatured capability description', get_capability_string('fake/fullfeatured:fakecapability'));
}
/**
* Test get_deprecated_capability_info() debugging messages.
*
* @covers ::get_deprecated_capability_info
*/
public function test_get_deprecated_capability_info_debugging(): void {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->create_and_enrol($course);
$this->setup_fake_plugin('access');
// Debugging messages should not be called with valid capability.
get_capability_info('fake/access:existingcapability');
$this->assertDebuggingNotCalled();
// Debugging messages should be called with invalid capability.
get_capability_info('fake/access:fakecapability');
$this->assertDebuggingCalled("The capability 'fake/access:fakecapability' is"
. " deprecated.This capability should not be used anymore.");
// Debugging messages should not be called with invalid capability with suppression param supplied.
get_capability_info('fake/access:fakecapability', false);
$this->assertDebuggingNotCalled();
}
}
/**