diff options
Diffstat (limited to 'engine/lib/access.php')
| -rw-r--r-- | engine/lib/access.php | 158 | 
1 files changed, 96 insertions, 62 deletions
| diff --git a/engine/lib/access.php b/engine/lib/access.php index e8b3b0d52..f7d3bf7ea 100644 --- a/engine/lib/access.php +++ b/engine/lib/access.php @@ -12,6 +12,26 @@   */  /** + * Return an ElggCache static variable cache for the access caches + * + * @staticvar ElggStaticVariableCache $access_cache + * @return \ElggStaticVariableCache + * @access private + */ +function _elgg_get_access_cache() { +	/** +	 * A default filestore cache using the dataroot. +	 */ +	static $access_cache; + +	if (!$access_cache) { +		$access_cache = new ElggStaticVariableCache('access'); +	} + +	return $access_cache; +} + +/**   * Return a string of access_ids for $user_id appropriate for inserting into an SQL IN clause.   *   * @uses get_access_array @@ -29,10 +49,10 @@   */  function get_access_list($user_id = 0, $site_id = 0, $flush = false) {  	global $CONFIG, $init_finished; -	static $access_list; - -	if (!isset($access_list)) { -		$access_list = array(); +	$cache = _elgg_get_access_cache(); +	 +	if ($flush) { +		$cache->clear();  	}  	if ($user_id == 0) { @@ -45,20 +65,20 @@ function get_access_list($user_id = 0, $site_id = 0, $flush = false) {  	$user_id = (int) $user_id;  	$site_id = (int) $site_id; -	if (isset($access_list[$user_id]) && $flush == false) { -		return $access_list[$user_id]; -	} +	$hash = $user_id . $site_id . 'get_access_list'; -	$access = "(" . implode(",", get_access_array($user_id, $site_id, $flush)) . ")"; +	if ($cache[$hash]) { +		return $cache[$hash]; +	} +	 +	$access_array = get_access_array($user_id, $site_id, $flush); +	$access = "(" . implode(",", $access_array) . ")"; -	// only cache if done with init and access is enabled (unless admin user) -	// session is loaded before init is finished, so don't need to check for user session -	if ($init_finished && (elgg_is_admin_logged_in() || !elgg_get_ignore_access())) { -		$access_list[$user_id] = $access; -		return $access_list[$user_id]; -	} else { -		return $access; +	if ($init_finished) { +		$cache[$hash] = $access;  	} +	 +	return $access;  }  /** @@ -86,12 +106,10 @@ function get_access_list($user_id = 0, $site_id = 0, $flush = false) {  function get_access_array($user_id = 0, $site_id = 0, $flush = false) {  	global $CONFIG, $init_finished; -	// @todo everything from the db is cached. -	// this cache might be redundant. But db cache is flushed on every db write. -	static $access_array; +	$cache = _elgg_get_access_cache(); -	if (!isset($access_array)) { -		$access_array = array(); +	if ($flush) { +		$cache->clear();  	}  	if ($user_id == 0) { @@ -105,35 +123,41 @@ function get_access_array($user_id = 0, $site_id = 0, $flush = false) {  	$user_id = (int) $user_id;  	$site_id = (int) $site_id; -	if (empty($access_array[$user_id]) || $flush == true) { -		$tmp_access_array = array(ACCESS_PUBLIC); +	$hash = $user_id . $site_id . 'get_access_array'; + +	if ($cache[$hash]) { +		$access_array = $cache[$hash]; +	} else { +		$access_array = array(ACCESS_PUBLIC);  		// The following can only return sensible data if the user is logged in.  		if (elgg_is_logged_in()) { -			$tmp_access_array[] = ACCESS_LOGGED_IN; +			$access_array[] = ACCESS_LOGGED_IN;  			// Get ACL memberships  			$query = "SELECT am.access_collection_id"  				. " FROM {$CONFIG->dbprefix}access_collection_membership am"  				. " LEFT JOIN {$CONFIG->dbprefix}access_collections ag ON ag.id = am.access_collection_id" -				. " WHERE am.user_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; +				. " WHERE am.user_guid = $user_id AND (ag.site_guid = $site_id OR ag.site_guid = 0)"; -			if ($collections = get_data($query)) { +			$collections = get_data($query); +			if ($collections) {  				foreach ($collections as $collection) {  					if (!empty($collection->access_collection_id)) { -						$tmp_access_array[] = (int)$collection->access_collection_id; +						$access_array[] = (int)$collection->access_collection_id;  					}  				}  			}  			// Get ACLs owned.  			$query = "SELECT ag.id FROM {$CONFIG->dbprefix}access_collections ag "; -			$query .= "WHERE ag.owner_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; +			$query .= "WHERE ag.owner_guid = $user_id AND (ag.site_guid = $site_id OR ag.site_guid = 0)"; -			if ($collections = get_data($query)) { +			$collections = get_data($query); +			if ($collections) {  				foreach ($collections as $collection) {  					if (!empty($collection->id)) { -						$tmp_access_array[] = (int)$collection->id; +						$access_array[] = (int)$collection->id;  					}  				}  			} @@ -141,21 +165,21 @@ function get_access_array($user_id = 0, $site_id = 0, $flush = false) {  			$ignore_access = elgg_check_access_overrides($user_id);  			if ($ignore_access == true) { -				$tmp_access_array[] = ACCESS_PRIVATE; +				$access_array[] = ACCESS_PRIVATE;  			} +		} -			// only cache if done with init and access is enabled (unless admin user) -			// session is loaded before init is finished, so don't need to check for user session -			if ($init_finished && (elgg_is_admin_logged_in() || !elgg_get_ignore_access())) { -				$access_array[$user_id] = $tmp_access_array; -			} +		if ($init_finished) { +			$cache[$hash] = $access_array;  		} -	} else { -		$tmp_access_array = $access_array[$user_id];  	} -	$options = array('user_id' => $user_id, 'site_id' => $site_id); -	return elgg_trigger_plugin_hook('access:collections:read', 'user', $options, $tmp_access_array); +	$options = array( +		'user_id' => $user_id, +		'site_id' => $site_id +	); +	 +	return elgg_trigger_plugin_hook('access:collections:read', 'user', $options, $access_array);  }  /** @@ -401,9 +425,12 @@ function has_access_to_entity($entity, $user = null) {   * @link http://docs.elgg.org/Access   */  function get_write_access_array($user_id = 0, $site_id = 0, $flush = false) { -	global $CONFIG; -	//@todo this is probably not needed since caching happens at the DB level. -	static $access_array; +	global $CONFIG, $init_finished; +	$cache = _elgg_get_access_cache(); + +	if ($flush) { +		$cache->clear(); +	}  	if ($user_id == 0) {  		$user_id = elgg_get_logged_in_user_guid(); @@ -416,37 +443,41 @@ function get_write_access_array($user_id = 0, $site_id = 0, $flush = false) {  	$user_id = (int) $user_id;  	$site_id = (int) $site_id; -	if (empty($access_array[$user_id]) || $flush == true) { -		$query = "SELECT ag.* FROM {$CONFIG->dbprefix}access_collections ag "; -		$query .= " WHERE (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; -		$query .= " AND (ag.owner_guid = {$user_id})"; -		// ACCESS_PRIVATE through ACCESS_PUBLIC take 0 through 2 -		// @todo this AND clause is unnecessary because of id starts at 3 for table -		$query .= " AND ag.id >= 3"; +	$hash = $user_id . $site_id . 'get_write_access_array'; -		$tmp_access_array = array( +	if ($cache[$hash]) { +		$access_array = $cache[$hash]; +	} else { +		// @todo is there such a thing as public write access? +		$access_array = array(  			ACCESS_PRIVATE => elgg_echo("PRIVATE"),  			ACCESS_FRIENDS => elgg_echo("access:friends:label"),  			ACCESS_LOGGED_IN => elgg_echo("LOGGED_IN"),  			ACCESS_PUBLIC => elgg_echo("PUBLIC")  		); +		 +		$query = "SELECT ag.* FROM {$CONFIG->dbprefix}access_collections ag "; +		$query .= " WHERE (ag.site_guid = $site_id OR ag.site_guid = 0)"; +		$query .= " AND (ag.owner_guid = $user_id)"; +  		$collections = get_data($query);  		if ($collections) {  			foreach ($collections as $collection) { -				$tmp_access_array[$collection->id] = $collection->name; +				$access_array[$collection->id] = $collection->name;  			}  		} -		$access_array[$user_id] = $tmp_access_array; -	} else { -		$tmp_access_array = $access_array[$user_id]; +		if ($init_finished) { +			$cache[$hash] = $access_array; +		}  	} -	$options = array('user_id' => $user_id, 'site_id' => $site_id); -	$tmp_access_array = elgg_trigger_plugin_hook('access:collections:write', 'user', -		$options, $tmp_access_array); - -	return $tmp_access_array; +	$options = array( +		'user_id' => $user_id, +		'site_id' => $site_id +	); +	return elgg_trigger_plugin_hook('access:collections:write', 'user', +		$options, $access_array);  }  /** @@ -476,7 +507,7 @@ function can_edit_access_collection($collection_id, $user_guid = null) {  		return false;  	} -	$write_access = get_write_access_array($user->getGUID(), null, true); +	$write_access = get_write_access_array($user->getGUID(), 0, true);  	// don't ignore access when checking users.  	if ($user_guid) { @@ -560,8 +591,6 @@ function create_access_collection($name, $owner_guid = 0, $site_guid = 0) {   * @see remove_user_from_access_collection()   */  function update_access_collection($collection_id, $members) { -	global $CONFIG; -  	$acl = get_access_collection($collection_id);  	if (!$acl) { @@ -877,6 +906,8 @@ function get_readable_access_level($entity_access_id) {   * @tip Use this to access entities in automated scripts   * when no user is logged in.   * + * @note This clears the access cache. + *   * @warning This will not show disabled entities.   * Use {@link access_show_hidden_entities()} to access disabled entities.   * @@ -888,6 +919,8 @@ function get_readable_access_level($entity_access_id) {   * @see elgg_get_ignore_access()   */  function elgg_set_ignore_access($ignore = true) { +	$cache = _elgg_get_access_cache(); +	$cache->clear();  	$elgg_access = elgg_get_access_object();  	return $elgg_access->setIgnoreAccess($ignore);  } @@ -1018,6 +1051,7 @@ function elgg_override_permissions($hook, $type, $value, $params) {   */  function access_test($hook, $type, $value, $params) {  	global $CONFIG; +  	$value[] = $CONFIG->path . 'engine/tests/api/access_collections.php';  	return $value;  } | 
