2006-08-08 05:13:06 +00:00
< ? php
2006-08-14 07:15:03 +00:00
/**
* Capability session information format
2006-08-08 05:13:06 +00:00
* 2 x 2 array
* [ context ][ capability ]
* where context is the context id of the table 'context'
* and capability is a string defining the capability
* e . g .
*
* [ Capabilities ] => [ 26 ][ mod / forum : viewpost ] = 1
* [ 26 ][ mod / forum : startdiscussion ] = - 8990
* [ 26 ][ mod / forum : editallpost ] = - 1
* [ 273 ][ moodle : blahblah ] = 1
* [ 273 ][ moodle : blahblahblah ] = 2
*/
// permission definitions
define ( 'CAP_ALLOW' , 1 );
define ( 'CAP_PREVENT' , - 1 );
define ( 'CAP_PROHIBIT' , - 1000 );
// context definitions
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 );
2006-08-13 15:48:57 +00:00
$context_cache = array (); // Cache of all used context objects for performance (by level and instance)
$context_cache_id = array (); // Index to above cache by id
2006-08-08 05:13:06 +00:00
2006-08-14 07:15:03 +00:00
2006-08-08 05:13:06 +00:00
/**
* This functions get all the course categories in proper order
2006-08-14 05:55:40 +00:00
* @ param int $context
2006-08-08 05:13:06 +00:00
* @ param int $type
* @ return array of contextids
*/
2006-08-14 05:55:40 +00:00
function get_parent_cats ( $context , $type ) {
2006-08-09 13:14:15 +00:00
$parents = array ();
2006-08-31 05:06:30 +00:00
switch ( $type ) {
2006-08-09 13:14:15 +00:00
case CONTEXT_COURSECAT :
2006-08-31 05:06:30 +00:00
if ( ! $cat = get_record ( 'course_categories' , 'id' , $context -> instanceid )) {
break ;
}
while ( ! empty ( $cat -> parent )) {
if ( ! $context = get_context_instance ( CONTEXT_COURSECAT , $cat -> parent )) {
break ;
}
2006-08-09 13:14:15 +00:00
$parents [] = $context -> id ;
$cat = get_record ( 'course_categories' , 'id' , $cat -> parent );
}
break ;
case CONTEXT_COURSE :
2006-08-31 05:06:30 +00:00
if ( ! $course = get_record ( 'course' , 'id' , $context -> instanceid )) {
break ;
}
if ( ! $catinstance = get_context_instance ( CONTEXT_COURSECAT , $course -> category )) {
break ;
}
2006-08-09 13:14:15 +00:00
$parents [] = $catinstance -> id ;
2006-08-31 05:06:30 +00:00
if ( ! $cat = get_record ( 'course_categories' , 'id' , $course -> category )) {
break ;
}
while ( ! empty ( $cat -> parent )) {
if ( ! $context = get_context_instance ( CONTEXT_COURSECAT , $cat -> parent )) {
break ;
}
2006-08-09 13:14:15 +00:00
$parents [] = $context -> id ;
$cat = get_record ( 'course_categories' , 'id' , $cat -> parent );
}
break ;
default :
break ;
}
return array_reverse ( $parents );
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
/*************************************
* Functions for Roles & Capabilites *
*************************************/
2006-08-08 05:13:06 +00:00
2006-08-14 05:55:40 +00:00
/**
* This function checks for a capability assertion being true . If it isn ' t
* then the page is terminated neatly with a standard error message
* @ param string $capability - name of the capability
* @ param object $context - a context object ( record from context table )
* @ param integer $userid - a userid number
* @ param string $errorstring - an errorstring
*/
function require_capability ( $capability , $context = NULL , $userid = NULL , $errormessage = " nopermissions " , $stringfile = '' ) {
2006-08-31 07:40:48 +00:00
global $USER ;
/// If the current user is not logged in, then make sure they are
if ( empty ( $userid ) and empty ( $USER -> id )) {
if ( $context && ( $context -> aggregatelevel == CONTEXT_COURSE )) {
require_login ( $context -> instanceid );
} else {
require_login ();
}
}
/// OK, if they still don't have the capability then print a nice error message
2006-08-14 05:55:40 +00:00
if ( ! has_capability ( $capability , $context , $userid )) {
$capabilityname = get_capability_string ( $capability );
print_error ( $errormessage , $stringfile , '' , $capabilityname );
}
}
2006-08-08 05:13:06 +00:00
/**
* This function returns whether the current user has the capability of performing a function
* For example , we can do has_capability ( 'mod/forum:replypost' , $cm ) in forum
* only one of the 4 ( moduleinstance , courseid , site , userid ) would be set at 1 time
* This is a recursive funciton .
* @ uses $USER
* @ param string $capability - name of the capability
2006-08-14 05:55:40 +00:00
* @ param object $context - a context object ( record from context table )
* @ param integer $userid - a userid number
2006-08-08 05:13:06 +00:00
* @ return bool
*/
2006-08-14 05:55:40 +00:00
function has_capability ( $capability , $context = NULL , $userid = NULL ) {
2006-08-08 05:13:06 +00:00
2006-08-13 15:48:57 +00:00
global $USER , $CONTEXT ;
2006-08-08 05:13:06 +00:00
2006-08-25 20:12:12 +00:00
if ( $userid ) {
if ( empty ( $USER -> id ) or ( $userid != $USER -> id )) {
$capabilities = load_user_capability ( $capability , $context , $userid );
} else { //$USER->id == $userid
$capabilities = empty ( $USER -> capabilities ) ? NULL : $USER -> capabilities ;
}
} else { // no userid
$capabilities = empty ( $USER -> capabilities ) ? NULL : $USER -> capabilities ;
2006-08-09 13:14:15 +00:00
}
2006-08-25 20:12:12 +00:00
2006-08-14 05:55:40 +00:00
if ( empty ( $context )) { // Use default CONTEXT if none specified
2006-08-13 15:48:57 +00:00
if ( empty ( $CONTEXT )) {
return false ;
} else {
$context = $CONTEXT ;
}
2006-08-14 05:55:40 +00:00
} else { // A context was given to us
if ( empty ( $CONTEXT )) {
$CONTEXT = $context ; // Store FIRST used context in this global as future default
}
2006-08-13 15:48:57 +00:00
}
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
// Check site
$sitecontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
if ( isset ( $capabilities [ $sitecontext -> id ][ 'moodle/site:doanything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $sitecontext -> id ][ 'moodle/site:doanything' ]);
2006-08-09 13:14:15 +00:00
}
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-08 05:13:06 +00:00
case CONTEXT_COURSECAT :
2006-08-09 13:14:15 +00:00
// Check parent cats.
2006-08-14 05:55:40 +00:00
$parentcats = get_parent_cats ( $context , CONTEXT_COURSECAT );
2006-08-09 13:14:15 +00:00
foreach ( $parentcats as $parentcat ) {
if ( isset ( $capabilities [ $parentcat ][ 'moodle/site:doanything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $parentcat ][ 'moodle/site:doanything' ]);
2006-08-14 07:15:03 +00:00
}
2006-08-09 13:14:15 +00:00
}
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSE :
2006-08-09 13:14:15 +00:00
// Check parent cat.
2006-08-14 05:55:40 +00:00
$parentcats = get_parent_cats ( $context , CONTEXT_COURSE );
2006-08-09 13:14:15 +00:00
foreach ( $parentcats as $parentcat ) {
if ( isset ( $capabilities [ $parentcat ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $parentcat ][ 'do_anything' ]);
}
2006-08-09 13:14:15 +00:00
}
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_GROUP :
2006-08-09 13:14:15 +00:00
// Find course.
$group = get_record ( 'groups' , 'id' , $context -> instanceid );
2006-08-08 05:13:06 +00:00
$courseinstance = get_context_instance ( CONTEXT_COURSE , $group -> courseid );
2006-08-25 20:12:12 +00:00
$parentcats = get_parent_cats ( $courseinstance , CONTEXT_COURSE );
2006-08-09 13:14:15 +00:00
foreach ( $parentcats as $parentcat ) {
if ( isset ( $capabilities [ $parentcat -> id ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $parentcat -> id ][ 'do_anything' ]);
}
}
2006-08-09 13:14:15 +00:00
$coursecontext = '' ;
if ( isset ( $capabilities [ $courseinstance -> id ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $courseinstance -> id ][ 'do_anything' ]);
}
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_MODULE :
// Find course.
$cm = get_record ( 'course_modules' , 'id' , $context -> instanceid );
2006-08-09 13:14:15 +00:00
$courseinstance = get_context_instance ( CONTEXT_COURSE , $cm -> course );
2006-08-25 20:12:12 +00:00
if ( $parentcats = get_parent_cats ( $courseinstance , CONTEXT_COURSE )) {
2006-08-09 13:14:15 +00:00
foreach ( $parentcats as $parentcat ) {
if ( isset ( $capabilities [ $parentcat ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $parentcat ][ 'do_anything' ]);
2006-08-14 07:15:03 +00:00
}
2006-08-25 20:12:12 +00:00
}
}
2006-08-09 13:14:15 +00:00
if ( isset ( $capabilities [ $courseinstance -> id ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $courseinstance -> id ][ 'do_anything' ]);
2006-08-14 07:15:03 +00:00
}
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_BLOCK :
// 1 to 1 to course.
// Find course.
$block = get_record ( 'block_instance' , 'id' , $context -> instanceid );
$courseinstance = get_context_instance ( CONTEXT_COURSE , $block -> pageid ); // needs check
2006-08-25 20:12:12 +00:00
$parentcats = get_parent_cats ( $courseinstance , CONTEXT_COURSE );
2006-08-09 13:14:15 +00:00
foreach ( $parentcats as $parentcat ) {
if ( isset ( $capabilities [ $parentcat ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $parentcat ][ 'do_anything' ]);
2006-08-14 07:15:03 +00:00
}
}
2006-08-25 20:12:12 +00:00
2006-08-09 13:14:15 +00:00
if ( isset ( $capabilities [ $courseinstance -> id ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $courseinstance -> id ][ 'do_anything' ]);
2006-08-14 07:15:03 +00:00
}
2006-08-08 05:13:06 +00:00
break ;
default :
// CONTEXT_SYSTEM: CONTEXT_PERSONAL: CONTEXT_USERID:
// Do nothing.
break ;
2006-08-09 13:14:15 +00:00
}
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
// Last: check self.
2006-08-14 05:55:40 +00:00
if ( isset ( $capabilities [ $context -> id ][ 'do_anything' ])) {
2006-08-25 20:12:12 +00:00
return ( 0 < $capabilities [ $context -> id ][ 'do_anything' ]);
2006-08-09 13:14:15 +00:00
}
2006-08-25 20:12:12 +00:00
2006-08-09 13:14:15 +00:00
// do_anything has not been set, we now look for it the normal way.
2006-08-25 20:12:12 +00:00
return ( 0 < capability_search ( $capability , $context , $capabilities ));
2006-08-08 05:13:06 +00:00
2006-08-25 20:12:12 +00:00
}
2006-08-08 05:13:06 +00:00
/**
* In a separate function so that we won ' t have to deal with do_anything .
* again . Used by function has_capability .
* @ param $capability - capability string
2006-08-14 05:55:40 +00:00
* @ param $context - the context object
2006-08-08 05:13:06 +00:00
* @ param $capabilities - either $USER -> capability or loaded array
* @ return permission ( int )
*/
2006-08-14 05:55:40 +00:00
function capability_search ( $capability , $context , $capabilities ) {
2006-08-08 05:13:06 +00:00
global $USER , $CFG ;
2006-08-14 05:55:40 +00:00
2006-08-25 20:12:12 +00:00
2006-08-14 05:55:40 +00:00
if ( isset ( $capabilities [ $context -> id ][ $capability ])) {
2006-08-25 20:12:12 +00:00
if ( $CFG -> debug > 15 ) {
notify ( " Found $capability in context $context->id at level $context->aggregatelevel : " . $capabilities [ $context -> id ][ $capability ], 'notifytiny' );
}
2006-08-14 05:55:40 +00:00
return ( $capabilities [ $context -> id ][ $capability ]);
2006-08-08 05:13:06 +00:00
}
2006-08-25 20:12:12 +00:00
2006-08-08 05:13:06 +00:00
/* Then, we check the cache recursively */
2006-08-25 20:12:12 +00:00
$permission = 0 ;
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-08 05:13:06 +00:00
case CONTEXT_SYSTEM : // by now it's a definite an inherit
$permission = 0 ;
break ;
case CONTEXT_PERSONAL :
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
2006-08-25 20:12:12 +00:00
2006-08-08 05:13:06 +00:00
case CONTEXT_USERID :
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
2006-08-25 20:12:12 +00:00
2006-08-08 05:13:06 +00:00
case CONTEXT_COURSECAT : // Coursecat -> coursecat or site
$coursecat = get_record ( 'course_categories' , 'id' , $context -> instanceid );
2006-08-14 05:55:40 +00:00
if ( ! empty ( $coursecat -> parent )) { // return parent value if it exists
$parentcontext = get_context_instance ( CONTEXT_COURSECAT , $coursecat -> parent );
2006-08-08 05:13:06 +00:00
} else { // else return site value
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-08 05:13:06 +00:00
}
2006-08-14 05:55:40 +00:00
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSE : // 1 to 1 to course cat
// find the course cat, and return its value
$course = get_record ( 'course' , 'id' , $context -> instanceid );
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_COURSECAT , $course -> category );
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_GROUP : // 1 to 1 to course
$group = get_record ( 'groups' , 'id' , $context -> instanceid );
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_COURSE , $group -> courseid );
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_MODULE : // 1 to 1 to course
$cm = get_record ( 'course_modules' , 'id' , $context -> instanceid );
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_COURSE , $cm -> course );
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_BLOCK : // 1 to 1 to course
$block = get_record ( 'block_instance' , 'id' , $context -> instanceid );
2006-08-14 05:55:40 +00:00
$parentcontext = get_context_instance ( CONTEXT_COURSE , $block -> pageid ); // needs check
$permission = capability_search ( $capability , $parentcontext , $capabilities );
2006-08-08 05:13:06 +00:00
break ;
default :
error ( 'This is an unknown context!' );
return false ;
}
2006-08-25 20:12:12 +00:00
if ( $CFG -> debug > 15 ) {
notify ( " Found $capability recursively from context $context->id at level $context->aggregatelevel : $permission " , 'notifytiny' );
}
2006-08-09 13:14:15 +00:00
return $permission ;
2006-08-08 05:13:06 +00:00
}
/**
* This function should be called immediately after a login , when $USER is set .
* It will build an array of all the capabilities at each level
* i . e . site / metacourse / course_category / course / moduleinstance
* Note we should only load capabilities if they are explicitly assigned already ,
* we should not load all module ' s capability !
* @ param $userid - the id of the user whose capabilities we want to load
* @ return array
* possible just s simple 2 D array with [ contextid ][ capabilityname ]
* [ Capabilities ] => [ 26 ][ forum_post ] = 1
* [ 26 ][ forum_start ] = - 8990
* [ 26 ][ forum_edit ] = - 1
* [ 273 ][ blah blah ] = 1
* [ 273 ][ blah blah blah ] = 2
*/
2006-08-14 05:55:40 +00:00
function load_user_capability ( $capability = '' , $context = '' , $userid = '' ) {
2006-08-21 05:19:16 +00:00
2006-08-09 13:14:15 +00:00
global $USER , $CFG ;
2006-08-08 05:13:06 +00:00
if ( empty ( $userid )) {
$userid = $USER -> id ;
} else {
2006-08-25 20:12:12 +00:00
$otheruserid = $userid ;
2006-08-08 05:13:06 +00:00
}
2006-08-25 20:12:12 +00:00
2006-08-08 05:13:06 +00:00
if ( $capability ) {
2006-08-25 20:12:12 +00:00
$capsearch = " AND rc.capability = ' $capability ' " ;
2006-08-08 05:13:06 +00:00
} else {
2006-08-25 20:12:12 +00:00
$capsearch = " " ;
2006-08-08 05:13:06 +00:00
}
2006-08-31 04:17:51 +00:00
/// First we generate a list of all relevant contexts of the user
$usercontexts = array ();
2006-08-08 05:13:06 +00:00
2006-08-14 05:55:40 +00:00
if ( $context ) { // if context is specified
$usercontexts = get_parent_contexts ( $context );
2006-08-09 13:14:15 +00:00
} else { // else, we load everything
2006-08-31 04:17:51 +00:00
if ( $userroles = get_records ( 'role_assignments' , 'userid' , $userid )) {
foreach ( $userroles as $userrole ) {
$usercontexts [] = $userrole -> contextid ;
}
2006-08-09 13:14:15 +00:00
}
2006-08-31 04:17:51 +00:00
}
/// Set up SQL fragments for searching contexts
if ( $usercontexts ) {
2006-08-14 05:55:40 +00:00
$listofcontexts = '(' . implode ( ',' , $usercontexts ) . ')' ;
2006-08-31 04:17:51 +00:00
$searchcontexts1 = " c1.id IN $listofcontexts AND " ;
$searchcontexts2 = " c2.id IN $listofcontexts AND " ;
} else {
$listofcontexts = $searchcontexts1 = $searchcontexts2 = '' ;
2006-08-08 05:13:06 +00:00
}
2006-08-14 05:55:40 +00:00
2006-08-31 04:17:51 +00:00
/// Then we use 1 giant SQL to bring out all relevant capabilities.
/// The first part gets the capabilities of orginal role.
/// The second part gets the capabilities of overriden roles.
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
$siteinstance = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-08 05:13:06 +00:00
2006-08-22 16:18:11 +00:00
$SQL = " SELECT rc.capability, c1.id, (c1.aggregatelevel * 100) AS aggrlevel,
2006-08-08 05:13:06 +00:00
SUM ( rc . permission ) AS sum
FROM
2006-08-10 08:21:29 +00:00
{ $CFG -> prefix } role_assignments AS ra ,
{ $CFG -> prefix } role_capabilities AS rc ,
{ $CFG -> prefix } context AS c1
2006-08-08 05:13:06 +00:00
WHERE
2006-08-10 08:21:29 +00:00
ra . contextid = c1 . id AND
ra . roleid = rc . roleid AND
2006-08-08 05:13:06 +00:00
ra . userid = $userid AND
2006-08-31 04:17:51 +00:00
$searchcontexts1
2006-08-08 05:13:06 +00:00
rc . contextid = $siteinstance -> id
2006-08-09 13:14:15 +00:00
$capsearch
2006-08-08 05:13:06 +00:00
GROUP BY
2006-08-22 16:18:11 +00:00
rc . capability , aggrlevel , c1 . id
2006-08-08 05:13:06 +00:00
HAVING
2006-08-09 14:16:13 +00:00
SUM ( rc . permission ) != 0
2006-08-08 05:13:06 +00:00
UNION
2006-08-22 16:18:11 +00:00
SELECT rc . capability , c1 . id , ( c1 . aggregatelevel * 100 + c2 . aggregatelevel ) AS aggrlevel ,
2006-08-08 05:13:06 +00:00
SUM ( rc . permission ) AS sum
FROM
2006-08-10 08:21:29 +00:00
{ $CFG -> prefix } role_assignments AS ra ,
{ $CFG -> prefix } role_capabilities AS rc ,
{ $CFG -> prefix } context AS c1 ,
{ $CFG -> prefix } context AS c2
2006-08-08 05:13:06 +00:00
WHERE
2006-08-10 08:21:29 +00:00
ra . contextid = c1 . id AND
ra . roleid = rc . roleid AND
ra . userid = $userid AND
rc . contextid = c2 . id AND
2006-08-31 04:17:51 +00:00
$searchcontexts1
$searchcontexts2
rc . contextid != $siteinstance -> id
2006-08-08 05:13:06 +00:00
$capsearch
GROUP BY
2006-08-22 16:18:11 +00:00
rc . capability , aggrlevel , c1 . id
2006-08-08 05:13:06 +00:00
HAVING
2006-08-09 14:16:13 +00:00
SUM ( rc . permission ) != 0
2006-08-08 05:13:06 +00:00
ORDER BY
2006-08-22 16:18:11 +00:00
aggrlevel ASC
2006-08-08 05:13:06 +00:00
" ;
2006-08-09 13:14:15 +00:00
$capabilities = array (); // Reinitialize.
2006-08-22 16:18:11 +00:00
if ( ! $rs = get_recordset_sql ( $SQL )) {
error ( " Query failed in load_user_capability. " );
}
2006-08-22 09:04:23 +00:00
2006-08-08 05:13:06 +00:00
if ( $rs && $rs -> RecordCount () > 0 ) {
while ( ! $rs -> EOF ) {
2006-08-22 16:18:11 +00:00
$array = $rs -> fields ;
$temprecord = new object ;
2006-08-09 13:14:15 +00:00
foreach ( $array as $key => $val ) {
2006-08-22 16:18:11 +00:00
if ( $key == 'aggrlevel' ) {
$temprecord -> aggregatelevel = $val ;
} else {
$temprecord -> { $key } = $val ;
}
2006-08-09 13:14:15 +00:00
}
2006-08-08 05:13:06 +00:00
$capabilities [] = $temprecord ;
$rs -> MoveNext ();
}
}
2006-08-21 05:19:16 +00:00
2006-08-08 05:13:06 +00:00
/* so up to this point we should have somethign like this
2006-08-09 14:16:13 +00:00
* $capabilities [ 1 ] -> aggregatelevel = 1000
2006-08-08 05:13:06 +00:00
-> module = SITEID
-> capability = do_anything
-> id = 1 ( id is the context id )
-> sum = 0
2006-08-09 14:16:13 +00:00
* $capabilities [ 2 ] -> aggregatelevel = 1000
2006-08-08 05:13:06 +00:00
-> module = SITEID
-> capability = post_messages
-> id = 1
-> sum = - 9000
2006-08-09 14:16:13 +00:00
* $capabilittes [ 3 ] -> aggregatelevel = 3000
2006-08-08 05:13:06 +00:00
-> module = course
-> capability = view_course_activities
-> id = 25
-> sum = 1
2006-08-09 14:16:13 +00:00
* $capabilittes [ 4 ] -> aggregatelevel = 3000
2006-08-08 05:13:06 +00:00
-> module = course
-> capability = view_course_activities
-> id = 26
-> sum = 0 ( this is another course )
2006-08-09 14:16:13 +00:00
* $capabilities [ 5 ] -> aggregatelevel = 3050
2006-08-08 05:13:06 +00:00
-> module = course
-> capability = view_course_activities
-> id = 25 ( override in course 25 )
-> sum = - 1
* ....
* now we proceed to write the session array , going from top to bottom
* at anypoint , we need to go up and check parent to look for prohibit
*/
// print_object($capabilities);
/* This is where we write to the actualy capabilities array
* what we need to do from here on is
* going down the array from lowest level to highest level
* 1 ) recursively check for prohibit ,
* if any , we write prohibit
* else , we write the value
* 2 ) at an override level , we overwrite current level
* if it ' s not set to prohibit already , and if different
* ........ that should be it ........
*/
2006-08-09 13:14:15 +00:00
$usercap = array (); // for other user's capabilities
2006-08-08 05:13:06 +00:00
foreach ( $capabilities as $capability ) {
2006-08-14 05:55:40 +00:00
$context = get_context_instance_by_id ( $capability -> id );
2006-08-09 14:16:13 +00:00
if ( ! empty ( $otheruserid )) { // we are pulling out other user's capabilities, do not write to session
2006-08-09 13:14:15 +00:00
2006-08-14 05:55:40 +00:00
if ( capability_prohibits ( $capability -> capability , $context , $capability -> sum , $usercap )) {
2006-08-09 13:14:15 +00:00
$usercap [ $capability -> id ][ $capability -> capability ] = - 9000 ;
continue ;
}
$usercap [ $capability -> id ][ $capability -> capability ] = $capability -> sum ;
} else {
2006-08-14 05:55:40 +00:00
if ( capability_prohibits ( $capability -> capability , $context , $capability -> sum )) { // if any parent or parent's parent is set to prohibit
2006-08-09 13:14:15 +00:00
$USER -> capabilities [ $capability -> id ][ $capability -> capability ] = - 9000 ;
continue ;
}
// if no parental prohibit set
// just write to session, i am not sure this is correct yet
// since 3050 shows up after 3000, and 3070 shows up after 3050,
// it should be ok just to overwrite like this, provided that there's no
// parental prohibits
// no point writing 0, since 0 = inherit
// we need to write even if it's 0, because it could be an inherit override
$USER -> capabilities [ $capability -> id ][ $capability -> capability ] = $capability -> sum ;
}
2006-08-08 05:13:06 +00:00
}
// now we don't care about the huge array anymore, we can dispose it.
unset ( $capabilities );
2006-08-09 14:16:13 +00:00
if ( ! empty ( $otheruseid )) {
2006-08-09 13:14:15 +00:00
return $usercap ; // return the array
2006-08-08 05:13:06 +00:00
}
// see array in session to see what it looks like
}
/**
* This is a recursive function that checks whether the capability in this
* context , or the parent capabilities are set to prohibit .
*
* At this point , we can probably just use the values already set in the
* session variable , since we are going down the level . Any prohit set in
* parents would already reflect in the session .
*
* @ param $capability - capability name
* @ param $sum - sum of all capabilities values
2006-08-14 05:55:40 +00:00
* @ param $context - the context object
2006-08-08 05:13:06 +00:00
* @ param $array - when loading another user caps , their caps are not stored in session but an array
*/
2006-08-14 05:55:40 +00:00
function capability_prohibits ( $capability , $context , $sum = '' , $array = '' ) {
2006-08-08 05:13:06 +00:00
global $USER ;
2006-08-14 05:55:40 +00:00
2006-08-08 05:13:06 +00:00
if ( $sum < - 8000 ) {
// If this capability is set to prohibit.
return true ;
}
if ( isset ( $array )) {
2006-08-14 05:55:40 +00:00
if ( isset ( $array [ $context -> id ][ $capability ])
&& $array [ $context -> id ][ $capability ] < - 8000 ) {
2006-08-09 13:14:15 +00:00
return true ;
}
2006-08-08 05:13:06 +00:00
} else {
2006-08-09 13:14:15 +00:00
// Else if set in session.
2006-08-14 05:55:40 +00:00
if ( isset ( $USER -> capabilities [ $context -> id ][ $capability ])
&& $USER -> capabilities [ $context -> id ][ $capability ] < - 8000 ) {
2006-08-09 13:14:15 +00:00
return true ;
}
2006-08-08 05:13:06 +00:00
}
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-08 05:13:06 +00:00
case CONTEXT_SYSTEM :
// By now it's a definite an inherit.
return 0 ;
break ;
case CONTEXT_PERSONAL :
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_USERID :
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSECAT :
// Coursecat -> coursecat or site.
$coursecat = get_record ( 'course_categories' , 'id' , $context -> instanceid );
2006-08-09 14:16:13 +00:00
if ( ! empty ( $coursecat -> parent )) {
2006-08-08 05:13:06 +00:00
// return parent value if exist.
$parent = get_context_instance ( CONTEXT_COURSECAT , $coursecat -> parent );
} else {
// Return site value.
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
}
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSE :
// 1 to 1 to course cat.
// Find the course cat, and return its value.
$course = get_record ( 'course' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSECAT , $course -> category );
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_GROUP :
// 1 to 1 to course.
$group = get_record ( 'groups' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $group -> courseid );
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_MODULE :
// 1 to 1 to course.
$cm = get_record ( 'course_modules' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $cm -> course );
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_BLOCK :
// 1 to 1 to course.
$block = get_record ( 'block_instance' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $block -> pageid ); // needs check
2006-08-14 05:55:40 +00:00
return capability_prohibits ( $capability , $parent );
2006-08-08 05:13:06 +00:00
break ;
default :
error ( 'This is an unknown context!' );
return false ;
}
}
/**
* A print form function . This should either grab all the capabilities from
* files or a central table for that particular module instance , then present
* them in check boxes . Only relevant capabilities should print for known
* context .
* @ param $mod - module id of the mod
*/
function print_capabilities ( $modid = 0 ) {
global $CFG ;
$capabilities = array ();
if ( $modid ) {
// We are in a module specific context.
// Get the mod's name.
// Call the function that grabs the file and parse.
$cm = get_record ( 'course_modules' , 'id' , $modid );
$module = get_record ( 'modules' , 'id' , $cm -> module );
} else {
// Print all capabilities.
foreach ( $capabilities as $capability ) {
// Prints the check box component.
}
}
}
/**
2006-08-11 02:44:02 +00:00
* Installs the roles system .
* This function runs on a fresh install as well as on an upgrade from the old
* hard - coded student / teacher / admin etc . roles to the new roles system .
2006-08-08 05:13:06 +00:00
*/
2006-08-11 02:44:02 +00:00
function moodle_install_roles () {
2006-08-08 05:13:06 +00:00
2006-08-11 02:44:02 +00:00
global $CFG , $db ;
2006-08-08 05:13:06 +00:00
// Create a system wide context for assignemnt.
$systemcontext = $context = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-11 02:44:02 +00:00
// Create default/legacy roles and capabilities.
// (1 legacy capability per legacy role at system level).
2006-08-08 05:13:06 +00:00
$adminrole = create_role ( get_string ( 'administrator' ), get_string ( 'administratordescription' ), 'moodle/legacy:admin' );
2006-08-09 13:14:15 +00:00
if ( ! assign_capability ( 'moodle/site:doanything' , CAP_ALLOW , $adminrole , $systemcontext -> id )) {
2006-08-08 05:13:06 +00:00
error ( 'Could not assign moodle/site:doanything to the admin role' );
}
$coursecreatorrole = create_role ( get_string ( 'coursecreators' ), get_string ( 'coursecreatorsdescription' ), 'moodle/legacy:coursecreator' );
2006-08-09 13:14:15 +00:00
$noneditteacherrole = create_role ( get_string ( 'noneditingteacher' ), get_string ( 'noneditingteacherdescription' ), 'moodle/legacy:teacher' );
$editteacherrole = create_role ( get_string ( 'defaultcourseteacher' ), get_string ( 'defaultcourseteacherdescription' ), 'moodle/legacy:editingteacher' );
$studentrole = create_role ( get_string ( 'defaultcoursestudent' ), get_string ( 'defaultcoursestudentdescription' ), 'moodle/legacy:student' );
2006-08-08 05:13:06 +00:00
$guestrole = create_role ( get_string ( 'guest' ), get_string ( 'guestdescription' ), 'moodle/legacy:guest' );
2006-08-11 02:44:02 +00:00
// Look inside user_admin, user_creator, user_teachers, user_students and
// assign above new roles. If a user has both teacher and student role,
// only teacher role is assigned. The assignment should be system level.
$dbtables = $db -> MetaTables ( 'TABLES' );
2006-08-08 05:13:06 +00:00
2006-08-11 02:44:02 +00:00
2006-08-09 13:14:15 +00:00
/**
2006-08-08 05:13:06 +00:00
* Upgrade the admins .
2006-08-11 02:44:02 +00:00
* Sort using id ASC , first one is primary admin .
2006-08-08 05:13:06 +00:00
*/
2006-08-11 02:44:02 +00:00
if ( in_array ( $CFG -> prefix . 'user_admins' , $dbtables )) {
if ( $useradmins = get_records_sql ( 'SELECT * from ' . $CFG -> prefix . 'user_admins ORDER BY ID ASC' )) {
foreach ( $useradmins as $admin ) {
role_assign ( $adminrole , $admin -> userid , 0 , $systemcontext -> id );
}
}
} else {
// This is a fresh install.
2006-08-08 05:13:06 +00:00
}
2006-08-11 02:44:02 +00:00
2006-08-08 05:13:06 +00:00
/**
* Upgrade course creators .
*/
2006-08-11 02:44:02 +00:00
if ( in_array ( $CFG -> prefix . 'user_coursecreators' , $dbtables )) {
if ( $usercoursecreators = get_records ( 'user_coursecreators' )) {
foreach ( $usercoursecreators as $coursecreator ) {
role_assign ( $$coursecreatorrole , $coursecreator -> userid , 0 , $systemcontext -> id );
}
}
2006-08-08 05:13:06 +00:00
}
2006-08-11 02:44:02 +00:00
2006-08-08 05:13:06 +00:00
/**
* Upgrade editting teachers and non - editting teachers .
*/
2006-08-11 02:44:02 +00:00
if ( in_array ( $CFG -> prefix . 'user_teachers' , $dbtables )) {
if ( $userteachers = get_records ( 'user_teachers' )) {
foreach ( $userteachers as $teacher ) {
$coursecontext = get_context_instance ( CONTEXT_COURSE , $teacher -> course ); // needs cache
if ( $teacher -> editall ) { // editting teacher
role_assign ( $editteacherrole , $teacher -> userid , 0 , $coursecontext -> id );
} else {
role_assign ( $noneditteacherrole , $teacher -> userid , 0 , $coursecontext -> id );
}
}
2006-08-08 05:13:06 +00:00
}
}
2006-08-11 02:44:02 +00:00
2006-08-08 05:13:06 +00:00
/**
* Upgrade students .
*/
2006-08-11 02:44:02 +00:00
if ( in_array ( $CFG -> prefix . 'user_students' , $dbtables )) {
if ( $userstudents = get_records ( 'user_students' )) {
foreach ( $userstudents as $student ) {
$coursecontext = get_context_instance ( CONTEXT_COURSE , $student -> course );
role_assign ( $studentrole , $student -> userid , 0 , $coursecontext -> id );
}
}
2006-08-08 05:13:06 +00:00
}
2006-08-11 02:44:02 +00:00
2006-08-08 05:13:06 +00:00
/**
* Upgrade guest ( only 1 entry ) .
*/
2006-08-11 02:44:02 +00:00
if ( $guestuser = get_record ( 'user' , 'username' , 'guest' )) {
role_assign ( $guestrole , $guestuser -> id , 0 , $systemcontext -> id );
}
2006-08-23 06:36:08 +00:00
/**
* Insert the correct records for legacy roles
*/
allow_assign ( $adminrole , $adminrole );
allow_assign ( $adminrole , $coursecreatorrole );
allow_assign ( $adminrole , $noneditteacherrole );
allow_assign ( $adminrole , $editteacherrole );
allow_assign ( $adminrole , $studentrole );
allow_assign ( $adminrole , $guestrole );
allow_assign ( $coursecreatorrole , $noneditteacherrole );
allow_assign ( $coursecreatorrole , $editteacherrole );
allow_assign ( $coursecreatorrole , $studentrole );
allow_assign ( $coursecreatorrole , $guestrole );
allow_assign ( $editteacherrole , $noneditteacherrole );
allow_assign ( $editteacherrole , $studentrole );
allow_assign ( $editteacherrole , $guestrole );
/// overrides
allow_override ( $adminrole , $adminrole );
allow_override ( $adminrole , $coursecreatorrole );
allow_override ( $adminrole , $noneditteacherrole );
allow_override ( $adminrole , $editteacherrole );
allow_override ( $adminrole , $studentrole );
2006-08-23 08:14:14 +00:00
allow_override ( $adminrole , $guestrole );
2006-08-11 02:44:02 +00:00
// Should we delete the tables after we are done? Not yet.
2006-08-08 05:13:06 +00:00
}
/**
* Assign the defaults found in this capabality definition to roles that have
* the corresponding legacy capabilities assigned to them .
* @ param $legacyperms - an array in the format ( example ) :
* 'guest' => CAP_PREVENT ,
* 'student' => CAP_ALLOW ,
* 'teacher' => CAP_ALLOW ,
* 'editingteacher' => CAP_ALLOW ,
* 'coursecreator' => CAP_ALLOW ,
* 'admin' => CAP_ALLOW
* @ return boolean - success or failure .
*/
function assign_legacy_capabilities ( $capability , $legacyperms ) {
foreach ( $legacyperms as $type => $perm ) {
$systemcontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
// The legacy capabilities are:
// 'moodle/legacy:guest'
// 'moodle/legacy:student'
// 'moodle/legacy:teacher'
// 'moodle/legacy:editingteacher'
// 'moodle/legacy:coursecreator'
// 'moodle/legacy:admin'
if ( ! $roles = get_roles_with_capability ( 'moodle/legacy:' . $type , CAP_ALLOW )) {
return false ;
}
foreach ( $roles as $role ) {
// Assign a site level capability.
if ( ! assign_capability ( $capability , $perm , $role -> id , $systemcontext -> id )) {
return false ;
}
}
}
return true ;
}
2006-08-14 07:15:03 +00:00
/**
* Checks to see if a capability is a legacy capability .
* @ param $capabilityname
* @ return boolean
*/
2006-08-08 05:13:06 +00:00
function islegacy ( $capabilityname ) {
2006-08-09 13:14:15 +00:00
if ( strstr ( $capabilityname , 'legacy' ) === false ) {
return false ;
} else {
return true ;
}
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
/**********************************
2006-08-08 05:13:06 +00:00
* Context Manipulation functions *
**********************************/
/**
* This should be called prolly everytime a user , group , module , course ,
* coursecat or site is set up maybe ?
* @ param $level
* @ param $instanceid
*/
2006-08-21 05:19:16 +00:00
function create_context ( $aggregatelevel , $instanceid ) {
if ( ! get_record ( 'context' , 'aggregatelevel' , $aggregatelevel , 'instanceid' , $instanceid )) {
2006-08-08 05:13:06 +00:00
$context = new object ;
2006-08-21 05:19:16 +00:00
$context -> aggregatelevel = $aggregatelevel ;
2006-08-08 05:13:06 +00:00
$context -> instanceid = $instanceid ;
return insert_record ( 'context' , $context );
}
}
/**
* Get the context instance as an object . This function will create the
* context instance if it does not exist yet .
* @ param $level
* @ param $instance
*/
2006-08-21 05:19:16 +00:00
function get_context_instance ( $aggregatelevel = NULL , $instance = SITEID ) {
2006-08-13 13:28:01 +00:00
2006-08-25 14:15:52 +00:00
global $context_cache , $context_cache_id , $CONTEXT ;
2006-08-23 01:29:52 +00:00
2006-08-13 15:48:57 +00:00
/// If no level is supplied then return the current global context if there is one
2006-08-21 05:19:16 +00:00
if ( empty ( $aggregatelevel )) {
2006-08-13 15:48:57 +00:00
if ( empty ( $CONTEXT )) {
if ( $CFG -> debug > 7 ) {
notify ( " Error: get_context_instance() called without a context " );
}
} else {
return $CONTEXT ;
}
2006-08-13 13:28:01 +00:00
}
2006-08-13 15:48:57 +00:00
/// Check the cache
2006-08-21 05:19:16 +00:00
if ( isset ( $context_cache [ $aggregatelevel ][ $instance ])) { // Already cached
return $context_cache [ $aggregatelevel ][ $instance ];
2006-08-13 13:28:01 +00:00
}
2006-08-13 15:48:57 +00:00
/// Get it from the database, or create it
2006-08-21 05:19:16 +00:00
if ( ! $context = get_record ( 'context' , 'aggregatelevel' , $aggregatelevel , 'instanceid' , $instance )) {
create_context ( $aggregatelevel , $instance );
$context = get_record ( 'context' , 'aggregatelevel' , $aggregatelevel , 'instanceid' , $instance );
2006-08-13 13:28:01 +00:00
}
2006-08-13 15:48:57 +00:00
/// Update the cache
2006-08-21 05:19:16 +00:00
$context_cache [ $aggregatelevel ][ $instance ] = $context ; // Cache it for later
2006-08-13 15:48:57 +00:00
$context_cache_id [ $context -> id ] = $context ; // Cache it for later
2006-08-13 13:28:01 +00:00
2006-08-14 05:55:40 +00:00
2006-08-08 05:13:06 +00:00
return $context ;
}
2006-08-14 07:15:03 +00:00
2006-08-13 15:48:57 +00:00
/**
* Get a context instance as an object , from a given id .
* @ param $id
*/
function get_context_instance_by_id ( $id ) {
2006-08-23 01:29:52 +00:00
global $context_cache , $context_cache_id ;
2006-08-13 15:48:57 +00:00
if ( isset ( $context_cache_id [ $id ])) { // Already cached
2006-08-22 16:18:11 +00:00
return $context_cache_id [ $id ];
2006-08-13 15:48:57 +00:00
}
if ( $context = get_record ( 'context' , 'id' , $id )) { // Update the cache and return
2006-08-21 05:19:16 +00:00
$context_cache [ $context -> aggregatelevel ][ $context -> instanceid ] = $context ;
2006-08-13 15:48:57 +00:00
$context_cache_id [ $context -> id ] = $context ;
return $context ;
}
return false ;
}
2006-08-08 05:13:06 +00:00
2006-08-13 09:25:45 +00:00
/**
* Get the local override ( if any ) for a given capability in a role in a context
* @ param $roleid
2006-08-14 05:55:40 +00:00
* @ param $contextid
* @ param $capability
2006-08-13 09:25:45 +00:00
*/
function get_local_override ( $roleid , $contextid , $capability ) {
return get_record ( 'role_capabilities' , 'roleid' , $roleid , 'capability' , $capability , 'contextid' , $contextid );
}
2006-08-08 05:13:06 +00:00
/************************************
* DB TABLE RELATED FUNCTIONS *
************************************/
2006-08-14 07:15:03 +00:00
/**
2006-08-08 05:13:06 +00:00
* function that creates a role
* @ param name - role name
* @ param description - role description
* @ param legacy - optional legacy capability
* @ return id or false
*/
function create_role ( $name , $description , $legacy = '' ) {
2006-08-09 13:14:15 +00:00
// check for duplicate role name
if ( $role = get_record ( 'role' , 'name' , $name )) {
error ( 'there is already a role with this name!' );
}
$role -> name = $name ;
$role -> description = $description ;
if ( $id = insert_record ( 'role' , $role )) {
2006-08-11 02:44:02 +00:00
if ( $legacy ) {
$context = get_context_instance ( CONTEXT_SYSTEM , SITEID );
assign_capability ( $legacy , CAP_ALLOW , $id , $context -> id );
2006-08-09 13:14:15 +00:00
}
return $id ;
} else {
return false ;
}
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
2006-08-08 05:13:06 +00:00
/**
* Function to write context specific overrides , or default capabilities .
* @ param module - string name
* @ param capability - string name
* @ param contextid - context id
* @ param roleid - role id
* @ param permission - int 1 , - 1 or - 1000
*/
function assign_capability ( $capability , $permission , $roleid , $contextid ) {
2006-08-09 13:14:15 +00:00
global $USER ;
if ( empty ( $permission ) || $permission == 0 ) { // if permission is not set
unassign_capability ( $capability , $roleid , $contextid );
}
2006-08-08 05:13:06 +00:00
$cap = new object ;
$cap -> contextid = $contextid ;
$cap -> roleid = $roleid ;
$cap -> capability = $capability ;
$cap -> permission = $permission ;
$cap -> timemodified = time ();
2006-08-14 13:42:34 +00:00
$cap -> modifierid = empty ( $USER -> id ) ? 0 : $USER -> id ;
2006-08-08 05:13:06 +00:00
return insert_record ( 'role_capabilities' , $cap );
}
/**
* Unassign a capability from a role .
* @ param $roleid - the role id
* @ param $capability - the name of the capability
* @ return boolean - success or failure
*/
function unassign_capability ( $capability , $roleid , $contextid = NULL ) {
2006-08-09 13:14:15 +00:00
if ( isset ( $contextid )) {
$status = delete_records ( 'role_capabilities' , 'capability' , $capability ,
'roleid' , $roleid , 'contextid' , $contextid );
} else {
$status = delete_records ( 'role_capabilities' , 'capability' , $capability ,
'roleid' , $roleid );
}
return $status ;
2006-08-08 05:13:06 +00:00
}
/**
* Get the roles that have a given capability .
* @ param $capability - capability name ( string )
* @ param $permission - optional , the permission defined for this capability
* either CAP_ALLOW , CAP_PREVENT or CAP_PROHIBIT
* @ return array or role objects
*/
function get_roles_with_capability ( $capability , $permission = NULL ) {
global $CFG ;
$selectroles = " SELECT r.*
FROM { $CFG -> prefix } role AS r ,
{ $CFG -> prefix } role_capabilities AS rc
WHERE rc . capability = '$capability'
AND rc . roleid = r . id " ;
if ( isset ( $permission )) {
$selectroles .= " AND rc.permission = ' $permission ' " ;
}
return get_records_sql ( $selectroles );
}
/**
2006-08-31 07:40:48 +00:00
* This function makes a role - assignment ( a role for a user or group in a particular context )
2006-08-08 05:13:06 +00:00
* @ param $roleid - the role of the id
* @ param $userid - userid
* @ param $groupid - group id
* @ param $contextid - id of the context
* @ param $timestart - time this assignment becomes effective
* @ param $timeend - time this assignemnt ceases to be effective
* @ uses $USER
* @ return id - new id of the assigment
*/
2006-08-31 07:58:53 +00:00
function role_assign ( $roleid , $userid , $groupid , $contextid , $timestart = 0 , $timeend = 0 , $hidden = 0 , $enrol = 'manual' ) {
2006-08-09 05:37:31 +00:00
global $USER , $CFG ;
2006-08-08 05:13:06 +00:00
2006-08-14 08:26:58 +00:00
if ( $CFG -> debug > 7 ) {
2006-08-09 13:14:15 +00:00
notify ( " Assign roleid $roleid userid $userid contextid $contextid " , 'notifytiny' );
2006-08-09 05:37:31 +00:00
}
2006-08-08 05:13:06 +00:00
2006-08-31 07:40:48 +00:00
/// Do some data validation
2006-08-08 05:13:06 +00:00
if ( empty ( $roleid )) {
2006-08-31 07:40:48 +00:00
notify ( 'Role ID not provided' );
return false ;
2006-08-08 05:13:06 +00:00
}
if ( empty ( $userid ) && empty ( $groupid )) {
2006-08-31 07:40:48 +00:00
notify ( 'Either userid or groupid must be provided' );
return false ;
2006-08-08 05:13:06 +00:00
}
if ( empty ( $contextid )) {
2006-08-31 07:40:48 +00:00
notify ( 'A valid context must be provided' );
return false ;
2006-08-08 05:13:06 +00:00
}
2006-08-31 07:40:48 +00:00
if (( $timestart and $timeend ) and ( $timestart > $timeend )) {
notify ( 'The end time must be later than the start time' );
return false ;
}
/// Check for existing entry
if ( $userid ) {
$ra = get_record ( 'role_assignments' , 'roleid' , $roleid , 'contextid' , $contextid , 'userid' , $userid );
} else {
$ra = get_record ( 'role_assignments' , 'roleid' , $roleid , 'contextid' , $contextid , 'groupid' , $groupid );
}
$newra = new object ;
2006-08-08 05:13:06 +00:00
2006-08-31 07:40:48 +00:00
if ( empty ( $ra )) { // Create a new entry
$newra -> roleid = $roleid ;
$newra -> contextid = $contextid ;
$newra -> userid = $userid ;
$newra -> groupid = $groupid ;
$newra -> hidden = $hidden ;
2006-08-31 07:58:53 +00:00
$newra -> enrol = $enrol ;
2006-08-31 07:40:48 +00:00
$newra -> timestart = $timestart ;
$newra -> timeend = $timeend ;
$newra -> timemodified = time ();
$newra -> modifier = empty ( $USER -> id ) ? 0 : $USER -> id ;
return insert_record ( 'role_assignments' , $newra );
} else { // We already have one, just update it
$newra -> id = $ra -> id ;
$newra -> hidden = $hidden ;
2006-08-31 07:58:53 +00:00
$newra -> enrol = $enrol ;
2006-08-31 07:40:48 +00:00
$newra -> timestart = $timestart ;
$newra -> timeend = $timeend ;
$newra -> timemodified = time ();
$newra -> modifier = empty ( $USER -> id ) ? 0 : $USER -> id ;
return update_record ( 'role_assignments' , $newra );
}
2006-08-08 05:13:06 +00:00
}
/**
* Deletes a role assignment .
* @ param $roleid
* @ param $userid
* @ param $groupid
* @ param $contextid
* @ return boolean - success or failure
*/
function role_unassign ( $roleid , $userid , $groupid , $contextid ) {
2006-08-31 08:30:28 +00:00
if ( $groupid && empty ( $userid )) {
return delete_records ( 'role_assignments' , 'groupid' , $groupid , 'roleid' , $roleid , 'contextid' , $contextid );
} else {
return delete_records ( 'role_assignments' , 'userid' , $userid , 'roleid' , $roleid , 'contextid' , $contextid );
2006-08-09 13:14:15 +00:00
}
2006-08-08 05:13:06 +00:00
}
/**
* Loads the capability definitions for the component ( from file ) . If no
* capabilities are defined for the component , we simply return an empty array .
* @ param $component - examples : 'moodle' , 'mod/forum' , 'block/quiz_results'
* @ return array of capabilities
*/
function load_capability_def ( $component ) {
global $CFG ;
if ( $component == 'moodle' ) {
$defpath = $CFG -> libdir . '/db/access.php' ;
$varprefix = 'moodle' ;
} else {
$defpath = $CFG -> dirroot . '/' . $component . '/db/access.php' ;
$varprefix = str_replace ( '/' , '_' , $component );
}
$capabilities = array ();
if ( file_exists ( $defpath )) {
require_once ( $defpath );
$capabilities = $ { $varprefix . '_capabilities' };
}
return $capabilities ;
}
/**
* Gets the capabilities that have been cached in the database for this
* component .
* @ param $component - examples : 'moodle' , 'mod/forum' , 'block/quiz_results'
* @ return array of capabilities
*/
function get_cached_capabilities ( $component = 'moodle' ) {
if ( $component == 'moodle' ) {
$storedcaps = get_records_select ( 'capabilities' ,
" name LIKE 'moodle/%:%' " );
} else {
$storedcaps = get_records_select ( 'capabilities' ,
" name LIKE ' $component :%' " );
}
return $storedcaps ;
}
/**
* Updates the capabilities table with the component capability definitions .
* If no parameters are given , the function updates the core moodle
* capabilities .
*
* Note that the absence of the db / access . php capabilities definition file
* will cause any stored capabilities for the component to be removed from
* the database .
*
* @ param $component - examples : 'moodle' , 'mod/forum' , 'block/quiz_results'
* @ return boolean
*/
function update_capabilities ( $component = 'moodle' ) {
$storedcaps = array ();
2006-08-31 08:36:36 +00:00
$filecaps = load_capability_def ( $component );
2006-08-08 05:13:06 +00:00
$cachedcaps = get_cached_capabilities ( $component );
if ( $cachedcaps ) {
foreach ( $cachedcaps as $cachedcap ) {
array_push ( $storedcaps , $cachedcap -> name );
2006-08-31 08:36:36 +00:00
// update risk bitmasks in existing capabilitites if needed
if ( array_key_exists ( $cachedcap -> name , $filecaps )) {
if ( ! array_key_exists ( 'riskbitmask' , $filecaps [ $cachedcap -> name ])) {
$filecaps [ $cachedcap -> name ][ 'riskbitmask' ] = 0 ; // no risk by default
}
if ( $cachedcap -> riskbitmask != $filecaps [ $cachedcap -> name ][ 'riskbitmask' ]) {
$updatecap = new object ;
$updatecap -> id = $cachedcap -> id ;
$updatecap -> riskbitmask = $filecaps [ $cachedcap -> name ][ 'riskbitmask' ];
if ( ! update_record ( 'capabilities' , $updatecap )) {
return false ;
}
}
}
2006-08-08 05:13:06 +00:00
}
}
2006-08-31 08:36:36 +00:00
2006-08-08 05:13:06 +00:00
// Are there new capabilities in the file definition?
$newcaps = array ();
foreach ( $filecaps as $filecap => $def ) {
if ( ! $storedcaps ||
( $storedcaps && in_array ( $filecap , $storedcaps ) === false )) {
$newcaps [ $filecap ] = $def ;
}
}
// Add new capabilities to the stored definition.
foreach ( $newcaps as $capname => $capdef ) {
$capability = new object ;
$capability -> name = $capname ;
$capability -> captype = $capdef [ 'captype' ];
$capability -> contextlevel = $capdef [ 'contextlevel' ];
$capability -> component = $component ;
2006-08-31 08:36:36 +00:00
$capability -> riskbitmask = $capdef [ 'riskbitmask' ];
2006-08-08 05:13:06 +00:00
if ( ! insert_record ( 'capabilities' , $capability , false , 'id' )) {
return false ;
}
// Do we need to assign the new capabilities to roles that have the
// legacy capabilities moodle/legacy:* as well?
if ( isset ( $capdef [ 'legacy' ]) && is_array ( $capdef [ 'legacy' ]) &&
! assign_legacy_capabilities ( $capname , $capdef [ 'legacy' ])) {
error ( 'Could not assign legacy capabilities' );
return false ;
}
}
// Are there any capabilities that have been removed from the file
// definition that we need to delete from the stored capabilities and
// role assignments?
capabilities_cleanup ( $component , $filecaps );
return true ;
}
/**
* Deletes cached capabilities that are no longer needed by the component .
* Also unassigns these capabilities from any roles that have them .
* @ param $component - examples : 'moodle' , 'mod/forum' , 'block/quiz_results'
* @ param $newcapdef - array of the new capability definitions that will be
* compared with the cached capabilities
* @ return int - number of deprecated capabilities that have been removed
*/
function capabilities_cleanup ( $component , $newcapdef = NULL ) {
$removedcount = 0 ;
if ( $cachedcaps = get_cached_capabilities ( $component )) {
foreach ( $cachedcaps as $cachedcap ) {
if ( empty ( $newcapdef ) ||
array_key_exists ( $cachedcap -> name , $newcapdef ) === false ) {
// Remove from capabilities cache.
if ( ! delete_records ( 'capabilities' , 'name' , $cachedcap -> name )) {
error ( 'Could not delete deprecated capability ' . $cachedcap -> name );
} else {
$removedcount ++ ;
}
// Delete from roles.
if ( $roles = get_roles_with_capability ( $cachedcap -> name )) {
foreach ( $roles as $role ) {
if ( ! unassign_capability ( $role -> id , $cachedcap -> name )) {
error ( 'Could not unassign deprecated capability ' .
$cachedcap -> name . ' from role ' . $role -> name );
}
}
}
} // End if.
}
}
return $removedcount ;
}
2006-08-14 07:15:03 +00:00
/****************
* UI FUNCTIONS *
****************/
2006-08-08 05:13:06 +00:00
/**
* prints human readable context identifier .
*/
2006-08-14 05:55:40 +00:00
function print_context_name ( $context ) {
2006-08-13 15:48:57 +00:00
2006-08-09 04:51:05 +00:00
$name = '' ;
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-09 04:51:05 +00:00
2006-08-08 05:13:06 +00:00
case CONTEXT_SYSTEM : // by now it's a definite an inherit
2006-08-09 04:51:05 +00:00
$name = get_string ( 'site' );
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_PERSONAL :
2006-08-09 04:51:05 +00:00
$name = get_string ( 'personal' );
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_USERID :
2006-08-09 04:51:05 +00:00
if ( $user = get_record ( 'user' , 'id' , $context -> instanceid )) {
$name = get_string ( 'user' ) . ': ' . fullname ( $user );
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_COURSECAT : // Coursecat -> coursecat or site
2006-08-09 04:51:05 +00:00
if ( $category = get_record ( 'course_categories' , 'id' , $context -> instanceid )) {
$name = get_string ( 'category' ) . ': ' . $category -> name ;
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_COURSE : // 1 to 1 to course cat
2006-08-09 04:51:05 +00:00
if ( $course = get_record ( 'course' , 'id' , $context -> instanceid )) {
$name = get_string ( 'course' ) . ': ' . $course -> fullname ;
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_GROUP : // 1 to 1 to course
2006-08-09 04:51:05 +00:00
if ( $group = get_record ( 'groups' , 'id' , $context -> instanceid )) {
$name = get_string ( 'group' ) . ': ' . $group -> name ;
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_MODULE : // 1 to 1 to course
2006-08-09 13:14:15 +00:00
if ( $cm = get_record ( 'course_modules' , 'id' , $context -> instanceid )) {
if ( $module = get_record ( 'modules' , 'id' , $cm -> module )) {
if ( $mod = get_record ( $module -> name , 'id' , $cm -> instance )) {
2006-08-09 04:51:05 +00:00
$name = get_string ( 'activitymodule' ) . ': ' . $mod -> name ;
2006-08-09 13:14:15 +00:00
}
2006-08-09 04:51:05 +00:00
}
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
case CONTEXT_BLOCK : // 1 to 1 to course
2006-08-09 13:14:15 +00:00
if ( $blockinstance = get_record ( 'block_instance' , 'id' , $context -> instanceid )) {
if ( $block = get_record ( 'block' , 'id' , $blockinstance -> blockid )) {
2006-08-09 04:51:05 +00:00
$name = get_string ( 'blocks' ) . ': ' . get_string ( $block -> name , 'block_' . $block -> name );
}
}
2006-08-13 15:48:57 +00:00
break ;
2006-08-08 05:13:06 +00:00
default :
error ( 'This is an unknown context!' );
2006-08-13 15:48:57 +00:00
return false ;
}
return $name ;
2006-08-08 05:13:06 +00:00
}
/**
* Extracts the relevant capabilities given a contextid .
* All case based , example an instance of forum context .
* Will fetch all forum related capabilities , while course contexts
* Will fetch all capabilities
2006-08-14 05:55:40 +00:00
* @ param object context
2006-08-08 05:13:06 +00:00
* @ return array ();
*
* capabilities
* `name` varchar ( 150 ) NOT NULL ,
* `captype` varchar ( 50 ) NOT NULL ,
* `contextlevel` int ( 10 ) NOT NULL ,
* `component` varchar ( 100 ) NOT NULL ,
*/
2006-08-14 05:55:40 +00:00
function fetch_context_capabilities ( $context ) {
2006-08-09 13:14:15 +00:00
global $CFG ;
2006-08-08 05:13:06 +00:00
$sort = 'ORDER BY contextlevel,component,id' ; // To group them sensibly for display
2006-08-09 13:14:15 +00:00
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
case CONTEXT_SYSTEM : // all
$SQL = " select * from { $CFG -> prefix } capabilities " ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_PERSONAL :
2006-08-15 08:29:29 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities where contextlevel = " . CONTEXT_PERSONAL ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_USERID :
2006-08-15 08:29:29 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities where contextlevel = " . CONTEXT_USERID ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSECAT : // all
2006-08-09 13:14:15 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities " ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSE : // all
2006-08-09 13:14:15 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities " ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_GROUP : // group caps
break ;
case CONTEXT_MODULE : // mod caps
2006-08-09 13:14:15 +00:00
$cm = get_record ( 'course_modules' , 'id' , $context -> instanceid );
$module = get_record ( 'modules' , 'id' , $cm -> module );
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities where contextlevel = " . CONTEXT_MODULE . "
and component = 'mod/$module->name' " ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_BLOCK : // block caps
2006-08-09 13:14:15 +00:00
$cb = get_record ( 'block_instance' , 'id' , $context -> instanceid );
$block = get_record ( 'block' , 'id' , $cb -> blockid );
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
$SQL = " select * from { $CFG -> prefix } capabilities where contextlevel = " . CONTEXT_BLOCK . "
and component = 'block/$block->name' " ;
2006-08-08 05:13:06 +00:00
break ;
default :
return false ;
}
$records = get_records_sql ( $SQL . ' ' . $sort );
return $records ;
}
/**
* This function pulls out all the resolved capabilities ( overrides and
* defaults ) of a role used in capability overrieds in contexts at a given
* context .
2006-08-15 08:29:29 +00:00
* @ param obj $context
2006-08-08 05:13:06 +00:00
* @ param int $roleid
* @ return array
*/
2006-08-28 08:42:30 +00:00
function role_context_capabilities ( $roleid , $context , $cap = '' ) {
2006-08-09 13:14:15 +00:00
global $CFG ;
$sitecontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
2006-08-14 05:55:40 +00:00
if ( $sitecontext -> id == $context -> id ) {
2006-08-09 13:14:15 +00:00
return array ();
}
// first of all, figure out all parental contexts
$contexts = array_reverse ( get_parent_contexts ( $context ));
$contexts = '(' . implode ( ',' , $contexts ) . ')' ;
2006-08-28 08:42:30 +00:00
if ( $cap ) {
$search = ' AND rc.capability = "' . $cap . '" ' ;
} else {
$search = '' ;
}
2006-08-09 13:14:15 +00:00
$SQL = " SELECT rc.* FROM { $CFG -> prefix } role_capabilities rc, { $CFG -> prefix } context c
where rc . contextid in $contexts
and rc . roleid = $roleid
2006-08-28 08:42:30 +00:00
and rc . contextid = c . id $search
2006-08-21 05:19:16 +00:00
ORDER BY c . aggregatelevel DESC , rc . capability DESC " ;
2006-08-28 08:42:30 +00:00
2006-08-09 13:14:15 +00:00
$records = get_records_sql ( $SQL );
$capabilities = array ();
// We are traversing via reverse order.
foreach ( $records as $record ) {
// If not set yet (i.e. inherit or not set at all), or currently we have a prohibit
if ( ! isset ( $capabilities [ $record -> capability ]) || $record -> permission <- 500 ) {
$capabilities [ $record -> capability ] = $record -> permission ;
}
}
return $capabilities ;
2006-08-08 05:13:06 +00:00
}
/**
2006-08-14 05:55:40 +00:00
* Recursive function which , given a context , find all parent context ids ,
2006-08-08 05:13:06 +00:00
* and return the array in reverse order , i . e . parent first , then grand
* parent , etc .
* @ param object $context
* @ return array ()
*/
function get_parent_contexts ( $context ) {
2006-08-21 05:19:16 +00:00
switch ( $context -> aggregatelevel ) {
2006-08-08 05:13:06 +00:00
case CONTEXT_SYSTEM : // no parent
2006-08-09 13:14:15 +00:00
return null ;
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_PERSONAL :
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
return array ( $parent -> id );
break ;
case CONTEXT_USERID :
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
return array ( $parent -> id );
break ;
case CONTEXT_COURSECAT : // Coursecat -> coursecat or site
$coursecat = get_record ( 'course_categories' , 'id' , $context -> instanceid );
2006-08-31 05:06:30 +00:00
if ( ! empty ( $coursecat -> parent )) { // return parent value if exist
2006-08-08 05:13:06 +00:00
$parent = get_context_instance ( CONTEXT_COURSECAT , $coursecat -> parent );
return array_merge ( array ( $parent -> id ), get_parent_contexts ( $parent ));
} else { // else return site value
$parent = get_context_instance ( CONTEXT_SYSTEM , SITEID );
return array ( $parent -> id );
}
break ;
case CONTEXT_COURSE : // 1 to 1 to course cat
// find the course cat, and return its value
$course = get_record ( 'course' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSECAT , $course -> category );
return array_merge ( array ( $parent -> id ), get_parent_contexts ( $parent ));
break ;
case CONTEXT_GROUP : // 1 to 1 to course
$group = get_record ( 'groups' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $group -> courseid );
return array_merge ( array ( $parent -> id ), get_parent_contexts ( $parent ));
break ;
case CONTEXT_MODULE : // 1 to 1 to course
$cm = get_record ( 'course_modules' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $cm -> course );
return array_merge ( array ( $parent -> id ), get_parent_contexts ( $parent ));
break ;
case CONTEXT_BLOCK : // 1 to 1 to course
$block = get_record ( 'block_instance' , 'id' , $context -> instanceid );
$parent = get_context_instance ( CONTEXT_COURSE , $block -> pageid ); // needs check
return array_merge ( array ( $parent -> id ), get_parent_contexts ( $parent ));
break ;
default :
error ( 'This is an unknown context!' );
return false ;
}
}
/**
* This function gets the capability of a role in a given context .
* It is needed when printing override forms .
* @ param int $contextid
* @ param string $capability
* @ param array $capabilities - array loaded using role_context_capabilities
* @ return int ( allow , prevent , prohibit , inherit )
*/
function get_role_context_capability ( $contextid , $capability , $capabilities ) {
2006-08-09 13:14:15 +00:00
return $capabilities [ $contextid ][ $capability ];
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
/**
* Returns the human - readable , translated version of the capability .
* Basically a big switch statement .
* @ param $capabilityname - e . g . mod / choice : readresponses
*/
2006-08-13 09:11:45 +00:00
function get_capability_string ( $capabilityname ) {
2006-08-08 05:13:06 +00:00
2006-08-14 07:15:03 +00:00
// Typical capabilityname is mod/choice:readresponses
2006-08-13 09:11:45 +00:00
$names = split ( '/' , $capabilityname );
$stringname = $names [ 1 ]; // choice:readresponses
$components = split ( ':' , $stringname );
$componentname = $components [ 0 ]; // choice
2006-08-09 13:14:15 +00:00
switch ( $names [ 0 ]) {
case 'mod' :
2006-08-13 09:11:45 +00:00
$string = get_string ( $stringname , $componentname );
2006-08-09 13:14:15 +00:00
break ;
case 'block' :
2006-08-13 09:11:45 +00:00
$string = get_string ( $stringname , 'block_' . $componentname );
2006-08-09 13:14:15 +00:00
break ;
2006-08-13 09:11:45 +00:00
2006-08-09 13:14:15 +00:00
case 'moodle' :
2006-08-13 09:11:45 +00:00
$string = get_string ( $stringname , 'role' );
2006-08-09 13:14:15 +00:00
break ;
case 'enrol' :
2006-08-13 09:11:45 +00:00
$string = get_string ( $stringname , 'enrol_' . $componentname );
break ;
2006-08-09 13:14:15 +00:00
default :
2006-08-13 09:11:45 +00:00
$string = get_string ( $stringname );
2006-08-09 13:14:15 +00:00
break ;
}
2006-08-13 09:11:45 +00:00
return $string ;
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
/**
* This gets the mod / block / course / core etc strings .
* @ param $component
* @ param $contextlevel
*/
2006-08-08 05:13:06 +00:00
function get_component_string ( $component , $contextlevel ) {
2006-08-09 13:14:15 +00:00
switch ( $contextlevel ) {
2006-08-08 05:13:06 +00:00
2006-08-09 13:14:15 +00:00
case CONTEXT_SYSTEM :
2006-08-13 09:11:45 +00:00
$string = get_string ( 'coresystem' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_PERSONAL :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'personal' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_USERID :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'users' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSECAT :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'categories' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_COURSE :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'course' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_GROUP :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'group' );
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_MODULE :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'modulename' , basename ( $component ));
2006-08-08 05:13:06 +00:00
break ;
case CONTEXT_BLOCK :
2006-08-09 13:14:15 +00:00
$string = get_string ( 'blockname' , 'block_' . $component . '.php' );
2006-08-08 05:13:06 +00:00
break ;
default :
error ( 'This is an unknown context!' );
return false ;
2006-08-09 13:14:15 +00:00
}
return $string ;
2006-08-08 05:13:06 +00:00
}
2006-08-14 07:15:03 +00:00
2006-08-23 06:36:08 +00:00
/** gets the list of roles assigned to this context
* @ param object $context
* @ return array
*/
2006-08-14 08:14:02 +00:00
function get_roles_used_in_context ( $context ) {
global $CFG ;
return get_records_sql ( ' SELECT distinct r . id , r . name
FROM '.$CFG->prefix.' role_assignments ra ,
'.$CFG->prefix.' role r
WHERE r . id = ra . roleid
AND ra . contextid = '.$context->id.'
ORDER BY r . sortorder ASC ' );
}
2006-08-23 06:36:08 +00:00
/** this function is used to print roles column in user profile page .
* @ param int userid
* @ param int contextid
* @ return string
*/
2006-08-15 08:29:29 +00:00
function get_user_roles_in_context ( $userid , $contextid ){
global $CFG ;
$rolestring = '' ;
$SQL = 'select * from ' . $CFG -> prefix . 'role_assignments ra, ' . $CFG -> prefix . 'role r where ra.userid=' . $userid . ' and ra.contextid=' . $contextid . ' and ra.roleid = r.id' ;
if ( $roles = get_records_sql ( $SQL )) {
foreach ( $roles as $userrole ) {
$rolestring .= '<a href="' . $CFG -> wwwroot . '/user/index.php?contextid=' . $userrole -> contextid . '&roleid=' . $userrole -> roleid . '">' . $userrole -> name . '</a>, ' ;
}
}
return rtrim ( $rolestring , ', ' );
}
2006-08-18 08:01:16 +00:00
2006-08-23 06:36:08 +00:00
/**
* Checks if a user can override capabilities of a particular role in this context
* @ param object $context
* @ param int targetroleid - the id of the role you want to override
* @ return boolean
*/
2006-08-18 08:01:16 +00:00
function user_can_override ( $context , $targetroleid ) {
// first check if user has override capability
// if not return false;
if ( ! has_capability ( 'moodle/role:override' , $context )) {
return false ;
}
// pull out all active roles of this user from this context(or above)
2006-08-19 08:12:45 +00:00
if ( $userroles = get_user_roles ( $context )) {
foreach ( $userroles as $userrole ) {
// if any in the role_allow_override table, then it's ok
if ( get_record ( 'role_allow_override' , 'roleid' , $userrole -> roleid , 'allowoverride' , $targetroleid )) {
return true ;
}
2006-08-18 08:01:16 +00:00
}
}
return false ;
}
2006-08-23 06:36:08 +00:00
/**
* Checks if a user can assign users to a particular role in this context
* @ param object $context
* @ param int targetroleid - the id of the role you want to assign users to
* @ return boolean
*/
2006-08-18 08:01:16 +00:00
function user_can_assign ( $context , $targetroleid ) {
// first check if user has override capability
// if not return false;
if ( ! has_capability ( 'moodle/role:assign' , $context )) {
return false ;
}
// pull out all active roles of this user from this context(or above)
2006-08-19 08:12:45 +00:00
if ( $userroles = get_user_roles ( $context )) {
foreach ( $userroles as $userrole ) {
// if any in the role_allow_override table, then it's ok
if ( get_record ( 'role_allow_assign' , 'roleid' , $userrole -> roleid , 'allowassign' , $targetroleid )) {
return true ;
}
2006-08-18 08:01:16 +00:00
}
}
return false ;
}
2006-08-23 06:36:08 +00:00
/**
* gets all the user roles assigned in this context , or higher contexts
* this is mainly used when checking if a user can assign a role , or overriding a role
* i . e . we need to know what this user holds , in order to verify against allow_assign and
* allow_override tables
* @ param object $context
* @ param int $userid
* @ return array
*/
2006-08-19 08:12:45 +00:00
function get_user_roles ( $context , $userid = 0 ) {
2006-08-18 08:01:16 +00:00
global $USER , $CFG , $db ;
2006-08-19 08:12:45 +00:00
if ( empty ( $userid )) {
if ( empty ( $USER -> id )) {
return array ();
}
$userid = $USER -> id ;
}
if ( $parents = get_parent_contexts ( $context )) {
$contexts = ' AND ra.contextid IN (' . implode ( ',' , $parents ) . ')' ;
} else {
$contexts = ' AND ra.contextid = \'' . $context -> id . '\'' ;
}
2006-08-18 08:01:16 +00:00
return get_records_sql ( ' SELECT *
FROM '.$CFG->prefix.' role_assignments ra
2006-08-19 08:12:45 +00:00
WHERE ra . userid = ' . $userid .
$contexts );
2006-08-18 08:01:16 +00:00
}
2006-08-23 06:36:08 +00:00
/**
* Creates a record in the allow_override table
* @ param int sroleid - source roleid
* @ param int troleid - target roleid
* @ return int - id or false
*/
function allow_override ( $sroleid , $troleid ) {
$record -> roleid = $sroleid ;
$record -> allowoverride = $troleid ;
return insert_record ( 'role_allow_override' , $record );
}
/**
* Creates a record in the allow_assign table
* @ param int sroleid - source roleid
* @ param int troleid - target roleid
* @ return int - id or false
*/
function allow_assign ( $sroleid , $troleid ) {
$record -> roleid = $sroleid ;
$record -> allowassign = $troleid ;
return insert_record ( 'role_allow_assign' , $record );
}
/**
* gets a list of roles assignalbe in this context for this user
* @ param object $context
* @ return array
*/
function get_assignable_roles ( $context ) {
$role = get_records ( 'role' );
$options = array ();
foreach ( $role as $rolex ) {
if ( user_can_assign ( $context , $rolex -> id )) {
$options [ $rolex -> id ] = $rolex -> name ;
}
}
return $options ;
}
/**
* gets a list of roles that can be overriden in this context by this user
* @ param object $context
* @ return array
*/
function get_overridable_roles ( $context ) {
$role = get_records ( 'role' );
$options = array ();
foreach ( $role as $rolex ) {
if ( user_can_override ( $context , $rolex -> id )) {
$options [ $rolex -> id ] = $rolex -> name ;
}
}
return $options ;
}
2006-08-28 08:42:30 +00:00
/**
* who has this capability in this context
* does not handling user level resolving !!!
* i . e 1 person has 2 roles 1 allow , 1 prevent , this will not work properly
* @ param $context - object
* @ param $capability - string capability
* @ param $fields - fields to be pulled
* @ param $sort - the sort order
*/
function get_users_by_capability ( $context , $capability , $fields = 'distinct u.*' , $sort = '' ) {
global $CFG ;
// first get all roles with this capability in this context, or above
$possibleroles = get_roles_with_capability ( $capability , CAP_ALLOW );
$validroleids = array ();
foreach ( $possibleroles as $prole ) {
$caps = role_context_capabilities ( $prole -> id , $context , $capability ); // resolved list
if ( $caps [ $capability ] > 0 ) { // resolved capability > 0
$validroleids [] = $prole -> id ;
}
}
if ( $usercontexts = get_parent_contexts ( $context )) {
$listofcontexts = '(' . implode ( ',' , $usercontexts ) . ')' ;
} else {
$sitecontext = get_context_instance ( CONTEXT_SYSTEM , SITEID );
$listofcontexts = '(' . $sitecontext -> id . ')' ; // must be site
}
$roleids = '(' . implode ( ',' , $validroleids ) . ')' ;
$select = ' SELECT ' . $fields ;
$from = ' FROM ' . $CFG -> prefix . 'user u LEFT JOIN ' . $CFG -> prefix . 'role_assignments ra ON ra.userid = u.id ' ;
$where = ' WHERE (ra.contextid = ' . $context -> id . ' OR ra.contextid in ' . $listofcontexts . ') AND u.deleted = 0 AND ra.roleid in ' . $roleids . ' ' ;
return get_records_sql ( $select . $from . $where );
}
2006-08-31 08:36:36 +00:00
?>