Development:Roles and modules: Difference between revisions
Helen Foster (talk | contribs) m (→Introduction: typo) |
(link to Roles and Capabilities forum instead of General Developer's one) |
||
Line 1: | Line 1: | ||
This is a page for '''developers''' that describes how to make Moodle modules work under 1.7 roles system. =) For more background information, please read [[Development:Roles]]. For any clarifications please post to the [http://moodle.org/mod/forum/view.php? | This is a page for '''developers''' that describes how to make Moodle modules work under 1.7 roles system. =) For more background information, please read [[Development:Roles]]. For any clarifications please post to the [http://moodle.org/mod/forum/view.php?f=941 Roles and Capabilities forum]. | ||
==Introduction== | ==Introduction== |
Revision as of 08:42, 17 January 2007
This is a page for developers that describes how to make Moodle modules work under 1.7 roles system. =) For more background information, please read Development:Roles. For any clarifications please post to the Roles and Capabilities forum.
Introduction
Moodle 1.6 and below uses 7 default roles, namely primary admin, admin, editing teachers, non-editing teachers, students and guests. The set of capabilities that users associated to these roles can perform is fixed. To check permissions, we normally use isteacheredit($courseid), isguest() etc.
Template:Moodle 1.7 Under the new 1.7 system, roles do not have a fixed set of capabilities anymore. We use a different function called has_capability() to check for specific capabilities, more on this later.
Context
Context is an important concept to make roles work. There are currently 8 levels
define('CONTEXT_SYSTEM', 10); define('CONTEXT_PERSONAL', 20); define('CONTEXT_USERID', 30); define('CONTEXT_COURSECAT', 40); define('CONTEXT_COURSE', 50); define('CONTEXT_GROUP', 60); define('CONTEXT_MODULE', 70); define('CONTEXT_BLOCK', 80);
They are stored as a tuple [contextlevel][instanceid]. For example course with id =2 would be [50][2]. Module with id 495 would be [70][495].
At module level, you only need to worry about CONTEXT_MODULE. Normally, foreach page accessible in your module you would need to load the module using get_context_instance(). The way to use it for modules is $context = get_context_instance(CONTEXT_MODULE, $cm->id); where $cm is the course module object that you would normally have anyway. The contextid is needed for every permission check later on in all your pages.
The has_capability($capability, $contextid, $kill) function
inputs:
$capability is the name of the capability $contextid is normally $context->id, the module context id $kill set to 1 if you want to kill the page, it will throw an error and inform the user that required permission is missing. For example you place has_capability('forum_read', $context->id, true) at the top of the page to prevent users from reading the whole page.
This function looks up a capability for a given context and associated parents recursively. We are pretty much relying on this funciton alone to resolve all capability issues. Original isteacher(), isadmin(), isstudent() etc should all be changed accordingly.
==Loading capabilities== - for now, this plan might change later
Loading capabilities is done when a user first log in. Because it is quite an expensive call, we only load it once and stores everything in the session. So when has_capability() is called, it looks for the values stored in the session variable.
Code rewrite
Some modules might require some tiny rewrites because permission is only checked once at the top, for example some scripts only checks for isstudent() at the top. Now we are able to refine those capabilities, so we need to put the required code changes (add has_capability()) to where the specific capability is needed. For example, in a forum we check to see if user is a student before displaying a discussion page, now we need to check individual permissions for forum_read and forum_reply.
Sample code
// somewhere at the top, after getting $cm, load context $context = get_context_instance(CONTEXT_MODULE, $cm->id); ... has_capability('forum_read', $cm->id, true); // kills this page if user is not allowed to read ... if (has_capability('forum_reply', $cm->id) { print_reply_link(); }
Core API
The core API is located at libdir/accesslib, if you would like to read it =)