function has_capability_in_accessdata($capability, $context, $accessdata, $doanything) {
global $CFG;
/// build $paths as a list of current + all parent "paths" with order bottom-to-top
$contextids = explode('/', $context->path);
$paths = array($context->path);
while (count($contextids) > 2) {
array_pop($contextids);
$paths[] = implode('/', $contextids);
}
$roles = array();
$switchedrole = false;
/// Find out if role switched
if (isset($accessdata['rsw'])) {
// check for isset() is fast
// empty() is slow...
if (empty($accessdata['rsw'])) {
unset($accessdata['rsw']); // keep things fast and unambiguous
break;
}
// From the bottom up...
foreach ($paths as $path) {
if (isset($accessdata['rsw'][$ctxp])) {
// Found a switchrole assignment
// check for that role _plus_ the default user role
$roles = array($accessdata['rsw'][$ctxp]=>null, $CFG->defaultuserroleid=>null);
$switchedrole = true;
break;
}
}
}
if (!$switchedrole) {
// get all users roles in this context and above
foreach ($paths as $path) {
if (isset($accessdata['ra'][$path])) {
foreach ($accessdata['ra'][$path] as $roleid) {
$roles[$roleid] = null;
}
}
}
// Find out if user is admin - do anything is allowed in system context only since 2.0
// do anything is ignored when switching roles - it is not allowed to switch to admin role anyway
if ($doanything) {
$systempath = '/'.SYSCONTEXTID;
foreach ($roles as $roleid=>$ignored) {
if (isset($accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'])
and $accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'] == CAP_ALLOW) {
return true;
}
}
}
}
/// Now find out what access is given to each role
/// going from bottom-->up - the lowes override wins unless there is a CAP_PROHIBIT somewhere above tested context
foreach ($roles as $roleid=>$ignored) {
$access = null;
foreach ($paths as $path) {
if (isset($accessdata['rdef']["{$path}:$roleid"][$capability])) {
$perm = (int)$accessdata['rdef']["{$path}:$roleid"][$capability];
if ($perm === CAP_PROHIBIT or is_null($roles[$roleid])) {
$roles[$roleid] = $perm;
}
}
}
}
// any CAP_PROHIBIT found means no access
if (array_search(CAP_PROHIBIT, $roles) !== false) {
return false;
}
// at least one CAP_ALLOW means user has access
return (array_search(CAP_ALLOW, $roles) !== false);
}
Petr Škoda (skodak) added a comment - 08/Mar/09 09:49 AM sample code:
function has_capability_in_accessdata($capability, $context, $accessdata, $doanything) {
global $CFG;
/// build $paths as a list of current + all parent "paths" with order bottom-to-top
$contextids = explode('/', $context->path);
$paths = array($context->path);
while (count($contextids) > 2) {
array_pop($contextids);
$paths[] = implode('/', $contextids);
}
$roles = array();
$switchedrole = false;
/// Find out if role switched
if (isset($accessdata['rsw'])) {
// check for isset() is fast
// empty() is slow...
if (empty($accessdata['rsw'])) {
unset($accessdata['rsw']); // keep things fast and unambiguous
break;
}
// From the bottom up...
foreach ($paths as $path) {
if (isset($accessdata['rsw'][$ctxp])) {
// Found a switchrole assignment
// check for that role _plus_ the default user role
$roles = array($accessdata['rsw'][$ctxp]=>null, $CFG->defaultuserroleid=>null);
$switchedrole = true;
break;
}
}
}
if (!$switchedrole) {
// get all users roles in this context and above
foreach ($paths as $path) {
if (isset($accessdata['ra'][$path])) {
foreach ($accessdata['ra'][$path] as $roleid) {
$roles[$roleid] = null;
}
}
}
// Find out if user is admin - do anything is allowed in system context only since 2.0
// do anything is ignored when switching roles - it is not allowed to switch to admin role anyway
if ($doanything) {
$systempath = '/'.SYSCONTEXTID;
foreach ($roles as $roleid=>$ignored) {
if (isset($accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'])
and $accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'] == CAP_ALLOW) {
return true;
}
}
}
}
/// Now find out what access is given to each role
/// going from bottom-->up - the lowes override wins unless there is a CAP_PROHIBIT somewhere above tested context
foreach ($roles as $roleid=>$ignored) {
$access = null;
foreach ($paths as $path) {
if (isset($accessdata['rdef']["{$path}:$roleid"][$capability])) {
$perm = (int)$accessdata['rdef']["{$path}:$roleid"][$capability];
if ($perm === CAP_PROHIBIT or is_null($roles[$roleid])) {
$roles[$roleid] = $perm;
}
}
}
}
// any CAP_PROHIBIT found means no access
if (array_search(CAP_PROHIBIT, $roles) !== false) {
return false;
}
// at least one CAP_ALLOW means user has access
return (array_search(CAP_ALLOW, $roles) !== false);
}
Petr Škoda (skodak) added a comment - 25/Mar/09 04:20 PM sending an experimental patch for 1.9, it is missing a lot of strings and has some problems, but should clearly illustrate how it could work
All content on this web site is made available under the GNU General Public License, unless otherwise stated.
function has_capability_in_accessdata($capability, $context, $accessdata, $doanything) {
global $CFG;
/// build $paths as a list of current + all parent "paths" with order bottom-to-top
$contextids = explode('/', $context->path);
$paths = array($context->path);
while (count($contextids) > 2) { array_pop($contextids); $paths[] = implode('/', $contextids); }
$roles = array();
$switchedrole = false;
/// Find out if role switched
if (isset($accessdata['rsw'])) {
// check for isset() is fast
// empty() is slow...
if (empty($accessdata['rsw'])) { unset($accessdata['rsw']); // keep things fast and unambiguous break; }
// From the bottom up...
foreach ($paths as $path) {
if (isset($accessdata['rsw'][$ctxp])) { // Found a switchrole assignment // check for that role _plus_ the default user role $roles = array($accessdata['rsw'][$ctxp]=>null, $CFG->defaultuserroleid=>null); $switchedrole = true; break; }
}
}
if (!$switchedrole) {
// get all users roles in this context and above
foreach ($paths as $path) {
if (isset($accessdata['ra'][$path])) {
foreach ($accessdata['ra'][$path] as $roleid) { $roles[$roleid] = null; }
}
}
// Find out if user is admin - do anything is allowed in system context only since 2.0
// do anything is ignored when switching roles - it is not allowed to switch to admin role anyway
if ($doanything) {
$systempath = '/'.SYSCONTEXTID;
foreach ($roles as $roleid=>$ignored) {
if (isset($accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'])
and $accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'] == CAP_ALLOW) { return true; }
}
}
}
/// Now find out what access is given to each role
/// going from bottom-->up - the lowes override wins unless there is a CAP_PROHIBIT somewhere above tested context
foreach ($roles as $roleid=>$ignored) {
$access = null;
foreach ($paths as $path) {
if (isset($accessdata['rdef']["{$path}:$roleid"][$capability])) {
$perm = (int)$accessdata['rdef']["{$path}:$roleid"][$capability];
if ($perm === CAP_PROHIBIT or is_null($roles[$roleid])) { $roles[$roleid] = $perm; }
}
}
}
// any CAP_PROHIBIT found means no access
if (array_search(CAP_PROHIBIT, $roles) !== false) { return false; }
// at least one CAP_ALLOW means user has access
return (array_search(CAP_ALLOW, $roles) !== false);
}