mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-01 13:48:37 +02:00
ENHANCEMENT: Performance enhnacement to Permission::check(), to grab all the permission codes from the DB at once.
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@83436 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
e1ea8759be
commit
fdc6574064
@ -101,16 +101,19 @@ class Permission extends DataObject {
|
|||||||
*/
|
*/
|
||||||
public static function check($code, $arg = "any", $member = null, $strict = true) {
|
public static function check($code, $arg = "any", $member = null, $strict = true) {
|
||||||
if(!$member) {
|
if(!$member) {
|
||||||
if(!Member::currentUser()) {
|
if(!Member::currentUserID()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$member = Member::currentUser();
|
$member = Member::currentUserID();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::checkMember($member, $code, $arg, $strict);
|
return self::checkMember($member, $code, $arg, $strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions cache. The format is a map, where the keys are member IDs, and the values are
|
||||||
|
* arrays of permission codes.
|
||||||
|
*/
|
||||||
private static $cache_permissions = array();
|
private static $cache_permissions = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,23 +142,23 @@ class Permission extends DataObject {
|
|||||||
$perms_list = self::get_declared_permissions_list();
|
$perms_list = self::get_declared_permissions_list();
|
||||||
$memberID = (is_object($member)) ? $member->ID : $member;
|
$memberID = (is_object($member)) ? $member->ID : $member;
|
||||||
|
|
||||||
// Simple cache. This could be improved a lot by actually downloading all of the given user's permissions in one hit
|
if($arg == 'any') {
|
||||||
$codeStr = is_array($code) ? implode(',',$code) : $code;
|
// Cache the permissions in memory
|
||||||
if($arg == 'any' && isset(self::$cache_permissions[$memberID][$codeStr])) {
|
if(!isset(self::$cache_permissions[$memberID])) {
|
||||||
return self::$cache_permissions[$memberID][$codeStr];
|
self::$cache_permissions[$memberID] = self::permissions_for_member($memberID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If $admin_implies_all was false then this would be inefficient, but that's an edge
|
||||||
if(self::$declared_permissions && is_array($perms_list) && !in_array($code, $perms_list)) {
|
// case and this keeps the code simpler
|
||||||
user_error(
|
if(!is_array($code)) $code = array($code);
|
||||||
"Permission '$code' has not been declared. Use " .
|
if(self::$admin_implies_all) $code[] = "ADMIN";
|
||||||
"Permission::declare_permissions() to add this permission",
|
|
||||||
E_USER_WARNING
|
// Multiple $code values - return true if at least one matches, ie, intersection exists
|
||||||
);
|
return (bool)array_intersect($code, self::$cache_permissions[$memberID]);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
// The following code should only be used if you're not using the "any" arg. This is kind
|
||||||
|
// of obselete functionality and could possibly be deprecated.
|
||||||
|
|
||||||
$groupList = self::groupList($memberID);
|
$groupList = self::groupList($memberID);
|
||||||
if(!$groupList) return false;
|
if(!$groupList) return false;
|
||||||
@ -200,10 +203,7 @@ class Permission extends DataObject {
|
|||||||
)
|
)
|
||||||
")->value();
|
")->value();
|
||||||
|
|
||||||
if($permission) {
|
if($permission) return $permission;
|
||||||
self::$cache_permissions[$memberID][$codeStr] = $permission;
|
|
||||||
return $permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strict checking disabled?
|
// Strict checking disabled?
|
||||||
if(!self::$strict_checking || !$strict) {
|
if(!self::$strict_checking || !$strict) {
|
||||||
@ -216,16 +216,28 @@ class Permission extends DataObject {
|
|||||||
)
|
)
|
||||||
")->value();
|
")->value();
|
||||||
|
|
||||||
if(!$hasPermission) {
|
if(!$hasPermission) return;
|
||||||
self::$cache_permissions[$memberID][$codeStr] = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$cache_permissions[$memberID][$codeStr] = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the 'any' permission codes available to the given member.
|
||||||
|
*/
|
||||||
|
public static function permissions_for_member($memberID) {
|
||||||
|
$groupList = self::groupList($memberID);
|
||||||
|
$groupCSV = implode(", ", $groupList);
|
||||||
|
|
||||||
|
// Raw SQL for efficiency
|
||||||
|
return DB::query("
|
||||||
|
SELECT \"Code\"
|
||||||
|
FROM \"Permission\"
|
||||||
|
WHERE \"Type\" = " . self::GRANT_PERMISSION . " AND \"GroupID\" IN ($groupCSV)
|
||||||
|
")->column();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of groups that the given member belongs to.
|
* Get the list of groups that the given member belongs to.
|
||||||
|
Loading…
Reference in New Issue
Block a user