MDL-42192 accesslib: Cache capabilities list

With thanks to Andrew Nicols <[email protected]> for some ammendments.
This commit is contained in:
Tony Levi
2015-05-14 11:23:47 +09:30
parent 753d681076
commit aa7017432a
4 changed files with 74 additions and 19 deletions
+49 -19
View File
@@ -203,7 +203,6 @@ $ACCESSLIB_PRIVATE = new stdClass();
$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)
$ACCESSLIB_PRIVATE->rolepermissions = array(); // role permissions cache - helps a lot with mem usage
$ACCESSLIB_PRIVATE->capabilities = null; // detailed information about the capabilities
/**
* Clears accesslib's private caches. ONLY BE USED BY UNIT TESTS
@@ -241,7 +240,6 @@ function accesslib_clear_all_caches($resetcontexts) {
$ACCESSLIB_PRIVATE->dirtycontexts = null;
$ACCESSLIB_PRIVATE->accessdatabyuser = array();
$ACCESSLIB_PRIVATE->rolepermissions = array();
$ACCESSLIB_PRIVATE->capabilities = null;
if ($resetcontexts) {
context_helper::reset_caches();
@@ -2532,7 +2530,14 @@ function load_capability_def($component) {
*/
function get_cached_capabilities($component = 'moodle') {
global $DB;
return $DB->get_records('capabilities', array('component'=>$component));
$caps = get_all_capabilities();
$componentcaps = array();
foreach ($caps as $cap) {
if ($cap['component'] == $component) {
$componentcaps[] = (object) $cap;
}
}
return $componentcaps;
}
/**
@@ -2551,12 +2556,12 @@ function get_default_capabilities($archetype) {
$alldefs = array();
$defaults = array();
$components = array();
$allcaps = $DB->get_records('capabilities');
$allcaps = get_all_capabilities();
foreach ($allcaps as $cap) {
if (!in_array($cap->component, $components)) {
$components[] = $cap->component;
$alldefs = array_merge($alldefs, load_capability_def($cap->component));
if (!in_array($cap['component'], $components)) {
$components[] = $cap['component'];
$alldefs = array_merge($alldefs, load_capability_def($cap['component']));
}
}
foreach($alldefs as $name=>$def) {
@@ -2703,6 +2708,10 @@ function update_capabilities($component = 'moodle') {
}
}
// It is possible somebody directly modified the DB (according to accesslib_test anyway).
// So ensure our updating is based on fresh data.
cache::make('core', 'capabilities')->delete('core_capabilities');
$cachedcaps = get_cached_capabilities($component);
if ($cachedcaps) {
foreach ($cachedcaps as $cachedcap) {
@@ -2738,6 +2747,9 @@ function update_capabilities($component = 'moodle') {
}
}
// Flush the cached again, as we have changed DB.
cache::make('core', 'capabilities')->delete('core_capabilities');
// Are there new capabilities in the file definition?
$newcaps = array();
@@ -2788,6 +2800,9 @@ function update_capabilities($component = 'moodle') {
// reset static caches
accesslib_clear_all_caches(false);
// Flush the cached again, as we have changed DB.
cache::make('core', 'capabilities')->delete('core_capabilities');
return true;
}
@@ -2826,6 +2841,9 @@ function capabilities_cleanup($component, $newcapdef = null) {
} // End if.
}
}
if ($removedcount) {
cache::make('core', 'capabilities')->delete('core_capabilities');
}
return $removedcount;
}
@@ -2946,21 +2964,33 @@ function is_inside_frontpage(context $context) {
function get_capability_info($capabilityname) {
global $ACCESSLIB_PRIVATE, $DB; // one request per page only
//TODO: MUC - this could be cached in shared memory, it would eliminate 1 query per page
$caps = get_all_capabilities();
if (empty($ACCESSLIB_PRIVATE->capabilities)) {
$ACCESSLIB_PRIVATE->capabilities = array();
$caps = $DB->get_records('capabilities', array(), '', 'id, name, captype, riskbitmask');
foreach ($caps as $cap) {
$capname = $cap->name;
unset($cap->id);
unset($cap->name);
$cap->riskbitmask = (int)$cap->riskbitmask;
$ACCESSLIB_PRIVATE->capabilities[$capname] = $cap;
}
if (!isset($caps[$capabilityname])) {
return null;
}
return isset($ACCESSLIB_PRIVATE->capabilities[$capabilityname]) ? $ACCESSLIB_PRIVATE->capabilities[$capabilityname] : null;
return (object) $caps[$capabilityname];
}
/**
* Returns all capabilitiy records, preferably from MUC and not database.
*
* @return array All capability records
*/
function get_all_capabilities() {
global $DB;
$cache = cache::make('core', 'capabilities');
if (!$allcaps = $cache->get('core_capabilities')) {
$allcaps = $DB->get_records('capabilities', null, '', 'name as uniquename, *');
foreach ($allcaps as $k => $v) {
unset($v->uniquename);
$v->riskbitmask = (int) $v->riskbitmask;
$allcaps[$k] = (array) $v;
}
$cache->set('core_capabilities', $allcaps);
}
return $allcaps;
}
/**