diff --git a/includes/entity.wrapper.inc b/includes/entity.wrapper.inc index 4a0327c..f55fc9c 100644 --- a/includes/entity.wrapper.inc +++ b/includes/entity.wrapper.inc @@ -6,9 +6,138 @@ */ /** + * Interface EntityMetadataWrapperInterface + */ +interface EntityMetadataWrapperInterface { + + /** + * Gets info about the wrapped data. + * + * @return array + * Keys set are all keys as specified for a property in hook_entity_info() + * as well as possible the following keys: + * - name: If this wraps a property, the name of the property. + * - parent: The parent wrapper, if any. + * - langcode: The language code, if this data is language specific. + */ + public function info(); + + /** + * Gets the (entity)type of the wrapped data. + */ + public function type(); + + /** + * Returns the wrapped data. + * + * If no options are given the data is returned as described in the info. + * + * @param array $options + * (optional) A keyed array of options: + * - sanitize: A boolean flag indicating that textual properties should be + * sanitized for display to a web browser. Defaults to FALSE. + * - decode: If set to TRUE and some textual data is already sanitized, it + * strips HTML tags and decodes HTML entities. Defaults to FALSE. + * + * @return mixed + * The value of the wrapped data. If the data property is not set, NULL + * is returned. + * + * @throws EntityMetadataWrapperException + * In case there are no data values available to the wrapper, an exception + * is thrown. E.g. if the value for an entity property is to be retrieved + * and there is no entity available, the exception is thrown. However, if + * an entity is available but the property is not set, NULL is returned. + */ + public function value(array $options = array()); + + /** + * Returns the raw, unprocessed data. + * + * Most times this is the same as returned by value(), however for already + * processed and sanitized textual data, this will return the unprocessed data + * in contrast to value(). + */ + public function raw(); + + /** + * Set a new data value. + * + * @param mixed $value + * The value to set. + */ + public function set($value); + + /** + * Returns whether $value is a valid value to set. + * + * @param mixed $value + * The value to validate. + * + * @return bool + * TRUE if the value passes validation. FALSE otherwise. + */ + public function validate($value); + + /** + * Returns the options list. + * + * It also species possible values for the property, if defined. + * + * @param string $op + * (optional) One of 'edit' or 'view'. In case the list of possible values + * a user could set for a property differs from the list of values a + * property could have, $op determines which options should be returned. + * Defaults to 'edit'. + * E.g. all possible roles a user could have include the anonymous and the + * authenticated user roles, while those roles cannot be added to a user + * account. So their options would be included for 'view', but for 'edit' + * not. + * + * @return array + * An array as used by hook_options_list() or FALSE. + */ + public function optionsList($op = 'edit'); + + /** + * Returns the label for the currently set property value. + * + * It will only be returned if there is one available, i.e. if an options list + * has been specified. + * + * @return string + * The label. + */ + public function label(); + + /** + * Determines whether the given user has access to view or edit this property. + * + * Apart from relying on access metadata of properties, this takes into + * account information about entity level access, if available: + * - Referenced entities can only be viewed, when the user also has + * permission to view the entity. + * - A property may be only edited, if the user has permission to update the + * entity containing the property. + * + * @param string $op + * The operation being performed. One of 'view' or 'edit. + * @param object $account + * The user to check for. Leave it to NULL to check for the global user. + * @return bool + * Whether access to entity property is allowed for the given operation. + * However if we wrap no data, it returns whether access is allowed to the + * property of all entities of this type. + * If there is no access information for this property, TRUE is returned. + */ + public function access($op, $account = NULL); + +} + +/** * A common base class for all wrappers. */ -abstract class EntityMetadataWrapper { +abstract class EntityMetadataWrapper implements EntityMetadataWrapperInterface { protected $type; protected $data; @@ -37,46 +166,21 @@ abstract class EntityMetadataWrapper { } /** - * Gets info about the wrapped data. - * - * @return Array - * Keys set are all keys as specified for a property in hook_entity_info() - * as well as possible the following keys: - * - name: If this wraps a property, the name of the property. - * - parent: The parent wrapper, if any. - * - langcode: The language code, if this data is language specific. + * {@inheritdoc} */ public function info() { return $this->info; } /** - * Gets the (entity)type of the wrapped data. + * {@inheritdoc} */ public function type() { return $this->type; } /** - * Returns the wrapped data. If no options are given the data is returned as - * described in the info. - * - * @param $options - * (optional) A keyed array of options: - * - sanitize: A boolean flag indicating that textual properties should be - * sanitized for display to a web browser. Defaults to FALSE. - * - decode: If set to TRUE and some textual data is already sanitized, it - * strips HTML tags and decodes HTML entities. Defaults to FALSE. - * - * @return - * The value of the wrapped data. If the data property is not set, NULL - * is returned. - * - * @throws EntityMetadataWrapperException - * In case there are no data values available to the wrapper, an exception - * is thrown. E.g. if the value for an entity property is to be retrieved - * and there is no entity available, the exception is thrown. However, if - * an entity is available but the property is not set, NULL is returned. + * {@inheritdoc} */ public function value(array $options = array()) { if (!$this->dataAvailable() && isset($this->info['parent'])) { @@ -89,9 +193,7 @@ abstract class EntityMetadataWrapper { } /** - * Returns the raw, unprocessed data. Most times this is the same as returned - * by value(), however for already processed and sanitized textual data, this - * will return the unprocessed data in contrast to value(). + * {@inheritdoc} */ public function raw() { if (!$this->dataAvailable()) { @@ -107,7 +209,7 @@ abstract class EntityMetadataWrapper { /** * Returns whether data is available to work with. * - * @return + * @return bool * If we operate without any data FALSE, else TRUE. */ protected function dataAvailable() { @@ -115,7 +217,7 @@ abstract class EntityMetadataWrapper { } /** - * Set a new data value. + * {@inheritdoc} */ public function set($value) { if (!$this->validate($value)) { @@ -128,7 +230,9 @@ abstract class EntityMetadataWrapper { } /** - * Updates the parent data structure of a data property with the latest data value. + * Updates the parent data structure of a data property. + * + * It will set the latest data value. */ protected function updateParent($value) { if (isset($this->info['parent'])) { @@ -137,7 +241,7 @@ abstract class EntityMetadataWrapper { } /** - * Returns whether $value is a valid value to set. + * {@inheritdoc} */ public function validate($value) { if (isset($value) && !entity_property_verify_data_type($value, $this->type)) { @@ -170,21 +274,7 @@ abstract class EntityMetadataWrapper { } /** - * Returns the options list specifying possible values for the property, if - * defined. - * - * @param $op - * (optional) One of 'edit' or 'view'. In case the list of possible values - * a user could set for a property differs from the list of values a - * property could have, $op determines which options should be returned. - * Defaults to 'edit'. - * E.g. all possible roles a user could have include the anonymous and the - * authenticated user roles, while those roles cannot be added to a user - * account. So their options would be included for 'view', but for 'edit' - * not. - * - * @return - * An array as used by hook_options_list() or FALSE. + * {@inheritdoc} */ public function optionsList($op = 'edit') { if (isset($this->info['options list']) && is_callable($this->info['options list'])) { @@ -195,8 +285,7 @@ abstract class EntityMetadataWrapper { } /** - * Returns the label for the currently set property value if there is one - * available, i.e. if an options list has been specified. + * {@inheritdoc} */ public function label() { if ($options = $this->optionsList('view')) { @@ -209,23 +298,7 @@ abstract class EntityMetadataWrapper { } /** - * Determines whether the given user has access to view or edit this property. - * Apart from relying on access metadata of properties, this takes into - * account information about entity level access, if available: - * - Referenced entities can only be viewed, when the user also has - * permission to view the entity. - * - A property may be only edited, if the user has permission to update the - * entity containing the property. - * - * @param $op - * The operation being performed. One of 'view' or 'edit. - * @param $account - * The user to check for. Leave it to NULL to check for the global user. - * @return boolean - * Whether access to entity property is allowed for the given operation. - * However if we wrap no data, it returns whether access is allowed to the - * property of all entities of this type. - * If there is no access information for this property, TRUE is returned. + * {@inheritdoc} */ public function access($op, $account = NULL) { return !empty($this->info['parent']) ? $this->info['parent']->propertyAccess($this->info['name'], $op, $account) : TRUE; @@ -267,10 +340,91 @@ class EntityValueWrapper extends EntityMetadataWrapper { } /** + * Interface EntityStructureWrapperInterface. + */ +interface EntityStructureWrapperInterface extends EntityMetadataWrapperInterface { + + /** + * Gets the info about the given property. + * + * @param string $name + * The name of the property. If not given, info about all properties will + * be returned. + * + * @throws EntityMetadataWrapperException + * If there is no such property. + * + * @return array + * An array of info about the property. + */ + public function getPropertyInfo($name = NULL); + + /** + * Returns a reference on the property info. + * + * If possible, use the property info alter callback for spotting metadata. + * The reference may be used to alter the property info for any remaining + * cases, e.g. if additional metadata has been asserted. + * + * @return &array + * The reference on the property info. + */ + public function &refPropertyInfo(); + + /** + * Sets a new language to use for retrieving properties. + * + * @param $langcode + * The language code of the language to set. + * + * @return EntityStructureWrapper + * The structure wrapper. + */ + public function language($langcode = LANGUAGE_NONE); + + /** + * Gets the language used for retrieving properties. + * + * @return object + * The language object of the language or NULL for the default language. + * + * @see EntityStructureWrapper::language() + */ + public function getPropertyLanguage(); + + /** + * Get the wrapper for a property. + * + * @return EntityMetadataWrapper + * An instance of EntityMetadataWrapper. + */ + public function get($name); + + /** + * Returns an iterator on the structure items. + * + * @return EntityMetadataWrapperIterator + * The iterator. + */ + public function getIterator(); + + /** + * Returns the identifier of the data structure. + * + * If there is none, NULL is returned. + * + * @return mixed + * The identifier. + */ + public function getIdentifier(); + +} + +/** * Provides a general wrapper for any data structure. For this to work the * metadata has to be passed during construction. */ -class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAggregate { +class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAggregate, EntityStructureWrapperInterface { protected $propertyInfo = array(), $propertyInfoAltered = FALSE; protected $langcode = LANGUAGE_NONE; @@ -316,15 +470,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg } /** - * Gets the info about the given property. - * - * @param $name - * The name of the property. If not given, info about all properties will - * be returned. - * @throws EntityMetadataWrapperException - * If there is no such property. - * @return - * An array of info about the property. + * {@inheritdoc} */ public function getPropertyInfo($name = NULL) { $this->spotInfo(); @@ -338,22 +484,14 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg } /** - * Returns a reference on the property info. - * - * If possible, use the property info alter callback for spotting metadata. - * The reference may be used to alter the property info for any remaining - * cases, e.g. if additional metadata has been asserted. + * {@inheritdoc} */ public function &refPropertyInfo() { return $this->propertyInfo; } /** - * Sets a new language to use for retrieving properties. - * - * @param $langcode - * The language code of the language to set. - * @return EntityWrapper + * {@inheritdoc} */ public function language($langcode = LANGUAGE_NONE) { if ($langcode != $this->langcode) { @@ -364,12 +502,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg } /** - * Gets the language used for retrieving properties. - * - * @return String - * The language object of the language or NULL for the default language. - * - * @see EntityStructureWrapper::language() + * {@inheritdoc} */ public function getPropertyLanguage() { if ($this->langcode != LANGUAGE_NONE && $list = language_list()) { @@ -381,10 +514,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg } /** - * Get the wrapper for a property. - * - * @return - * An instance of EntityMetadataWrapper. + * {@inheritdoc} */ public function get($name) { // Look it up in the cache if possible. @@ -526,14 +656,16 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg return isset($this->propertyInfo['properties'][$name]); } + /** + * {@inheritdoc} + */ public function getIterator() { $this->spotInfo(); return new EntityMetadataWrapperIterator($this, array_keys($this->propertyInfo['properties'])); } /** - * Returns the identifier of the data structure. If there is none, NULL is - * returned. + * {@inheritdoc} */ public function getIdentifier() { return isset($this->id) && $this->dataAvailable() ? $this->id->value() : NULL; @@ -555,12 +687,95 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg } /** + * Interface EntityDrupalWrapperInterface. + */ +interface EntityDrupalWrapperInterface extends EntityStructureWrapperInterface { + + /** + * Returns the identifier of the wrapped entity. + * + * @return mixed + * The identifier. + * + * @see entity_id() + */ + public function getIdentifier(); + + /** + * Returns the bundle of an entity, or FALSE if it has no bundles. + * + * @return string|bool + * The bundle or FALSE. + */ + public function getBundle(); + + /** + * Returns the entity prepared for rendering. + * + * @return array + * The entity prepared for rendering. + * + * @see entity_view() + */ + public function view($view_mode = 'full', $langcode = NULL, $page = NULL); + + /** + * Checks whether the operation $op is allowed on the entity. + * + * @return bool + * TRUE if the account is allowed to perform the operation. FALSE otherwise. + * + * @see entity_access() + */ + public function entityAccess($op, $account = NULL); + + /** + * Permanently save the wrapped entity. + * + * @throws EntityMetadataWrapperException + * If the entity type does not support saving. + * + * @return EntityDrupalWrapper + * The wrapped entity. + */ + public function save(); + + /** + * Permanently delete the wrapped entity. + * + * @return EntityDrupalWrapper + * The wrapped entity. + */ + public function delete(); + + /** + * Gets the info about the wrapped entity. + * + * @param array + * The entity information. + */ + public function entityInfo(); + + /** + * Returns the name of the key used by the entity for given entity key. + * + * @param string $name + * One of 'id', 'name', 'bundle' or 'revision'. + * + * @return string + * The name of the key used by the entity. + */ + public function entityKey($name); + +} + +/** * Provides a wrapper for entities registrered in hook_entity_info(). * * The wrapper eases applying getter and setter callbacks of entity properties * specified in hook_entity_property_info(). */ -class EntityDrupalWrapper extends EntityStructureWrapper { +class EntityDrupalWrapper extends EntityStructureWrapper implements EntityDrupalWrapperInterface { /** * Contains the entity id. @@ -685,7 +900,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Returns the bundle of an entity, or FALSE if it has no bundles. + * {@inheritdoc} */ public function getBundle() { if ($this->dataAvailable()) { @@ -695,11 +910,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Overridden. - * - * @param $options - * An array of options. Known keys: - * - identifier: If set to TRUE, the entity identifier is returned. + * {@inheritdoc} */ public function value(array $options = array()) { // Try loading the data via the getter callback if there is none yet. @@ -720,16 +931,14 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Returns the entity prepared for rendering. - * - * @see entity_view() + * {@inheritdoc} */ public function view($view_mode = 'full', $langcode = NULL, $page = NULL) { return entity_view($this->type(), array($this->value()), $view_mode, $langcode, $page); } /** - * Overridden to support setting the entity by either the object or the id. + * {@inheritdoc} */ public function set($value) { if (!$this->validate($value)) { @@ -780,7 +989,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Overridden. + * {@inheritdoc} */ public function type() { // In case of a generic entity wrapper, load the data first to determine @@ -825,9 +1034,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Checks whether the operation $op is allowed on the entity. - * - * @see entity_access() + * {@inheritdoc} */ public function entityAccess($op, $account = NULL) { $entity = $this->dataAvailable() ? $this->value() : NULL; @@ -841,12 +1048,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Permanently save the wrapped entity. - * - * @throws EntityMetadataWrapperException - * If the entity type does not support saving. - * - * @return EntityDrupalWrapper + * {@inheritdoc} */ public function save() { if ($this->data) { @@ -864,9 +1066,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Permanently delete the wrapped entity. - * - * @return EntityDrupalWrapper + * {@inheritdoc} */ public function delete() { if ($this->dataAvailable() && $this->value()) { @@ -879,28 +1079,21 @@ class EntityDrupalWrapper extends EntityStructureWrapper { } /** - * Gets the info about the wrapped entity. + * {@inheritdoc} */ public function entityInfo() { return $this->entityInfo; } /** - * Returns the name of the key used by the entity for given entity key. - * - * @param $name - * One of 'id', 'name', 'bundle' or 'revision'. - * @return - * The name of the key used by the entity. + * {@inheritdoc} */ public function entityKey($name) { return isset($this->entityInfo['entity keys'][$name]) ? $this->entityInfo['entity keys'][$name] : FALSE; } /** - * Returns the entity label. - * - * @see entity_label() + * {@inheritdoc} */ public function label() { if ($entity = $this->value()) {