MDL-49398 accesslib: Update for 3.4 and cleanups

This commit is contained in:
Skylar Kelty 2017-03-27 11:44:43 +01:00
parent 95c0b810bf
commit 4bdd769309
No known key found for this signature in database
GPG Key ID: 2C9C7284E79B6B2C
3 changed files with 68 additions and 56 deletions

View File

@ -180,6 +180,7 @@ if (!defined('CONTEXT_CACHE_MAX_SIZE')) {
*/
global $ACCESSLIB_PRIVATE;
$ACCESSLIB_PRIVATE = new stdClass();
$ACCESSLIB_PRIVATE->cacheroledefs = array(); // Holds site-wide role definitions.
$ACCESSLIB_PRIVATE->dirtycontexts = null; // Dirty contexts cache, loaded from DB once per page
$ACCESSLIB_PRIVATE->accessdatabyuser = array(); // Holds the cache of $accessdata structure for users (including $USER)
@ -216,17 +217,44 @@ function accesslib_clear_all_caches_for_unit_testing() {
function accesslib_clear_all_caches($resetcontexts) {
global $ACCESSLIB_PRIVATE;
// Reset builtin static cache.
get_role_definitions(array(), true);
$ACCESSLIB_PRIVATE->dirtycontexts = null;
$ACCESSLIB_PRIVATE->accessdatabyuser = array();
$ACCESSLIB_PRIVATE->cacheroledefs = array();
$cache = cache::make('core', 'roledefs');
$cache->purge();
if ($resetcontexts) {
context_helper::reset_caches();
}
}
/**
* Clears accesslib's private cache of a specific role or roles. ONLY BE USED FROM THIS LIBRARY FILE!
*
* This reset does not touch global $USER.
*
* @access private
* @param int|array $roles
* @return void
*/
function accesslib_clear_role_cache($roles) {
global $ACCESSLIB_PRIVATE;
if (!is_array($roles)) {
$roles = [$roles];
}
foreach ($roles as $role) {
if (isset($ACCESSLIB_PRIVATE->cacheroledefs[$role])) {
unset($ACCESSLIB_PRIVATE->cacheroledefs[$role]);
}
}
$cache = cache::make('core', 'roledefs');
$cache->delete_many($roles);
}
/**
* Role is assigned at system context.
*
@ -242,49 +270,34 @@ function get_role_access($roleid) {
/**
* Fetch raw "site wide" role definitions.
* Even MUC static acceleration cache appears a bit slow for this.
* Important as can be hit hundreds of times per page.
*
* @param array $roleids List of role ids to fetch definitions for.
* @param bool $resetcache Reset the inbuilt static cache.
* @return array Complete definition for each requested role.
*/
function get_role_definitions(array $roleids, $resetcache = false, $resetmuc = array()) {
global $DB;
// Even MUC static acceleration cache appears a bit slow for this.
// Important as can be hit hundreds of times per page.
static $cache_roledefs = null;
static $cache_roleids = null;
if ($resetcache) {
$cache_roledefs = null;
$cache_roleids = null;
if ($resetmuc) {
$cache = cache::make('core', 'roledefs');
$cache->delete_many($resetmuc);
}
return;
}
if ($roleids === $cache_roleids) {
return $cache_roledefs;
}
function get_role_definitions(array $roleids) {
global $ACCESSLIB_PRIVATE;
if (empty($roleids)) {
return array();
}
$cache = cache::make('core', 'roledefs');
$cache_roledefs = array_filter($cache->get_many($roleids));
// Grab all keys we have not yet got in our static cache.
if ($uncached = array_diff($roleids, array_keys($ACCESSLIB_PRIVATE->cacheroledefs))) {
$cache = cache::make('core', 'roledefs');
$ACCESSLIB_PRIVATE->cacheroledefs += array_filter($cache->get_many($uncached));
if ($uncached = array_diff($roleids, array_keys($cache_roledefs))) {
$uncached = get_role_definitions_uncached($uncached);
$cache->set_many($uncached);
// Check we have the remaining keys from the MUC.
if ($uncached = array_diff($roleids, array_keys($ACCESSLIB_PRIVATE->cacheroledefs))) {
$uncached = get_role_definitions_uncached($uncached);
$ACCESSLIB_PRIVATE->cacheroledefs += $uncached;
$cache->set_many($uncached);
}
}
$cache_roledefs += $uncached;
$cache_roleids = $roleids;
return $cache_roledefs;
// Return just the roles we need.
return array_intersect_key($ACCESSLIB_PRIVATE->cacheroledefs, array_flip($roleids));
}
/**
@ -304,10 +317,10 @@ function get_role_definitions_uncached(array $roleids) {
$rdefs = array();
$sql = "SELECT ctx.path, rc.roleid, rc.capability, rc.permission
FROM {role_capabilities} rc
JOIN {context} ctx ON rc.contextid = ctx.id
WHERE rc.roleid $sql
ORDER BY ctx.path, rc.roleid, rc.capability";
FROM {role_capabilities} rc
JOIN {context} ctx ON rc.contextid = ctx.id
WHERE rc.roleid $sql
ORDER BY ctx.path, rc.roleid, rc.capability";
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $rd) {
@ -805,7 +818,7 @@ function require_capability($capability, context $context, $userid = null, $doan
* @return array access info array
*/
function get_user_roles_sitewide_accessdata($userid) {
global $CFG, $DB, $ACCESSLIB_PRIVATE;
global $CFG, $DB;
$accessdata = get_empty_accessdata();
@ -825,9 +838,9 @@ function get_user_roles_sitewide_accessdata($userid) {
// Preload every assigned role.
$sql = "SELECT ctx.path, ra.roleid, ra.contextid
FROM {role_assignments} ra
JOIN {context} ctx ON ctx.id = ra.contextid
WHERE ra.userid = :userid";
FROM {role_assignments} ra
JOIN {context} ctx ON ctx.id = ra.contextid
WHERE ra.userid = :userid";
$rs = $DB->get_recordset_sql($sql, array('userid' => $userid));
@ -889,7 +902,8 @@ function get_user_accessdata($userid, $preloadonly=false) {
}
} else {
$accessdata = get_user_roles_sitewide_accessdata($userid); // includes default role and frontpage role
// Includes default role and frontpage role.
$accessdata = get_user_roles_sitewide_accessdata($userid);
}
$ACCESSLIB_PRIVATE->accessdatabyuser[$userid] = $accessdata;
@ -1241,7 +1255,7 @@ function delete_role($roleid) {
$event->trigger();
// Reset any cache of this role, including MUC.
get_role_definitions(array(), true, array($roleid));
accesslib_clear_role_cache($roleid);
return true;
}
@ -1296,7 +1310,7 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw
}
// Reset any cache of this role, including MUC.
get_role_definitions(array(), true, array($roleid));
accesslib_clear_role_cache($roleid);
return true;
}
@ -1327,7 +1341,7 @@ function unassign_capability($capability, $roleid, $contextid = null) {
}
// Reset any cache of this role, including MUC.
get_role_definitions(array(), true, array($roleid));
accesslib_clear_role_cache($roleid);
return true;
}
@ -2057,7 +2071,7 @@ function reset_role_capabilities($roleid) {
}
// Reset any cache of this role, including MUC.
get_role_definitions(array(), true, array($roleid));
accesslib_clear_role_cache($roleid);
// Mark the system context dirty.
context_system::instance()->mark_dirty();
@ -4242,7 +4256,7 @@ function role_cap_duplicate($sourcerole, $targetrole) {
}
// Reset any cache of this role, including MUC.
get_role_definitions(array(), true, array($targetrole));
accesslib_clear_role_cache($targetrole);
}
/**
@ -4987,9 +5001,8 @@ abstract class context extends stdClass implements IteratorAggregate {
if ($ids) {
// Reset any cache of these roles, including MUC.
get_role_definitions(array(), true, $ids);
accesslib_clear_role_cache($ids);
}
}
/**

View File

@ -6570,7 +6570,6 @@ function calendar_cron() {
return true;
}
/**
* Previous internal API, it was not supposed to be used anywhere.
*
@ -6582,7 +6581,7 @@ function calendar_cron() {
* @return void modifies $accessdata parameter
*/
function load_course_context($userid, context_course $coursecontext, &$accessdata) {
throw new coding_exception('load_course_context() is removed. Please do not use accesslib private functions or data structures.');
throw new coding_exception('load_course_context() is removed. Do not use private functions or data structures.');
}
/**
@ -6596,7 +6595,7 @@ function load_course_context($userid, context_course $coursecontext, &$accessdat
* @return array
*/
function load_role_access_by_context($roleid, context $context, &$accessdata) {
throw new coding_exception('load_role_access_by_context() is removed. Please do not use accesslib private functions or data structures.');
throw new coding_exception('load_role_access_by_context() is removed. Do not use private functions or data structures.');
}
/**
@ -6607,7 +6606,7 @@ function load_role_access_by_context($roleid, context $context, &$accessdata) {
* @return void
*/
function dedupe_user_access() {
throw new coding_exception('dedupe_user_access() is removed. Please do not use accesslib private functions or data structures.');
throw new coding_exception('dedupe_user_access() is removed. Do not use private functions or data structures.');
}
/**
@ -6624,7 +6623,7 @@ function dedupe_user_access() {
* @return array access info array
*/
function get_user_access_sitewide($userid) {
debugging('get_user_access_sitewide() is deprecated. Please do not use accesslib private functions or data structures.', DEBUG_DEVELOPER);
debugging('get_user_access_sitewide() is deprecated. Do not use private functions or data structures.', DEBUG_DEVELOPER);
$accessdata = get_user_accessdata($userid);
$accessdata['rdef'] = array();

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2017060100.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2017060100.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.