diff options
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 +?> |