mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-42192 accesslib: Cache capabilities list
With thanks to Andrew Nicols <andrew@nicols.co.uk> for some ammendments.
This commit is contained in:
parent
753d681076
commit
aa7017432a
@ -37,6 +37,7 @@ $string['caching'] = 'Caching';
|
||||
$string['cacheadmin'] = 'Cache administration';
|
||||
$string['cacheconfig'] = 'Configuration';
|
||||
$string['cachedef_calendar_subscriptions'] = 'Calendar subscriptions';
|
||||
$string['cachedef_capabilities'] = 'System capabilities list';
|
||||
$string['cachedef_config'] = 'Config settings';
|
||||
$string['cachedef_coursecat'] = 'Course categories lists for particular user';
|
||||
$string['cachedef_coursecatrecords'] = 'Course categories records';
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,6 +126,16 @@ $definitions = array(
|
||||
'staticacceleration' => true,
|
||||
),
|
||||
|
||||
// Cache the capabilities list DB table. See get_all_capabilities in accesslib.
|
||||
'capabilities' => array(
|
||||
'mode' => cache_store::MODE_APPLICATION,
|
||||
'simplekeys' => true,
|
||||
'simpledata' => true,
|
||||
'staticacceleration' => true,
|
||||
'staticaccelerationsize' => 1,
|
||||
'ttl' => 3600, // Just in case.
|
||||
),
|
||||
|
||||
// YUI Module cache.
|
||||
// This stores the YUI module metadata for Shifted YUI modules in Moodle.
|
||||
'yuimodules' => array(
|
||||
|
@ -67,6 +67,20 @@ class core_accesslib_testcase extends advanced_testcase {
|
||||
$this->assertEmpty($ACCESSLIB_PRIVATE->accessdatabyuser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check modifying capability record is not exposed to other code.
|
||||
*/
|
||||
public function test_capabilities_mutation() {
|
||||
$oldcap = get_capability_info('moodle/site:config');
|
||||
$cap = get_capability_info('moodle/site:config');
|
||||
unset($cap->name);
|
||||
$newcap = get_capability_info('moodle/site:config');
|
||||
|
||||
$this->assertFalse(isset($cap->name));
|
||||
$this->assertTrue(isset($newcap->name));
|
||||
$this->assertTrue(isset($oldcap->name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting of role access
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user