mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 11:05:53 +02:00
ENHACEMENT: Improved caching of permissions for improved CMS perfromance for non-admins (merged from r102278)
This commit is contained in:
parent
d64e847534
commit
5d235fa9f7
@ -865,12 +865,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
// Standard mechanism for accepting permission changes from extensions
|
// Standard mechanism for accepting permission changes from extensions
|
||||||
$extended = $this->extendedCan('canDelete', $memberID);
|
$extended = $this->extendedCan('canDelete', $memberID);
|
||||||
if($extended !== null) return $extended;
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
|
||||||
if(isset(self::$cache_permissions['delete'][$this->ID])) {
|
|
||||||
return self::$cache_permissions['delete'][$this->ID];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regular canEdit logic is handled by can_edit_multiple
|
// Regular canEdit logic is handled by can_edit_multiple
|
||||||
$results = self::can_delete_multiple(array($this->ID), $memberID);
|
$results = self::can_delete_multiple(array($this->ID), $memberID);
|
||||||
|
|
||||||
@ -942,11 +937,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
if($extended !== null) return $extended;
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
if($this->ID) {
|
if($this->ID) {
|
||||||
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
|
||||||
if(isset(self::$cache_permissions['CanEditType'][$this->ID])) {
|
|
||||||
return self::$cache_permissions['CanEditType'][$this->ID];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regular canEdit logic is handled by can_edit_multiple
|
// Regular canEdit logic is handled by can_edit_multiple
|
||||||
$results = self::can_edit_multiple(array($this->ID), $memberID);
|
$results = self::can_edit_multiple(array($this->ID), $memberID);
|
||||||
|
|
||||||
@ -1029,16 +1019,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
$batchCallback=explode('::', $batchCallback);
|
$batchCallback=explode('::', $batchCallback);
|
||||||
|
|
||||||
if(is_callable($batchCallback)) {
|
if(is_callable($batchCallback)) {
|
||||||
$permissionValues = call_user_func($batchCallback, $ids,
|
call_user_func($batchCallback, $ids, Member::currentUserID(), false);
|
||||||
Member::currentUserID(), false);
|
|
||||||
|
|
||||||
if(!isset(self::$cache_permissions[$permission])) {
|
|
||||||
self::$cache_permissions[$permission] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
self::$cache_permissions[$permission] = $permissionValues
|
|
||||||
+ self::$cache_permissions[$permission];
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
user_error("SiteTree::prepopuplate_permission_cache can't calculate '$permission' "
|
user_error("SiteTree::prepopuplate_permission_cache can't calculate '$permission' "
|
||||||
. "with callback '$batchCallback'", E_USER_WARNING);
|
. "with callback '$batchCallback'", E_USER_WARNING);
|
||||||
@ -1069,7 +1050,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
// This is the name used on the permission cache
|
// This is the name used on the permission cache
|
||||||
// converts something like 'CanEditType' to 'edit'.
|
// converts something like 'CanEditType' to 'edit'.
|
||||||
$cacheKey = strtolower(substr($typeField, 3, -4));
|
$cacheKey = strtolower(substr($typeField, 3, -4)) . "-$memberID";
|
||||||
|
|
||||||
// Default result: nothing editable
|
// Default result: nothing editable
|
||||||
$result = array_fill_keys($ids, false);
|
$result = array_fill_keys($ids, false);
|
||||||
@ -1165,14 +1146,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isset($combinedStageResult)) {
|
if(isset($combinedStageResult)) {
|
||||||
// Cache results
|
// Cache the results
|
||||||
// TODO - Caching permissions is breaking unit tests. One possible issue
|
if(empty(self::$cache_permissions[$cacheKey])) self::$cache_permissions[$cacheKey] = array();
|
||||||
// is the cache needs to be flushed when permission on a page is changed,
|
self::$cache_permissions[$cacheKey] = $combinedStageResult + self::$cache_permissions[$cacheKey];
|
||||||
// but this only solved some of the failing unit tests. Disabled for now.
|
|
||||||
/*foreach($combinedStageResult as $id => $val) {
|
return $combinedStageResult;
|
||||||
self::$cache_permissions[$typeField][$id] = $val;
|
|
||||||
}*/
|
|
||||||
return $combinedStageResult;
|
|
||||||
} else {
|
} else {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
@ -1197,15 +1175,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
*/
|
*/
|
||||||
static function can_delete_multiple($ids, $memberID, $useCached = true) {
|
static function can_delete_multiple($ids, $memberID, $useCached = true) {
|
||||||
$deletable = array();
|
$deletable = array();
|
||||||
|
$result = array_fill_keys($ids, false);
|
||||||
$result = array_fill_keys($ids, false);
|
$cacheKey = "delete-$memberID";
|
||||||
|
|
||||||
// Look in the cache for values
|
// Look in the cache for values
|
||||||
if($useCached && isset(self::$cache_permissions['delete'])) {
|
if($useCached && isset(self::$cache_permissions[$cacheKey])) {
|
||||||
$cachedValues = array_intersect_key(self::$cache_permissions['delete'], $result);
|
$cachedValues = array_intersect_key(self::$cache_permissions[$cacheKey], $result);
|
||||||
|
|
||||||
// If we can't find everything in the cache, then look up the remainder separately
|
// If we can't find everything in the cache, then look up the remainder separately
|
||||||
$uncachedValues = array_diff_key($result, self::$cache_permissions['delete']);
|
$uncachedValues = array_diff_key($result, self::$cache_permissions[$cacheKey]);
|
||||||
if($uncachedValues) {
|
if($uncachedValues) {
|
||||||
$cachedValues = self::can_delete_multiple(array_keys($uncachedValues), $memberID, false)
|
$cachedValues = self::can_delete_multiple(array_keys($uncachedValues), $memberID, false)
|
||||||
+ $cachedValues;
|
+ $cachedValues;
|
||||||
@ -1253,6 +1231,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
// value
|
// value
|
||||||
return array_fill_keys($deletable, true) + array_fill_keys($ids, false);
|
return array_fill_keys($deletable, true) + array_fill_keys($ids, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collate selected descendants of this page.
|
* Collate selected descendants of this page.
|
||||||
@ -2706,6 +2685,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
static function reset() {
|
static function reset() {
|
||||||
self::$cache_permissions = array();
|
self::$cache_permissions = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function on_db_reset() {
|
||||||
|
self::$cache_permissions = array();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +504,8 @@ class SiteTreeTest extends SapphireTest {
|
|||||||
$page->CanEditType = 'OnlyTheseUsers';
|
$page->CanEditType = 'OnlyTheseUsers';
|
||||||
$page->EditorGroups()->add($this->idFromFixture('Group', 'editors'));
|
$page->EditorGroups()->add($this->idFromFixture('Group', 'editors'));
|
||||||
$page->write();
|
$page->write();
|
||||||
|
// Clear permission cache
|
||||||
|
SiteTree::on_db_reset();
|
||||||
|
|
||||||
// Confirm that Member.editor can now edit the page
|
// Confirm that Member.editor can now edit the page
|
||||||
$this->objFromFixture('Member','editor')->logIn();
|
$this->objFromFixture('Member','editor')->logIn();
|
||||||
|
Loading…
Reference in New Issue
Block a user