diff options
Diffstat (limited to 'engine/classes/ElggEntity.php')
| -rw-r--r-- | engine/classes/ElggEntity.php | 807 |
1 files changed, 623 insertions, 184 deletions
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php index 66aca035e..a563f6fad 100644 --- a/engine/classes/ElggEntity.php +++ b/engine/classes/ElggEntity.php @@ -23,8 +23,18 @@ * instead of this class. * * @package Elgg.Core - * @subpackage DataMode.Entities - * @link http://docs.elgg.org/DataModel/ElggEntity + * @subpackage DataModel.Entities + * + * @property string $type object, user, group, or site (read-only after save) + * @property string $subtype Further clarifies the nature of the entity (read-only after save) + * @property int $guid The unique identifier for this entity (read only) + * @property int $owner_guid The GUID of the creator of this entity + * @property int $container_guid The GUID of the entity containing this entity + * @property int $site_guid The GUID of the website this entity is associated with + * @property int $access_id Specifies the visibility level of this entity + * @property int $time_created A UNIX timestamp of when the entity was created (read-only, set on first save) + * @property int $time_updated A UNIX timestamp of when the entity was last updated (automatically updated on save) + * @property-read string $enabled */ abstract class ElggEntity extends ElggData implements Notable, // Calendar interface @@ -55,24 +65,16 @@ abstract class ElggEntity extends ElggData implements protected $temp_annotations = array(); /** - * Volatile data structure for this object, allows for storage of data - * in-memory that isn't sync'd back to the metadata table. + * Holds private settings until entity is saved. Once the entity is saved, + * private settings are written immediately to the database. */ - protected $volatile = array(); + protected $temp_private_settings = array(); /** - * Initialise the attributes array. - * - * This is vital to distinguish between metadata and base parameters. - * - * @return void - * @deprecated 1.8 Use initializeAttributes() + * Volatile data structure for this object, allows for storage of data + * in-memory that isn't sync'd back to the metadata table. */ - protected function initialise_attributes() { - elgg_deprecated_notice('ElggEntity::initialise_attributes() is deprecated by ::initializeAttributes()', 1.8); - - $this->initializeAttributes(); - } + protected $volatile = array(); /** * Initialize the attributes array. @@ -83,20 +85,19 @@ abstract class ElggEntity extends ElggData implements */ protected function initializeAttributes() { parent::initializeAttributes(); - - initialise_entity_cache(); - $this->attributes['guid'] = ""; - $this->attributes['type'] = ""; - $this->attributes['subtype'] = ""; + $this->attributes['guid'] = NULL; + $this->attributes['type'] = NULL; + $this->attributes['subtype'] = NULL; - $this->attributes['owner_guid'] = get_loggedin_userid(); - $this->attributes['container_guid'] = get_loggedin_userid(); + $this->attributes['owner_guid'] = elgg_get_logged_in_user_guid(); + $this->attributes['container_guid'] = elgg_get_logged_in_user_guid(); - $this->attributes['site_guid'] = 0; + $this->attributes['site_guid'] = NULL; $this->attributes['access_id'] = ACCESS_PRIVATE; - $this->attributes['time_updated'] = ""; - $this->attributes['last_action'] = ''; + $this->attributes['time_created'] = NULL; + $this->attributes['time_updated'] = NULL; + $this->attributes['last_action'] = NULL; $this->attributes['enabled'] = "yes"; // There now follows a bit of a hack @@ -138,7 +139,10 @@ abstract class ElggEntity extends ElggData implements return; } - $metadata_array = get_metadata_for_entity($this->guid); + $metadata_array = elgg_get_metadata(array( + 'guid' => $this->guid, + 'limit' => 0 + )); $this->attributes['guid'] = ""; @@ -183,7 +187,7 @@ abstract class ElggEntity extends ElggData implements */ public function get($name) { // See if its in our base attributes - if (isset($this->attributes[$name])) { + if (array_key_exists($name, $this->attributes)) { return $this->attributes[$name]; } @@ -197,8 +201,11 @@ abstract class ElggEntity extends ElggData implements /** * Sets the value of a property. * - * If $name is defined in $this->attributes that value is set, otherwise it will - * set the appropriate item of metadata. + * If $name is defined in $this->attributes that value is set, otherwise it is + * saved as metadata. + * + * @warning Metadata set this way will inherit the entity's owner and access ID. If you want + * to set metadata with a different owner, use create_metadata(). * * @warning It is important that your class populates $this->attributes with keys * for all base attributes, anything not in their gets set as METADATA. @@ -219,7 +226,6 @@ abstract class ElggEntity extends ElggData implements // Certain properties should not be manually changed! switch ($name) { case 'guid': - case 'time_created': case 'time_updated': case 'last_action': return FALSE; @@ -243,21 +249,53 @@ abstract class ElggEntity extends ElggData implements * @return mixed The value, or NULL if not found. */ public function getMetaData($name) { - if ((int) ($this->guid) > 0) { - $md = get_metadata_byname($this->getGUID(), $name); - } else { + $guid = $this->getGUID(); + + if (! $guid) { if (isset($this->temp_metadata[$name])) { - return $this->temp_metadata[$name]; + // md is returned as an array only if more than 1 entry + if (count($this->temp_metadata[$name]) == 1) { + return $this->temp_metadata[$name][0]; + } else { + return $this->temp_metadata[$name]; + } + } else { + return null; } } + // upon first cache miss, just load/cache all the metadata and retry. + // if this works, the rest of this function may not be needed! + $cache = elgg_get_metadata_cache(); + if ($cache->isKnown($guid, $name)) { + return $cache->load($guid, $name); + } else { + $cache->populateFromEntities(array($guid)); + // in case ignore_access was on, we have to check again... + if ($cache->isKnown($guid, $name)) { + return $cache->load($guid, $name); + } + } + + $md = elgg_get_metadata(array( + 'guid' => $guid, + 'metadata_name' => $name, + 'limit' => 0, + )); + + $value = null; + if ($md && !is_array($md)) { - return $md->value; + $value = $md->value; + } elseif (count($md) == 1) { + $value = $md[0]->value; } else if ($md && is_array($md)) { - return metadata_array_to_values($md); + $value = metadata_array_to_values($md); } - return null; + $cache->save($guid, $name, $value); + + return $value; } /** @@ -273,73 +311,136 @@ abstract class ElggEntity extends ElggData implements if (array_key_exists($name, $this->attributes)) { $this->attributes[$name] = ""; } else { - $this->clearMetaData($name); + $this->deleteMetadata($name); } } /** * Set a piece of metadata. * - * @tip Plugin authors should use the magic methods. + * Plugin authors should use the magic methods or create_metadata(). + * + * @warning The metadata will inherit the parent entity's owner and access ID. + * If you want to write metadata with a different owner, use create_metadata(). * * @access private * * @param string $name Name of the metadata - * @param mixed $value Value of the metadata + * @param mixed $value Value of the metadata (doesn't support assoc arrays) * @param string $value_type Types supported: integer and string. Will auto-identify if not set * @param bool $multiple Allow multiple values for a single name (doesn't support assoc arrays) * * @return bool */ - public function setMetaData($name, $value, $value_type = "", $multiple = false) { + public function setMetaData($name, $value, $value_type = null, $multiple = false) { + + // normalize value to an array that we will loop over + // remove indexes if value already an array. if (is_array($value)) { - unset($this->temp_metadata[$name]); - remove_metadata($this->getGUID(), $name); - foreach ($value as $v) { - if ((int) $this->guid > 0) { - $multiple = true; - if (!create_metadata($this->getGUID(), $name, $v, $value_type, - $this->getOwner(), $this->getAccessID(), $multiple)) { - return false; - } - } else { - if (($multiple) && (isset($this->temp_metadata[$name]))) { - if (!is_array($this->temp_metadata[$name])) { - $tmp = $this->temp_metadata[$name]; - $this->temp_metadata[$name] = array(); - $this->temp_metadata[$name][] = $tmp; - } - - $this->temp_metadata[$name][] = $value; - } else { - $this->temp_metadata[$name] = $value; - } + $value = array_values($value); + } else { + $value = array($value); + } + + // saved entity. persist md to db. + if ($this->guid) { + // if overwriting, delete first. + if (!$multiple) { + $options = array( + 'guid' => $this->getGUID(), + 'metadata_name' => $name, + 'limit' => 0 + ); + // @todo in 1.9 make this return false if can't add metadata + // https://github.com/elgg/elgg/issues/4520 + // + // need to remove access restrictions right now to delete + // because this is the expected behavior + $ia = elgg_set_ignore_access(true); + if (false === elgg_delete_metadata($options)) { + return false; } + elgg_set_ignore_access($ia); } - return true; - } else { - unset($this->temp_metadata[$name]); - if ((int) $this->guid > 0) { - $result = create_metadata($this->getGUID(), $name, $value, $value_type, - $this->getOwner(), $this->getAccessID(), $multiple); - return (bool)$result; - } else { - if (($multiple) && (isset($this->temp_metadata[$name]))) { - if (!is_array($this->temp_metadata[$name])) { - $tmp = $this->temp_metadata[$name]; - $this->temp_metadata[$name] = array(); - $this->temp_metadata[$name][] = $tmp; - } - - $this->temp_metadata[$name][] = $value; - } else { - $this->temp_metadata[$name] = $value; + // add new md + $result = true; + foreach ($value as $value_tmp) { + // at this point $value should be appended because it was cleared above if needed. + $md_id = create_metadata($this->getGUID(), $name, $value_tmp, $value_type, + $this->getOwnerGUID(), $this->getAccessId(), true); + if (!$md_id) { + return false; } + } - return true; + return $result; + } else { + // unsaved entity. store in temp array + // returning single entries instead of an array of 1 element is decided in + // getMetaData(), just like pulling from the db. + // + // if overwrite, delete first + if (!$multiple || !isset($this->temp_metadata[$name])) { + $this->temp_metadata[$name] = array(); } + + // add new md + $this->temp_metadata[$name] = array_merge($this->temp_metadata[$name], $value); + return true; + } + } + + /** + * Deletes all metadata on this object (metadata.entity_guid = $this->guid). + * If you pass a name, only metadata matching that name will be deleted. + * + * @warning Calling this with no $name will clear all metadata on the entity. + * + * @param null|string $name The name of the metadata to remove. + * @return bool + * @since 1.8 + */ + public function deleteMetadata($name = null) { + + if (!$this->guid) { + return false; } + + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['metadata_name'] = $name; + } + + return elgg_delete_metadata($options); + } + + /** + * Deletes all metadata owned by this object (metadata.owner_guid = $this->guid). + * If you pass a name, only metadata matching that name will be deleted. + * + * @param null|string $name The name of metadata to delete. + * @return bool + * @since 1.8 + */ + public function deleteOwnedMetadata($name = null) { + // access is turned off for this because they might + // no longer have access to an entity they created metadata on. + $ia = elgg_set_ignore_access(true); + $options = array( + 'metadata_owner_guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['metadata_name'] = $name; + } + + $r = elgg_delete_metadata($options); + elgg_set_ignore_access($ia); + return $r; } /** @@ -348,17 +449,53 @@ abstract class ElggEntity extends ElggData implements * @warning Calling this with no or empty arguments will clear all metadata on the entity. * * @param string $name The name of the metadata to clear - * * @return mixed bool + * @deprecated 1.8 Use deleteMetadata() */ - public function clearMetaData($name = "") { - if (empty($name)) { - return clear_metadata($this->getGUID()); - } else { - return remove_metadata($this->getGUID(), $name); + public function clearMetaData($name = '') { + elgg_deprecated_notice('ElggEntity->clearMetadata() is deprecated by ->deleteMetadata()', 1.8); + return $this->deleteMetadata($name); + } + + /** + * Disables metadata for this entity, optionally based on name. + * + * @param string $name An options name of metadata to disable. + * @return bool + * @since 1.8 + */ + public function disableMetadata($name = '') { + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['metadata_name'] = $name; } + + return elgg_disable_metadata($options); } + /** + * Enables metadata for this entity, optionally based on name. + * + * @warning Before calling this, you must use {@link access_show_hidden_entities()} + * + * @param string $name An options name of metadata to enable. + * @return bool + * @since 1.8 + */ + public function enableMetadata($name = '') { + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['metadata_name'] = $name; + } + + return elgg_enable_metadata($options); + } /** * Get a piece of volatile (non-persisted) data on this entity. @@ -379,7 +516,6 @@ abstract class ElggEntity extends ElggData implements } } - /** * Set a piece of volatile (non-persisted) data on this entity * @@ -396,7 +532,6 @@ abstract class ElggEntity extends ElggData implements $this->volatile[$name] = $value; } - /** * Remove all relationships to and from this entity. * @@ -405,13 +540,26 @@ abstract class ElggEntity extends ElggData implements * @see ElggEntity::addRelationship() * @see ElggEntity::removeRelationship() */ - public function clearRelationships() { + public function deleteRelationships() { remove_entity_relationships($this->getGUID()); remove_entity_relationships($this->getGUID(), "", true); return true; } /** + * Remove all relationships to and from this entity. + * + * @return bool + * @see ElggEntity::addRelationship() + * @see ElggEntity::removeRelationship() + * @deprecated 1.8 Use ->deleteRelationship() + */ + public function clearRelationships() { + elgg_deprecated_notice('ElggEntity->clearRelationships() is deprecated by ->deleteRelationships()', 1.8); + return $this->deleteRelationships(); + } + + /** * Add a relationship between this an another entity. * * @tip Read the relationship like "$guid is a $relationship of this entity." @@ -451,10 +599,14 @@ abstract class ElggEntity extends ElggData implements * @param mixed $value Value of private setting * * @return bool - * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings */ function setPrivateSetting($name, $value) { - return set_private_setting($this->getGUID(), $name, $value); + if ((int) $this->guid > 0) { + return set_private_setting($this->getGUID(), $name, $value); + } else { + $this->temp_private_settings[$name] = $value; + return true; + } } /** @@ -465,7 +617,14 @@ abstract class ElggEntity extends ElggData implements * @return mixed */ function getPrivateSetting($name) { - return get_private_setting($this->getGUID(), $name); + if ((int) ($this->guid) > 0) { + return get_private_setting($this->getGUID(), $name); + } else { + if (isset($this->temp_private_settings[$name])) { + return $this->temp_private_settings[$name]; + } + } + return null; } /** @@ -480,10 +639,117 @@ abstract class ElggEntity extends ElggData implements } /** + * Deletes all annotations on this object (annotations.entity_guid = $this->guid). + * If you pass a name, only annotations matching that name will be deleted. + * + * @warning Calling this with no or empty arguments will clear all annotations on the entity. + * + * @param null|string $name The annotations name to remove. + * @return bool + * @since 1.8 + */ + public function deleteAnnotations($name = null) { + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['annotation_name'] = $name; + } + + return elgg_delete_annotations($options); + } + + /** + * Deletes all annotations owned by this object (annotations.owner_guid = $this->guid). + * If you pass a name, only annotations matching that name will be deleted. + * + * @param null|string $name The name of annotations to delete. + * @return bool + * @since 1.8 + */ + public function deleteOwnedAnnotations($name = null) { + // access is turned off for this because they might + // no longer have access to an entity they created annotations on. + $ia = elgg_set_ignore_access(true); + $options = array( + 'annotation_owner_guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['annotation_name'] = $name; + } + + $r = elgg_delete_annotations($options); + elgg_set_ignore_access($ia); + return $r; + } + + /** + * Disables annotations for this entity, optionally based on name. + * + * @param string $name An options name of annotations to disable. + * @return bool + * @since 1.8 + */ + public function disableAnnotations($name = '') { + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['annotation_name'] = $name; + } + + return elgg_disable_annotations($options); + } + + /** + * Enables annotations for this entity, optionally based on name. + * + * @warning Before calling this, you must use {@link access_show_hidden_entities()} + * + * @param string $name An options name of annotations to enable. + * @return bool + * @since 1.8 + */ + public function enableAnnotations($name = '') { + $options = array( + 'guid' => $this->guid, + 'limit' => 0 + ); + if ($name) { + $options['annotation_name'] = $name; + } + + return elgg_enable_annotations($options); + } + + /** + * Helper function to return annotation calculation results + * + * @param string $name The annotation name. + * @param string $calculation A valid MySQL function to run its values through + * @return mixed + */ + private function getAnnotationCalculation($name, $calculation) { + $options = array( + 'guid' => $this->getGUID(), + 'annotation_name' => $name, + 'annotation_calculation' => $calculation + ); + + return elgg_get_annotations($options); + } + + /** * Adds an annotation to an entity. * * @warning By default, annotations are private. * + * @warning Annotating an unsaved entity more than once with the same name + * will only save the last annotation. + * * @param string $name Annotation name * @param mixed $value Annotation value * @param int $access_id Access ID @@ -491,8 +757,6 @@ abstract class ElggEntity extends ElggData implements * @param string $vartype The type of annotation value * * @return bool - * - * @link http://docs.elgg.org/DataModel/Annotations */ function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_id = 0, $vartype = "") { if ((int) $this->guid > 0) { @@ -509,15 +773,29 @@ abstract class ElggEntity extends ElggData implements * @param string $name Annotation name * @param int $limit Limit * @param int $offset Offset - * @param string $order asc or desc + * @param string $order Order by time: asc or desc * * @return array */ function getAnnotations($name, $limit = 50, $offset = 0, $order = "asc") { if ((int) ($this->guid) > 0) { - return get_annotations($this->getGUID(), "", "", $name, "", 0, $limit, $offset, $order); + + $options = array( + 'guid' => $this->guid, + 'annotation_name' => $name, + 'limit' => $limit, + 'offset' => $offset, + ); + + if ($order != 'asc') { + $options['reverse_order_by'] = true; + } + + return elgg_get_annotations($options); + } else if (isset($this->temp_annotations[$name])) { + return array($this->temp_annotations[$name]); } else { - return $this->temp_annotations[$name]; + return array(); } } @@ -528,11 +806,12 @@ abstract class ElggEntity extends ElggData implements * all annotations on the entity. * * @param string $name Annotation name - * * @return bool + * @deprecated 1.8 Use ->deleteAnnotations() */ function clearAnnotations($name = "") { - return clear_annotations($this->getGUID(), $name); + elgg_deprecated_notice('ElggEntity->clearAnnotations() is deprecated by ->deleteAnnotations()', 1.8); + return $this->deleteAnnotations($name); } /** @@ -543,7 +822,7 @@ abstract class ElggEntity extends ElggData implements * @return int */ function countAnnotations($name = "") { - return count_annotations($this->getGUID(), "", "", $name); + return $this->getAnnotationCalculation($name, 'count'); } /** @@ -554,7 +833,7 @@ abstract class ElggEntity extends ElggData implements * @return int */ function getAnnotationsAvg($name) { - return get_annotations_avg($this->getGUID(), "", "", $name); + return $this->getAnnotationCalculation($name, 'avg'); } /** @@ -565,7 +844,7 @@ abstract class ElggEntity extends ElggData implements * @return int */ function getAnnotationsSum($name) { - return get_annotations_sum($this->getGUID(), "", "", $name); + return $this->getAnnotationCalculation($name, 'sum'); } /** @@ -576,7 +855,7 @@ abstract class ElggEntity extends ElggData implements * @return int */ function getAnnotationsMin($name) { - return get_annotations_min($this->getGUID(), "", "", $name); + return $this->getAnnotationCalculation($name, 'min'); } /** @@ -587,7 +866,24 @@ abstract class ElggEntity extends ElggData implements * @return int */ function getAnnotationsMax($name) { - return get_annotations_max($this->getGUID(), "", "", $name); + return $this->getAnnotationCalculation($name, 'max'); + } + + /** + * Count the number of comments attached to this entity. + * + * @return int Number of comments + * @since 1.8.0 + */ + function countComments() { + $params = array('entity' => $this); + $num = elgg_trigger_plugin_hook('comments:count', $this->getType(), $params); + + if (is_int($num)) { + return $num; + } else { + return $this->getAnnotationCalculation('generic_comment', 'count'); + } } /** @@ -644,19 +940,19 @@ abstract class ElggEntity extends ElggData implements * @param ElggMetadata $metadata The piece of metadata to specifically check * @param int $user_guid The user GUID, optionally (default: logged in user) * - * @return true|false + * @return bool */ function canEditMetadata($metadata = null, $user_guid = 0) { return can_edit_entity_metadata($this->getGUID(), $user_guid, $metadata); } /** - * Can a user write to this entity + * Can a user add an entity to this container + * + * @param int $user_guid The user. + * @param string $type The type of entity we're looking to write + * @param string $subtype The subtype of the entity we're looking to write * - * @param int $user_guid The user. - * @param string $type The type of entity we're looking to write - * @param string $subtype The subtype of the entity we're looking to write - * * @return bool */ public function canWriteToContainer($user_guid = 0, $type = 'all', $subtype = 'all') { @@ -664,6 +960,61 @@ abstract class ElggEntity extends ElggData implements } /** + * Can a user comment on an entity? + * + * @tip Can be overridden by registering for the permissions_check:comment, + * <entity type> plugin hook. + * + * @param int $user_guid User guid (default is logged in user) + * + * @return bool + */ + public function canComment($user_guid = 0) { + if ($user_guid == 0) { + $user_guid = elgg_get_logged_in_user_guid(); + } + $user = get_entity($user_guid); + + // By default, we don't take a position of whether commenting is allowed + // because it is handled by the subclasses of ElggEntity + $params = array('entity' => $this, 'user' => $user); + return elgg_trigger_plugin_hook('permissions_check:comment', $this->type, $params, null); + } + + /** + * Can a user annotate an entity? + * + * @tip Can be overridden by registering for the permissions_check:annotate, + * <entity type> plugin hook. + * + * @tip If you want logged out users to annotate an object, do not call + * canAnnotate(). It's easier than using the plugin hook. + * + * @param int $user_guid User guid (default is logged in user) + * @param string $annotation_name The name of the annotation (default is unspecified) + * + * @return bool + */ + public function canAnnotate($user_guid = 0, $annotation_name = '') { + if ($user_guid == 0) { + $user_guid = elgg_get_logged_in_user_guid(); + } + $user = get_entity($user_guid); + + $return = true; + if (!$user) { + $return = false; + } + + $params = array( + 'entity' => $this, + 'user' => $user, + 'annotation_name' => $annotation_name, + ); + return elgg_trigger_plugin_hook('permissions_check:annotate', $this->type, $params, $return); + } + + /** * Returns the access_id. * * @return int The access ID @@ -675,7 +1026,7 @@ abstract class ElggEntity extends ElggData implements /** * Returns the guid. * - * @return int GUID + * @return int|null GUID */ public function getGUID() { return $this->get('guid'); @@ -707,18 +1058,29 @@ abstract class ElggEntity extends ElggData implements } /** + * Get the guid of the entity's owner. + * + * @return int The owner GUID + */ + public function getOwnerGUID() { + return $this->owner_guid; + } + + /** * Return the guid of the entity's owner. * * @return int The owner GUID + * @deprecated 1.8 Use getOwnerGUID() */ public function getOwner() { - return $this->owner_guid; + elgg_deprecated_notice("ElggEntity::getOwner deprecated for ElggEntity::getOwnerGUID", 1.8); + return $this->getOwnerGUID(); } /** - * Returns the ElggEntity or child object of the owner of the entity. + * Gets the ElggEntity that owns this entity. * - * @return ElggEntity The owning user + * @return ElggEntity The owning entity */ public function getOwnerEntity() { return get_entity($this->owner_guid); @@ -731,30 +1093,57 @@ abstract class ElggEntity extends ElggData implements * * @return bool */ + public function setContainerGUID($container_guid) { + $container_guid = (int)$container_guid; + + return $this->set('container_guid', $container_guid); + } + + /** + * Set the container for this object. + * + * @param int $container_guid The ID of the container. + * + * @return bool + * @deprecated 1.8 use setContainerGUID() + */ public function setContainer($container_guid) { + elgg_deprecated_notice("ElggObject::setContainer deprecated for ElggEntity::setContainerGUID", 1.8); $container_guid = (int)$container_guid; return $this->set('container_guid', $container_guid); } /** - * Returns the container GUID of this object. + * Gets the container GUID for this entity. * * @return int */ + public function getContainerGUID() { + return $this->get('container_guid'); + } + + /** + * Gets the container GUID for this entity. + * + * @return int + * @deprecated 1.8 Use getContainerGUID() + */ public function getContainer() { + elgg_deprecated_notice("ElggObject::getContainer deprecated for ElggEntity::getContainerGUID", 1.8); return $this->get('container_guid'); } /** - * Returns the container entity for this object. + * Get the container entity for this object. * * @return ElggEntity + * @since 1.8.0 */ public function getContainerEntity() { - return get_entity($this->getContainer()); + return get_entity($this->getContainerGUID()); } - + /** * Returns the UNIX epoch time that this entity was last updated * @@ -793,18 +1182,49 @@ abstract class ElggEntity extends ElggData implements } /** + * Get the URL for this entity's icon + * + * Plugins can register for the 'entity:icon:url', <type> plugin hook + * to customize the icon for an entity. + * + * @param string $size Size of the icon: tiny, small, medium, large + * + * @return string The URL + * @since 1.8.0 + */ + public function getIconURL($size = 'medium') { + $size = elgg_strtolower($size); + + if (isset($this->icon_override[$size])) { + elgg_deprecated_notice("icon_override on an individual entity is deprecated", 1.8); + return $this->icon_override[$size]; + } + + $type = $this->getType(); + $params = array( + 'entity' => $this, + 'size' => $size, + ); + + $url = elgg_trigger_plugin_hook('entity:icon:url', $type, $params, null); + if ($url == null) { + $url = "_graphics/icons/default/$size.png"; + } + + return elgg_normalize_url($url); + } + + /** * Returns a URL for the entity's icon. * * @param string $size Either 'large', 'medium', 'small' or 'tiny' * * @return string The url or false if no url could be worked out. - * @see get_entity_icon_url() + * @deprecated Use getIconURL() */ public function getIcon($size = 'medium') { - if (isset($this->icon_override[$size])) { - return $this->icon_override[$size]; - } - return get_entity_icon_url($this, $size); + elgg_deprecated_notice("getIcon() deprecated by getIconURL()", 1.8); + return $this->getIconURL($size); } /** @@ -816,8 +1236,11 @@ abstract class ElggEntity extends ElggData implements * @param string $size The size its for. * * @return bool + * @deprecated 1.8 See getIconURL() for the plugin hook to use */ public function setIcon($url, $size = 'medium') { + elgg_deprecated_notice("icon_override on an individual entity is deprecated", 1.8); + $url = sanitise_string($url); $size = sanitise_string($size); @@ -839,22 +1262,31 @@ abstract class ElggEntity extends ElggData implements } /** - * Save attributes to the entities table. + * Save an entity. * - * @return bool + * @return bool|int * @throws IOException */ public function save() { - $guid = (int) $this->guid; + $guid = $this->getGUID(); if ($guid > 0) { - cache_entity($this); - return update_entity( - $this->get('guid'), + // See #5600. This ensures the lower level can_edit_entity() check will use a + // fresh entity from the DB so it sees the persisted owner_guid + _elgg_disable_caching_for_entity($guid); + + $ret = update_entity( + $guid, $this->get('owner_guid'), $this->get('access_id'), - $this->get('container_guid') + $this->get('container_guid'), + $this->get('time_created') ); + + _elgg_enable_caching_for_entity($guid); + _elgg_cache_entity($this); + + return $ret; } else { // Create a new entity (nb: using attribute array directly // 'cos set function does something special!) @@ -876,8 +1308,7 @@ abstract class ElggEntity extends ElggData implements } } - // Save any unsaved annotations metadata. - // @todo How to capture extra information (access id etc) + // Save any unsaved annotations. if (sizeof($this->temp_annotations) > 0) { foreach ($this->temp_annotations as $name => $value) { $this->annotate($name, $value); @@ -885,14 +1316,19 @@ abstract class ElggEntity extends ElggData implements } } + // Save any unsaved private settings. + if (sizeof($this->temp_private_settings) > 0) { + foreach ($this->temp_private_settings as $name => $value) { + $this->setPrivateSetting($name, $value); + unset($this->temp_private_settings[$name]); + } + } + // set the subtype to id now rather than a string $this->attributes['subtype'] = get_subtype_id($this->attributes['type'], $this->attributes['subtype']); - // Cache object handle - if ($this->attributes['guid']) { - cache_entity($this); - } + _elgg_cache_entity($this); return $this->attributes['guid']; } @@ -901,12 +1337,16 @@ abstract class ElggEntity extends ElggData implements /** * Loads attributes from the entities table into the object. * - * @param int $guid GUID of Entity + * @param mixed $guid GUID of entity or stdClass object from entities table * * @return bool */ protected function load($guid) { - $row = get_entity_as_row($guid); + if ($guid instanceof stdClass) { + $row = $guid; + } else { + $row = get_entity_as_row($guid); + } if ($row) { // Create the array if necessary - all subclasses should test before creating @@ -925,9 +1365,12 @@ abstract class ElggEntity extends ElggData implements $this->attributes['tables_loaded']++; } + // guid needs to be an int https://github.com/elgg/elgg/issues/4111 + $this->attributes['guid'] = (int)$this->attributes['guid']; + // Cache object handle if ($this->attributes['guid']) { - cache_entity($this); + _elgg_cache_entity($this); } return true; @@ -996,10 +1439,12 @@ abstract class ElggEntity extends ElggData implements /** * Delete this entity. * + * @param bool $recursive Whether to delete all the entities contained by this entity + * * @return bool */ - public function delete() { - return delete_entity($this->get('guid')); + public function delete($recursive = true) { + return delete_entity($this->get('guid'), $recursive); } /* @@ -1007,19 +1452,25 @@ abstract class ElggEntity extends ElggData implements */ /** + * Gets the 'location' metadata for the entity + * + * @return string The location + */ + public function getLocation() { + return $this->location; + } + + /** * Sets the 'location' metadata for the entity * * @todo Unimplemented * * @param string $location String representation of the location * - * @return true + * @return bool */ public function setLocation($location) { - $location = sanitise_string($location); - $this->location = $location; - return true; } @@ -1029,13 +1480,10 @@ abstract class ElggEntity extends ElggData implements * @param float $lat Latitude * @param float $long Longitude * - * @return true + * @return bool * @todo Unimplemented */ public function setLatLong($lat, $long) { - $lat = sanitise_string($lat); - $long = sanitise_string($long); - $this->set('geo:lat', $lat); $this->set('geo:long', $long); @@ -1045,29 +1493,20 @@ abstract class ElggEntity extends ElggData implements /** * Return the entity's latitude. * - * @return int + * @return float * @todo Unimplemented */ public function getLatitude() { - return $this->get('geo:lat'); + return (float)$this->get('geo:lat'); } /** * Return the entity's longitude * - * @return Int + * @return float */ public function getLongitude() { - return $this->get('geo:long'); - } - - /** - * Return the entity's location - * - * @return string - */ - public function getLocation() { - return $this->get('location'); + return (float)$this->get('geo:long'); } /* @@ -1174,36 +1613,36 @@ abstract class ElggEntity extends ElggData implements foreach ($this->attributes as $k => $v) { $meta = NULL; - if (in_array( $k, $exportable_values)) { + if (in_array($k, $exportable_values)) { switch ($k) { - case 'guid' : // Dont use guid in OpenDD - case 'type' : // Type and subtype already taken care of - case 'subtype' : - break; + case 'guid': // Dont use guid in OpenDD + case 'type': // Type and subtype already taken care of + case 'subtype': + break; - case 'time_created' : // Created = published + case 'time_created': // Created = published $odd->setAttribute('published', date("r", $v)); - break; + break; - case 'site_guid' : // Container + case 'site_guid': // Container $k = 'site_uuid'; $v = guid_to_uuid($v); $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v); - break; + break; - case 'container_guid' : // Container + case 'container_guid': // Container $k = 'container_uuid'; $v = guid_to_uuid($v); $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v); - break; + break; - case 'owner_guid' : // Convert owner guid to uuid, this will be stored in metadata + case 'owner_guid': // Convert owner guid to uuid, this will be stored in metadata $k = 'owner_uuid'; $v = guid_to_uuid($v); $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v); - break; + break; - default : + default: $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v); } @@ -1221,7 +1660,7 @@ abstract class ElggEntity extends ElggData implements */ elgg_set_viewtype('default'); - $view = elgg_view_entity($this, true); + $view = elgg_view_entity($this, array('full_view' => true)); elgg_set_viewtype(); $tmp[] = new ODDMetaData($uuid . "volatile/renderedentity/", $uuid, @@ -1237,9 +1676,11 @@ abstract class ElggEntity extends ElggData implements /** * Import data from an parsed ODD xml data array. * - * @param array $data XML data + * @param ODD $data XML data * * @return true + * + * @throws InvalidParameterException */ public function import(ODD $data) { if (!($data instanceof ODDEntity)) { @@ -1251,7 +1692,7 @@ abstract class ElggEntity extends ElggData implements $this->attributes['subtype'] = $data->getAttribute('subclass'); // Set owner - $this->attributes['owner_guid'] = get_loggedin_userid(); // Import as belonging to importer. + $this->attributes['owner_guid'] = elgg_get_logged_in_user_guid(); // Import as belonging to importer. // Set time $this->attributes['time_created'] = strtotime($data->getAttribute('published')); @@ -1301,8 +1742,6 @@ abstract class ElggEntity extends ElggData implements * @return array */ public function getTags($tag_names = NULL) { - global $CONFIG; - if ($tag_names && !is_array($tag_names)) { $tag_names = array($tag_names); } @@ -1328,4 +1767,4 @@ abstract class ElggEntity extends ElggData implements return $entity_tags; } -}
\ No newline at end of file +} |
