diff options
| author | icewing <icewing@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2008-06-09 12:40:45 +0000 | 
|---|---|---|
| committer | icewing <icewing@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2008-06-09 12:40:45 +0000 | 
| commit | c522f28c7cf6c37ddd6b2b2a4bcc3093784f7577 (patch) | |
| tree | da07039a96a50d94fec2b54d57636334796315fa /engine/lib/entities.php | |
| parent | 8f4260e2a46eba16ebc2462ec1d23260e8377482 (diff) | |
| download | elgg-c522f28c7cf6c37ddd6b2b2a4bcc3093784f7577.tar.gz elgg-c522f28c7cf6c37ddd6b2b2a4bcc3093784f7577.tar.bz2 | |
Marcus Povey <marcus@dushka.co.uk>
* Added caching to entities. Please report any problems.
git-svn-id: https://code.elgg.org/elgg/trunk@831 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine/lib/entities.php')
| -rw-r--r-- | engine/lib/entities.php | 652 | 
1 files changed, 381 insertions, 271 deletions
| diff --git a/engine/lib/entities.php b/engine/lib/entities.php index db3665c6f..cbcd5ccad 100644 --- a/engine/lib/entities.php +++ b/engine/lib/entities.php @@ -11,6 +11,9 @@  	 * @link http://elgg.org/  	 */ +	/// Cache objects in order to minimise database access. +	$ENTITY_CACHE = array(); +	  	/**  	 * ElggEntity The elgg entity superclass  	 * This class holds methods for accessing the main entities table. @@ -32,7 +35,11 @@  		 * Subclasses should add to this in their constructors.  		 * Any field not appearing in this will be viewed as a   		 */ -		protected $attributes;
 +		protected $attributes; + +		/** +		 * Temporary cache for metadata, permitting meta data access before a guid has obtained. +		 */  		protected $temp_metadata;  		/** @@ -45,9 +52,11 @@  		 */  		protected function initialise_attributes()  		{ +			initialise_entity_cache(); +  			// Create attributes array if not already created  			if (!is_array($this->attributes)) $this->attributes = array(); -			if (!is_array($this->temp_metadata)) $this->temp_metadata = array();
 +			if (!is_array($this->temp_metadata)) $this->temp_metadata = array();  			$this->attributes['guid'] = "";  			$this->attributes['type'] = ""; @@ -77,14 +86,14 @@  				return $this->attributes[$name];  			} -			// No, so see if its in the meta data for this entity
 +			// No, so see if its in the meta data for this entity  			if ((int) ($this->guid) > 0) {  				$meta = $this->getMetaData($name);  				if ($meta) -					return $meta;
 -			} else {
 -				if (isset($this->temp_metadata[$name]))
 -					return $this->temp_metadata[$name];
 +					return $meta; +			} else { +				if (isset($this->temp_metadata[$name])) +					return $this->temp_metadata[$name];  			}  			// Can't find it, so return null @@ -117,9 +126,9 @@  				$this->attributes[$name] = $value;  			}  			else if ((int) $this->guid > 0) { -				return $this->setMetaData($name, $value);
 -			} else {
 -				$this->temp_metadata[$name] = $value;
 +				return $this->setMetaData($name, $value); +			} else { +				$this->temp_metadata[$name] = $value;  			}  			return true; @@ -135,9 +144,9 @@  			$md = get_metadata_byname($this->getGUID(), $name);  			if ($md && !is_array($md)) { -				return $md->value;
 -			} else if ($md && is_array($md)) {
 -				return metadata_array_to_values($md);
 +				return $md->value; +			} else if ($md && is_array($md)) { +				return metadata_array_to_values($md);  			}  			return null; @@ -155,11 +164,11 @@  		public function setMetaData($name, $value, $value_type = "", $multiple = false)  		{  			if (is_array($value)) -			{
 -				remove_metadata($this->getGUID(), $name);
 +			{ +				remove_metadata($this->getGUID(), $name);  				$multiple = true;  				foreach ($value as $v) { -					if (!create_metadata($this->getGUID(), $name, $v, $value_type, $this->getOwner(), $this->getAccessID(), $multiple)) return false; 
 +					if (!create_metadata($this->getGUID(), $name, $v, $value_type, $this->getOwner(), $this->getAccessID(), $multiple)) return false;   				}  				return true; @@ -172,24 +181,24 @@  		 * Clear metadata.  		 */  		public function clearMetaData($name = "") -		{
 +		{  			if (empty($name)) { -				return clear_metadata($this->getGUID());
 -			} else {
 -				return remove_metadata($this->getGUID(),$name);
 +				return clear_metadata($this->getGUID()); +			} else { +				return remove_metadata($this->getGUID(),$name);  			}  		} -		
 -		/**
 -		 * Remove all entities associated with this entity
 -		 *
 -		 * @return true
 -		 */
 -		public function clearRelationships() {
 -			remove_entity_relationships($this->getGUID());
 -			remove_entity_relationships($this->getGUID(),"",true);
 -			return true;
 -		}
 +		 +		/** +		 * Remove all entities associated with this entity +		 * +		 * @return true +		 */ +		public function clearRelationships() { +			remove_entity_relationships($this->getGUID()); +			remove_entity_relationships($this->getGUID(),"",true); +			return true; +		}  		/**  		 * Adds an annotation to an entity. By default, the type is detected automatically; however,  @@ -277,39 +286,39 @@  		{  			return get_annotations_max($this->getGUID(), "","",$name);  		} -		
 -		/**
 -		 * Gets an array of entities from a specific relationship type
 -		 *
 -		 * @param string $relationship Relationship type (eg "friends")
 -		 * @param true|false $inverse Is this an inverse relationship?
 -		 * @param int $limit Number of elements to return
 -		 * @param int $offset Indexing offset
 -		 * @return array|false An array of entities or false on failure
 -		 */		
 -		function getEntitiesFromRelationship($relationship, $inverse = false, $limit = 50, $offset = 0) {
 -			return get_entities_from_relationship($relationship,$this->getGUID(),$inverse,"","","","time_created desc",$limit,$offset);			
 -		}
 -		
 -		/**
 -		 * Gets the number of of entities from a specific relationship type
 -		 *
 -		 * @param string $relationship Relationship type (eg "friends")
 -		 * @return int|false The number of entities or false on failure
 -		 */		
 -		function countEntitiesFromRelationship($relationship) {
 -			return get_entities_from_relationship($relationship,$this->getGUID(),false,"","","","time_created desc",null,null,true);			
 -		}
 -		
 -		/**
 -		 * Determines whether or not the specified user (by default the current one) can edit the entity 
 -		 *
 -		 * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user)
 -		 * @return true|false
 -		 */
 -		function canEdit($user_guid = 0) {
 -			return can_edit_entity($this->getGUID(),$user_guid);
 -		}
 +		 +		/** +		 * Gets an array of entities from a specific relationship type +		 * +		 * @param string $relationship Relationship type (eg "friends") +		 * @param true|false $inverse Is this an inverse relationship? +		 * @param int $limit Number of elements to return +		 * @param int $offset Indexing offset +		 * @return array|false An array of entities or false on failure +		 */		 +		function getEntitiesFromRelationship($relationship, $inverse = false, $limit = 50, $offset = 0) { +			return get_entities_from_relationship($relationship,$this->getGUID(),$inverse,"","","","time_created desc",$limit,$offset);			 +		} +		 +		/** +		 * Gets the number of of entities from a specific relationship type +		 * +		 * @param string $relationship Relationship type (eg "friends") +		 * @return int|false The number of entities or false on failure +		 */		 +		function countEntitiesFromRelationship($relationship) { +			return get_entities_from_relationship($relationship,$this->getGUID(),false,"","","","time_created desc",null,null,true);			 +		} +		 +		/** +		 * Determines whether or not the specified user (by default the current one) can edit the entity  +		 * +		 * @param int $user_guid The user GUID, optionally (defaults to the currently logged in user) +		 * @return true|false +		 */ +		function canEdit($user_guid = 0) { +			return can_edit_entity($this->getGUID(),$user_guid); +		}  		/**  		 * Enter description here... @@ -334,13 +343,13 @@  		 * @todo document me  		 */  		public function getOwner() { return $this->get('owner_guid'); } -		
 -		/**
 -		 * Returns the actual entity of the user who owns this entity, if any
 -		 *
 -		 * @return ElggEntity The owning user
 -		 */
 -		public function getOwnerEntity() { return get_entity($this->get('owner_guid')); }
 +		 +		/** +		 * Returns the actual entity of the user who owns this entity, if any +		 * +		 * @return ElggEntity The owning user +		 */ +		public function getOwnerEntity() { return get_entity($this->get('owner_guid')); }  		/**  		 * Enter description here... @@ -373,13 +382,13 @@  		 * @todo document me  		 */  		public function getTimeUpdated() { return $this->get('time_updated'); } -		
 -		/**
 -		 * Gets the display URL for this entity
 -		 *
 -		 * @return string The URL
 -		 */
 -		public function getURL() { return get_entity_url($this->getGUID()); }
 +		 +		/** +		 * Gets the display URL for this entity +		 * +		 * @return string The URL +		 */ +		public function getURL() { return get_entity_url($this->getGUID()); }  		/**  		 * Save generic attributes to the entities table. @@ -389,6 +398,8 @@  			$guid = (int) $this->guid;  			if ($guid > 0)  			{  +				cache_entity($this); +  				return update_entity(  					$this->get('guid'),  					$this->get('owner_guid'), @@ -399,14 +410,17 @@  			{   				$this->attributes['guid'] = create_entity($this->attributes['type'], $this->attributes['subtype'], $this->attributes['owner_guid'], $this->attributes['access_id']); // Create a new entity (nb: using attribute array directly 'cos set function does something special!)  				if (!$this->attributes['guid']) throw new IOException(elgg_echo('IOException:BaseEntitySaveFailed'));  -				
 -				// Save any unsaved metadata
 -				if (sizeof($this->temp_metadata) > 0) {
 -					foreach($this->temp_metadata as $name => $value) {
 -						$this->$name = $value;
 -						unset($this->temp_metadata[$name]);
 -					}
 -				}
 +				 +				// Save any unsaved metadata +				if (sizeof($this->temp_metadata) > 0) { +					foreach($this->temp_metadata as $name => $value) { +						$this->$name = $value; +						unset($this->temp_metadata[$name]); +					} +				} +				 +				// Cache object handle +				if ($this->attributes['guid']) cache_entity($this);   				return $this->attributes['guid'];  			} @@ -431,6 +445,9 @@  				foreach($objarray as $key => $value)   					$this->attributes[$key] = $value; +				// Cache object handle +				if ($this->attributes['guid']) cache_entity($this);  +					  				return true;  			} @@ -442,7 +459,7 @@  		 */  		public function delete()   		{  -			$res = delete_entity($this->get('guid'));
 +			$res = delete_entity($this->get('guid'));  			return $res;  		} @@ -631,6 +648,83 @@  	}  	/** +	 * Initialise the entity cache. +	 */ +	function initialise_entity_cache() +	{ +		global $ENTITY_CACHE; +		 +		if (!is_array($ENTITY_CACHE)) +			$ENTITY_CACHE = array(); +	} +	 +	/** +	 * Invalidate this class' entry in the cache. +	 *  +	 * @param int $guid The guid +	 */ +	function invalidate_cache_for_entity($guid) +	{ +		global $ENTITY_CACHE; +		 +		$guid = (int)$guid; +			 +		unset($ENTITY_CACHE[$guid]); +				 +	} +	 +	/** +	 * Cache an entity. +	 *  +	 * @param ElggEntity $entity Entity to cache +	 */ +	function cache_entity(ElggEntity $entity) +	{ +		global $ENTITY_CACHE; +		 +		$ENTITY_CACHE[$entity->guid] = &$entity; +	} +	 +	/** +	 * Retrieve a entity from the cache. +	 *  +	 * @param int $guid The guid +	 */ +	function retrieve_cached_entity($guid) +	{ +		global $ENTITY_CACHE; +		 +		$guid = (int)$guid; +			 +		if (isset($ENTITY_CACHE[$guid]))  +			return $ENTITY_CACHE[$guid]; +				 +		return false; +	} +	 +	/** +	 * As retrieve_cached_entity, but returns the result as a stdClass (compatible with load functions that +	 * expect a database row.) +	 *  +	 * @param int $guid The guid +	 */ +	function retrieve_cached_entity_row($guid) +	{ +		$obj = retrieve_cached_entity($guid); +		if ($obj) +		{ +			$tmp = new stdClass; +			 +			foreach ($obj as $k => $v) +				$tmp->$k = $v; +				 +			return $tmp; +		} + +		return false; +	} +	 +	/**  	 * Return the integer ID for a given subtype, or false.  	 *   	 * TODO: Move to a nicer place? @@ -756,11 +850,11 @@  		$owner_guid = (int)$owner_guid;  		$access_id = (int)$access_id;  		$time = time(); -		
 -		$entity = get_entity($guid);
 +		 +		$entity = get_entity($guid);  		if ($entity->canEdit()) { -			
 +			  			if (trigger_event('update',$entity->type,$entity)) {  				$ret = update_data("UPDATE {$CONFIG->dbprefix}entities set owner_guid='$owner_guid', access_id='$access_id', time_updated='$time' WHERE guid=$guid"); @@ -768,9 +862,9 @@  				if ($ret===false)  					return false; -				return true;
 +				return true;  			} -			
 +			  		}  	} @@ -780,7 +874,7 @@  	 * @param string $type The type of the entity (site, user, object).  	 * @param string $subtype The subtype of the entity.  	 * @param int $owner_guid The GUID of the object's owner. -	 * @param int $access_id The access control group to create the entity with.
 +	 * @param int $access_id The access control group to create the entity with.  	 * @param int $site_guid The site to add this entity to. Leave as 0 (default) for the current site.  	 * @return mixed The new entity's GUID, or false on failure  	 */ @@ -792,13 +886,13 @@  		$subtype = add_subtype($type, $subtype);  		$owner_guid = (int)$owner_guid;   		$access_id = (int)$access_id; -		$time = time();
 -		if ($site_guid == 0)
 -			$site_guid = $CONFIG->site_guid;
 +		$time = time(); +		if ($site_guid == 0) +			$site_guid = $CONFIG->site_guid;  		$site_guid = (int) $site_guid; -		if ($type=="") throw new InvalidParameterException(elgg_echo('InvalidParameterException:EntityTypeNotSet'));
 -
 +		if ($type=="") throw new InvalidParameterException(elgg_echo('InvalidParameterException:EntityTypeNotSet')); +  		return insert_data("INSERT into {$CONFIG->dbprefix}entities (type, subtype, owner_guid, site_guid, access_id, time_created, time_updated) values ('$type',$subtype, $owner_guid, $site_guid, $access_id, $time, $time)");   	} @@ -815,9 +909,25 @@  		$guid = (int) $guid; -		$access = get_access_sql_suffix(); +		$row = retrieve_cached_entity_row($guid); +		if ($row) +		{ +			// We have already cached this object, so retrieve its value from the cache +			if ($CONFIG->debug) +				error_log("** Retrieving GUID:$guid from cache"); + +			return $row; +		} +		else +		{	 +			// Object not cached, load it. +			if ($CONFIG->debug) +				error_log("** GUID:$guid loaded from DB"); +			 +			$access = get_access_sql_suffix(); -		return get_data_row("SELECT * from {$CONFIG->dbprefix}entities where guid=$guid and $access"); +			return get_data_row("SELECT * from {$CONFIG->dbprefix}entities where guid=$guid and $access"); +		}  	}  	/** @@ -876,8 +986,8 @@  	 * @param int $owner_guid The GUID of the owning user  	 * @param string $order_by The field to order by; by default, time_created desc  	 * @param int $limit The number of entities to return; 10 by default -	 * @param int $offset The indexing offset, 0 by default
 -	 * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.
 +	 * @param int $offset The indexing offset, 0 by default +	 * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false.  	 * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.   	 */  	function get_entities($type = "", $subtype = "", $owner_guid = 0, $order_by = "time_created desc", $limit = 10, $offset = 0, $count = false, $site_guid = 0) @@ -888,13 +998,13 @@  			return false;  		$type = sanitise_string($type); -		$subtype = get_subtype_id($type, $subtype);
 +		$subtype = get_subtype_id($type, $subtype);  		$order_by = sanitise_string($order_by);  		$limit = (int)$limit; -		$offset = (int)$offset;
 -		$site_guid = (int) $site_guid;
 -		if ($site_guid == 0)
 +		$offset = (int)$offset; +		$site_guid = (int) $site_guid; +		if ($site_guid == 0)  			$site_guid = $CONFIG->site_guid;  		$where = array(); @@ -903,37 +1013,37 @@  			$where[] = "type='$type'";  		if ($subtype!=="")  			$where[] = "subtype=$subtype"; -		if ($owner_guid != "") {
 -			if (!is_array($owner_guid)) {
 +		if ($owner_guid != "") { +			if (!is_array($owner_guid)) {  				$owner_guid = (int) $owner_guid; -				$where[] = "owner_guid = '$owner_guid'";
 -			} else if (sizeof($owner_guid) > 0) {
 -				// Cast every element to the owner_guid array to int
 -				$owner_guid = array_map("sanitise_int", $owner_guid);
 -				$owner_guid = implode(",",$owner_guid);
 -				$where[] = "owner_guid in ({$owner_guid})";
 -			}
 -		}
 -		if ($site_guid > 0)
 +				$where[] = "owner_guid = '$owner_guid'"; +			} else if (sizeof($owner_guid) > 0) { +				// Cast every element to the owner_guid array to int +				$owner_guid = array_map("sanitise_int", $owner_guid); +				$owner_guid = implode(",",$owner_guid); +				$where[] = "owner_guid in ({$owner_guid})"; +			} +		} +		if ($site_guid > 0)  			$where[] = "site_guid = {$site_guid}"; -
 +  		if (!$count) { -			$query = "SELECT * from {$CONFIG->dbprefix}entities where ";
 -		} else {
 -			$query = "select count(guid) as total from {$CONFIG->dbprefix}entities where ";
 +			$query = "SELECT * from {$CONFIG->dbprefix}entities where "; +		} else { +			$query = "select count(guid) as total from {$CONFIG->dbprefix}entities where ";  		}  		foreach ($where as $w)  			$query .= " $w and "; -		$query .= get_access_sql_suffix(); // Add access controls
 -		if (!$count) {
 -			$query .= " order by $order_by";
 +		$query .= get_access_sql_suffix(); // Add access controls +		if (!$count) { +			$query .= " order by $order_by";  			if ($limit) $query .= " limit $offset, $limit"; // Add order and limit -			$dt = get_data($query, "entity_row_to_elggstar");
 -			return $dt;
 -		} else {
 -			$total = get_data_row($query);
 -			return $total->total;
 +			$dt = get_data($query, "entity_row_to_elggstar"); +			return $dt; +		} else { +			$total = get_data_row($query); +			return $total->total;  		}  	} @@ -945,21 +1055,21 @@  	function delete_entity($guid)  	{  		global $CONFIG; -		
 -		// TODO Make sure this deletes all metadata/annotations/relationships/etc!!
 +		 +		// TODO Make sure this deletes all metadata/annotations/relationships/etc!!  		$guid = (int)$guid; -		if ($entity = get_entity($guid)) {
 -			if (trigger_event('delete',$entity->type,$entity)) {
 -				if ($entity->canEdit()) {
 -					$entity->clearMetadata();
 -					$entity->clearAnnotations();
 +		if ($entity = get_entity($guid)) { +			if (trigger_event('delete',$entity->type,$entity)) { +				if ($entity->canEdit()) { +					$entity->clearMetadata(); +					$entity->clearAnnotations();  					$entity->clearRelationships(); -					$res = delete_data("DELETE from {$CONFIG->dbprefix}entities where guid={$guid}");
 -					return $res;
 -				} 
 -			}
 -		}
 +					$res = delete_data("DELETE from {$CONFIG->dbprefix}entities where guid={$guid}"); +					return $res; +				}  +			} +		}  		return false;  	} @@ -1075,141 +1185,141 @@  			}  		}  	} -	
 -	/**
 -	 * Determines whether or not the specified user can edit the specified entity.
 -	 * 
 -	 * This is extendible by registering a plugin hook taking in the parameters 'entity' and 'user',
 -	 * which are the entity and user entities respectively
 -	 * 
 -	 * @see register_plugin_hook 
 -	 *
 -	 * @param int $entity_guid The GUID of the entity
 -	 * @param int $user_guid The GUID of the user
 -	 * @return true|false Whether the specified user can edit the specified entity.
 -	 */
 -	function can_edit_entity($entity_guid, $user_guid = 0) {
 -		
 -		if ($user_guid == 0) {
 -			if (isset($_SESSION['user'])) {
 -				$user = $_SESSION['user'];
 -			} else {
 -				$user = null;
 -			}
 -		} else {
 -			$user = get_entity($user_guid);
 +	 +	/** +	 * Determines whether or not the specified user can edit the specified entity. +	 *  +	 * This is extendible by registering a plugin hook taking in the parameters 'entity' and 'user', +	 * which are the entity and user entities respectively +	 *  +	 * @see register_plugin_hook  +	 * +	 * @param int $entity_guid The GUID of the entity +	 * @param int $user_guid The GUID of the user +	 * @return true|false Whether the specified user can edit the specified entity. +	 */ +	function can_edit_entity($entity_guid, $user_guid = 0) { +		 +		if ($user_guid == 0) { +			if (isset($_SESSION['user'])) { +				$user = $_SESSION['user']; +			} else { +				$user = null; +			} +		} else { +			$user = get_entity($user_guid); +		} + +		if (($entity = get_entity($entity_guid)) && (!is_null($user))) { + +			if ($entity->getOwner() == $user->getGUID()) return true; +			if ($entity->type == "user" && $entity->getGUID() == $user->getGUID()) return true; +			 +			return trigger_plugin_hook('permissions_check',$entity->type,array('entity' => $entity, 'user' => $user),false); +		 +		} else { +			 +			return false; +			  		} -
 -		if (($entity = get_entity($entity_guid)) && (!is_null($user))) {
 -
 -			if ($entity->getOwner() == $user->getGUID()) return true;
 -			if ($entity->type == "user" && $entity->getGUID() == $user->getGUID()) return true;
 -			
 -			return trigger_plugin_hook('permissions_check',$entity->type,array('entity' => $entity, 'user' => $user),false);
 -		
 -		} else {
 -			
 -			return false;
 -			
 -		}
 -		
 -	}
 -	
 -	/**
 -	 * Gets the URL for an entity, given a particular GUID
 -	 *
 -	 * @param int $entity_guid The GUID of the entity
 -	 * @return string The URL of the entity
 -	 */
 -	function get_entity_url($entity_guid) {
 -		
 -		global $CONFIG;
 -		if ($entity = get_entity($entity_guid)) {
 -
 -			$url = "";
 -			
 -			if (isset($CONFIG->entity_url_handler[$entity->getType()][$entity->getSubType()])) {
 -				$function =  $CONFIG->entity_url_handler[$entity->getType()][$entity->getSubType()];
 -				if (is_callable($function)) {
 -					$url = $function($entity);
 -				}
 -			}
 -			if (isset($CONFIG->entity_url_handler[$entity->getType()]['all'])) {
 -				$function =  $CONFIG->entity_url_handler[$entity->getType()]['all'];
 -				if (is_callable($function)) {
 -					$url = $function($entity);
 -				}
 -			}
 -			if (isset($CONFIG->entity_url_handler['all']['all'])) {
 -				$function =  $CONFIG->entity_url_handler['all']['all'];
 -				if (is_callable($function)) {
 -					$url = $function($entity);
 -				}
 -			}
 -
 -			if ($url == "") {
 -				$url = $CONFIG->url . "pg/view/" . $entity_guid;
 -			}
 -			return $url;
 -			
 -		}
 -		return false;
 -		
 -	}
 -	
 -	/**
 -	 * Sets the URL handler for a particular entity type and subtype
 -	 *
 -	 * @param string $function_name The function to register
 -	 * @param string $entity_type The entity type
 -	 * @param string $entity_subtype The entity subtype
 -	 * @return true|false Depending on success
 -	 */
 -	function register_entity_url_handler($function_name, $entity_type = "all", $entity_subtype = "all") {
 -		global $CONFIG;
 -		
 -		if (!is_callable($function_name)) return false;
 -		
 -		if (!isset($CONFIG->entity_url_handler)) {
 -			$CONFIG->entity_url_handler = array();
 -		}
 -		if (!isset($CONFIG->entity_url_handler[$entity_type])) {
 -			$CONFIG->entity_url_handler[$entity_type] = array();
 -		}
 -		$CONFIG->entity_url_handler[$entity_type][$entity_subtype] = $function_name;
 -		
 -		return true;
 -		
 -	}
 -	
 -	/**
 -	 * Page handler for generic entities view system
 -	 *
 -	 * @param array $page Page elements from pain page handler
 -	 */
 -	function entities_page_handler($page) {
 -		if (isset($page[0])) {
 -			global $CONFIG;
 -			set_input('guid',$page[0]);
 -			@include($CONFIG->path . "entities/index.php");
 -		}
 -	}
 -	
 -	/**
 -	 * Entities init function; establishes the page handler
 -	 *
 -	 */
 -	function entities_init() {
 -		register_page_handler('view','entities_page_handler');
 -	}
 +		 +	} +	 +	/** +	 * Gets the URL for an entity, given a particular GUID +	 * +	 * @param int $entity_guid The GUID of the entity +	 * @return string The URL of the entity +	 */ +	function get_entity_url($entity_guid) { +		 +		global $CONFIG; +		if ($entity = get_entity($entity_guid)) { + +			$url = ""; +			 +			if (isset($CONFIG->entity_url_handler[$entity->getType()][$entity->getSubType()])) { +				$function =  $CONFIG->entity_url_handler[$entity->getType()][$entity->getSubType()]; +				if (is_callable($function)) { +					$url = $function($entity); +				} +			} +			if (isset($CONFIG->entity_url_handler[$entity->getType()]['all'])) { +				$function =  $CONFIG->entity_url_handler[$entity->getType()]['all']; +				if (is_callable($function)) { +					$url = $function($entity); +				} +			} +			if (isset($CONFIG->entity_url_handler['all']['all'])) { +				$function =  $CONFIG->entity_url_handler['all']['all']; +				if (is_callable($function)) { +					$url = $function($entity); +				} +			} + +			if ($url == "") { +				$url = $CONFIG->url . "pg/view/" . $entity_guid; +			} +			return $url; +			 +		} +		return false; +		 +	} +	 +	/** +	 * Sets the URL handler for a particular entity type and subtype +	 * +	 * @param string $function_name The function to register +	 * @param string $entity_type The entity type +	 * @param string $entity_subtype The entity subtype +	 * @return true|false Depending on success +	 */ +	function register_entity_url_handler($function_name, $entity_type = "all", $entity_subtype = "all") { +		global $CONFIG; +		 +		if (!is_callable($function_name)) return false; +		 +		if (!isset($CONFIG->entity_url_handler)) { +			$CONFIG->entity_url_handler = array(); +		} +		if (!isset($CONFIG->entity_url_handler[$entity_type])) { +			$CONFIG->entity_url_handler[$entity_type] = array(); +		} +		$CONFIG->entity_url_handler[$entity_type][$entity_subtype] = $function_name; +		 +		return true; +		 +	} +	 +	/** +	 * Page handler for generic entities view system +	 * +	 * @param array $page Page elements from pain page handler +	 */ +	function entities_page_handler($page) { +		if (isset($page[0])) { +			global $CONFIG; +			set_input('guid',$page[0]); +			@include($CONFIG->path . "entities/index.php"); +		} +	} +	 +	/** +	 * Entities init function; establishes the page handler +	 * +	 */ +	function entities_init() { +		register_page_handler('view','entities_page_handler'); +	}  	/** Register the import hook */  	register_plugin_hook("import", "all", "import_entity_plugin_hook", 0);  	/** Register the hook, ensuring entities are serialised first */ -	register_plugin_hook("export", "all", "export_entity_plugin_hook", 0);
 -	
 -	/** Register init system event **/
 +	register_plugin_hook("export", "all", "export_entity_plugin_hook", 0); +	 +	/** Register init system event **/  	register_event_handler('init','system','entities_init'); -?>
\ No newline at end of file +?> | 
