- Moodle 1.9 Extension Development
- Jonathan Moore Michael Churchward
- 1022字
- 2021-08-06 17:24:05
Working with capabilities
In Chapter 1, Moodle Architecture, we covered an overview of Moodle's role and permission system. Now we will get a chance to see the system in action. In a later section, we will also add our own access permissions to Moodle.
Testing for built-in capabilities
We use two Moodle core functions to test for a capability, in this section of code. First, we call the get_context_instance()
function with the site or global context, CONTEXT_SYSTEM
. The function get_context_instance()
will return a context object to us for the requested context type, in this case the system context. Once the context is loaded, we use the require_capability
function to test if the user has the moodle/site:doanything
capability (essentially, the ability to do anything and everything on the site). require_capability
tests the current user's capabilities to see if they have the specified capability in the specified context. If they don't, the page is redirected to an error page:
function get_content() {
if ($this->content !== NULL) {
return $this->content;
}//if
$context = get_context_instance(CONTEXT_SYSTEM); require_capability('moodle/site:doanything', $context);
$this->content = new stdClass;
$this->content->text = 'Hello World!';
return $this->content;
}//function get_content
If we test this same code while logged in as a non-administrative user, we start to see some issues with how the error is handled. This is an example of using require_capability
incorrectly. When the permission fails, we end up with a partially-rendered Moodle screen. The block bleeds out of its side column and the rest of screen is not printed. The following screenshot illustrates what this looks like if the block is placed in the left-hand side column and viewed by a non-administrative user:

The require_capability
function is more appropriate for blocking access to an entire page of content. If we want to handle missing capabilities elegantly for a block, we should use the function has_capability
. Using the following syntax leads to output that works correctly whether or not the user has the required permission. In this case, we use the has_capability
function, which accepts a capability and a context. It returns a response indicating whether or not the user has access to the capability. We then route the results into an if/else
clause, which outputs different information to the user depending on whether the capability is present or not.
$context = get_context_instance(CONTEXT_SYSTEM);
$this->content = new stdClass;
if (!has_capability('moodle/site:doanything', $context)){
$this->content->text = 'Not Admin!';
}// if
else {
$this->content->text = 'Secret Message to Admins!'
}// else
return $this->content;
This method is very useful when you want to display different values to the user depending on which capabilities they have access to.
Hiding a block based on capabilities
In many cases, we are only going to want to display the block if the user has a particular capability. By performing some simple restructuring, our get_content()
function provides this functionality. By moving the creation of the $this object
and its return value into the if
statement, we remove the block display if the user doesn't have the moodle/site:doanything
capability:
$context = get_context_instance(CONTEXT_SYSTEM); if (has_capability('moodle/site:doanything', $context)){ $this->content = new stdClass; $this->content->text = 'Secret Message to Admins!'; return $this->content; }// if
This method leads to a much cleaner page display, and maximizes the data displayed to the user on any given screen.
Adding your own capability
Let's add a capability, by creating a folder called db
within our module. Inside the folder, we create a file called access.php
. This file is then used to define your capabilities. Here is an example of a simple read capability definition. Capabilities are defined as arrays. Note that the key assignment is the name of the capability block/helloworld:view
. The other values in the array assignment are used to specify which context the capability applies to, the type of capability, and finally default values for legacy roles.
<?php $block_helloworld_capabilities = array( 'block/helloworld:view' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, 'legacy' => array( 'guest' => CAP_PREVENT, 'student' => CAP_PREVENT, 'teacher' => CAP_PREVENT, 'editingteacher' => CAP_PREVENT, 'coursecreator' => CAP_PREVENT, 'admin' => CAP_ALLOW ) ) ); ?>
In order to make this change take effect, we need to increment our version value in the block_helloworld.php
file. The format for Moodle version numbers is an integer value of the date (year + month + day) plus two digits to indicate the micro version. The higher the number, the newer the version of the module. Let's set the date of our module to year 2009, month 05, and day 07. This also happens to be the third update to the code for today, so we add a micro version of 03. The following code illustrates the assigning of this version number:
$this->version = 2009050703;
Note that, as a result of these changes, we should also add some additional strings, as follows, to our language file:
$string['helloworld:view'] = 'View Hello World Block'; $string['blockname'] = 'HelloWorld';
Let's have a look at the results of these changes, by viewing a role definition in the following screenshot:

Checking for our new capability
Now that we have added our new capability, we can use it in our block code instead of the moodle/site:doanything
capability. In this new section of code, the line testing the capability is changed as follows, to use the new one that we created:
function get_content() {
if ($this->content !== NULL) {
return $this->content;
}//if
$context = get_context_instance(CONTEXT_SYSTEM);
if (has_capability('block/helloworld:view', $context)) {
$this->content = new stdClass;
$this->content->text = 'Hello World!';
return $this->content;
} //if
Note that this new capability will work anywhere that we might apply a block: on the front page, on the administration page, in the My Moodle page, within course pages, and so on. However, because we have defined the capability in CONTEXT_SYSTEM
only users with a role assigned at the site level will be able to view this block.
In testing, we will find that this block is visible to administrative users, because we set the admin legacy role to have CAP_ALLOW
in our access.php
file. However, any other built-in roles, even if assigned at the site level, will not see this block, because they have received the CAP_PREVENT
permission—unless we manually change their role definition.
We can find further details on the latest methods for programming access permissions at http://docs.moodle.org/en/Development:Roles#Programming_Interface.
- Creo Parametric 8.0中文版基礎入門一本通
- Microsoft Visual C++ Windows Applications by Example
- Moldflow模流分析與工程應用
- SolidWorks 2008機械設計一冊通
- Photoshop+CorelDRAW平面設計實例教程(第4版)
- Photoshop電商設計與產品精修實戰(微視頻版)
- AutoCAD 2022中文版完全自學一本通
- Origin科技繪圖與數據分析
- Joomla! E/Commerce with VirtueMart
- NumPy 1.5 Beginner's Guide
- C# 2008 and 2005 Threaded Programming: Beginner's Guide
- SolidWorks 2020中文版入門、精通與實戰
- 中文版Photoshop CS6基礎教程
- Sage ACT! 2011 Dashboard and Report Cookbook
- Premiere短視頻制作(第2版·全彩慕課版)