如何为Moodle自定义角色程序化添加自定义权限
Got it, let's walk through how to programmatically add that custom_capability to your custom_role across all Moodle instances, building on the partial code you shared.
Step 1: Complete the Capability Definition in access.php
First, finish the permission setup in blocks/custom_block/db/access.php. This file defines the capability itself, so we'll fill in the missing parts and structure it properly:
<?php defined('MOODLE_INTERNAL') || die(); $capabilities = array( 'block/custom_block:custom_capability' => array( 'riskbitmask' => RISK_SPAM | RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( // Leave this empty if you don't want any built-in roles to have this permission by default // Example: 'manager' => CAP_ALLOW, if you want admins to get it automatically ), 'clonepermissionsfrom' => 'moodle/site:config', // Optional: Use this to inherit permission behavior from an existing capability ), );
Step 2: Programmatically Assign the Capability to custom_role
Defining the capability doesn't automatically assign it to your custom role. We'll add an installation or upgrade script to handle this across instances.
Option A: For a New Block Installation (use install.php)
Create blocks/custom_block/db/install.php to run setup when the block is first installed:
<?php defined('MOODLE_INTERNAL') || die(); function xmldb_block_custom_block_install() { global $DB; // Fetch the ID of your custom role (replace 'custom_role' with your role's shortname) $customrole = $DB->get_record('role', array('shortname' => 'custom_role')); if ($customrole) { // Assign the capability to the role at system context assign_capability('block/custom_block:custom_capability', CAP_ALLOW, $customrole->id, CONTEXT_SYSTEM); // Refresh permissions and caches to apply changes immediately role_change_permissions($customrole->id, CONTEXT_SYSTEM); purge_all_caches(); } return true; }
Option B: For an Existing Block Upgrade (use upgrade.php)
If your block is already deployed and you're adding this permission as an update, use blocks/custom_block/db/upgrade.php:
<?php defined('MOODLE_INTERNAL') || die(); function xmldb_block_custom_block_upgrade($oldversion) { global $DB; $dbman = $DB->get_manager(); // Replace 2024052000 with your block's new version number if ($oldversion < 2024052000) { // Fetch the custom role $customrole = $DB->get_record('role', array('shortname' => 'custom_role')); if ($customrole) { assign_capability('block/custom_block:custom_capability', CAP_ALLOW, $customrole->id, CONTEXT_SYSTEM); role_change_permissions($customrole->id, CONTEXT_SYSTEM); purge_all_caches(); } upgrade_block_savepoint(true, 2024052000, 'custom_block'); } return true; }
Step 3: Deploy and Validate
- Push these files to all your Moodle instances
- Run the Moodle upgrade script by visiting
/admin/index.phpon each instance - Verify the permission was assigned:
- Go to Site Administration > Users > Permissions > Define roles
- Select your
custom_role - Check if
block/custom_block:custom_capabilityappears in the list of allowed permissions - Test with a user assigned to
custom_roleto ensure the capability works as expected
Key Notes
- Double-check the
shortnameof your custom role to avoid missing the role record - If your
custom_roleis also created programmatically, make sure that role creation runs before the permission assignment (adjust the order ininstall.phpif needed) - If your capability applies to a different context (not
CONTEXT_SYSTEM), update the context ID inassign_capability()accordingly
内容的提问来源于stack exchange,提问作者xDaizu

