You are here

class EntityListWrapper in Entity API 7

Wraps a list of values.

If the wrapped data is a list of data, its numerical indexes may be used to retrieve wrappers for the list items. For that this wrapper implements ArrayAccess so it may be used like a usual numerically indexed array.

Hierarchy

Expanded class hierarchy of EntityListWrapper

File

includes/entity.wrapper.inc, line 1000
Provides wrappers allowing easy usage of the entity metadata.

View source
class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggregate, ArrayAccess, Countable {

  /**
   * The type of contained items.
   */
  protected $itemType;

  /**
   * Whether this is a list of entities with a known entity type, i.e. for
   * generic list of entities (list<entity>) this is FALSE.
   */
  protected $isEntityList;
  public function __construct($type, $data = NULL, $info = array()) {
    parent::__construct($type, NULL, $info);
    $this->itemType = entity_property_list_extract_type($this->type);
    if (!$this->itemType) {
      $this->itemType = 'unknown';
    }
    $this->isEntityList = (bool) entity_get_info($this->itemType);
    if (isset($data)) {
      $this
        ->set($data);
    }
  }

  /**
   * Get the wrapper for a single item.
   *
   * @return EntityMetadataWrapper
   *   An instance of EntityMetadataWrapper.
   */
  public function get($delta) {

    // Look it up in the cache if possible.
    if (!array_key_exists($delta, $this->cache)) {
      if (!isset($delta)) {

        // The [] operator has been used so point at a new entry.
        $values = parent::value();
        $delta = $values ? max(array_keys($values)) + 1 : 0;
      }
      if (is_numeric($delta)) {
        $info = array(
          'parent' => $this,
          'name' => $delta,
        ) + $this->info;
        $this->cache[$delta] = entity_metadata_wrapper($this->itemType, NULL, $info);
      }
      else {
        throw new EntityMetadataWrapperException('There can be only numerical keyed items in a list.');
      }
    }
    return $this->cache[$delta];
  }
  protected function getPropertyValue($delta) {

    // Make use parent::value() to easily by-pass any entity-loading.
    $data = parent::value();
    if (isset($data[$delta])) {
      return $data[$delta];
    }
  }
  protected function getPropertyRaw($delta) {
    return $this
      ->getPropertyValue($delta);
  }
  protected function setProperty($delta, $value) {
    $data = parent::value();
    if (is_numeric($delta)) {
      $data[$delta] = $value;
      $this
        ->set($data);
    }
  }
  protected function propertyAccess($delta, $op, $account = NULL) {
    return $this
      ->access($op, $account);
  }

  /**
   * Returns the list as numerically indexed array.
   *
   * Note that a list of entities might contain stale entity references. In
   * that case the wrapper and the identifier of a stale reference would be
   * still accessible, however the entity object value would be NULL. That way,
   * there may be NULL values in lists of entity objects due to stale entity
   * references.
   *
   * @param $options
   *   An array of options. Known keys:
   *   - identifier: If set to TRUE for a list of entities, it won't be returned
   *     as list of fully loaded entity objects, but as a list of entity ids.
   *     Note that this list may contain ids of stale entity references.
   */
  public function value(array $options = array()) {

    // For lists of entities fetch full entity objects before returning.
    // Generic entity-wrappers need to be handled separately though.
    if ($this->isEntityList && empty($options['identifier']) && $this
      ->dataAvailable()) {
      $list = parent::value();
      $entities = $list ? entity_load($this
        ->get(0)->type, $list) : array();

      // Make sure to keep the array keys as present in the list.
      foreach ($list as $key => $id) {

        // In case the entity cannot be loaded, we return NULL just as for empty
        // properties.
        $list[$key] = isset($entities[$id]) ? $entities[$id] : NULL;
      }
      return $list;
    }
    return parent::value();
  }
  public function set($values) {

    // Support setting lists of fully loaded entities.
    if ($this->isEntityList && $values && is_object(reset($values))) {
      foreach ($values as $key => $value) {

        // Ignore outdated NULL value references in lists of entities.
        if (isset($value)) {
          list($id, $vid, $bundle) = entity_extract_ids($this->itemType, $value);
          $values[$key] = $id;
        }
      }
    }
    return parent::set($values);
  }

  /**
   * If we wrap a list, we return an iterator over the data list.
   */
  public function getIterator() {

    // In case there is no data available, just iterate over the first item.
    return new EntityMetadataWrapperIterator($this, $this
      ->dataAvailable() && is_array(parent::value()) ? array_keys(parent::value()) : array(
      0,
    ));
  }

  /**
   * Implements the ArrayAccess interface.
   */
  public function offsetGet($delta) {
    return $this
      ->get($delta);
  }
  public function offsetExists($delta) {
    return $this
      ->dataAvailable() && ($data = $this
      ->value()) && array_key_exists($delta, $data);
  }
  public function offsetSet($delta, $value) {
    $this
      ->get($delta)
      ->set($value);
  }
  public function offsetUnset($delta) {
    if ($this
      ->offsetExists($delta)) {
      unset($this->data[$delta]);
      $this
        ->set($this->data);
    }
  }
  public function count() {
    return $this
      ->dataAvailable() ? count($this
      ->value()) : 0;
  }

  /**
   * Overridden.
   */
  public function validate($value) {

    // Required lists may not be empty or unset.
    if (!empty($this->info['required']) && empty($value)) {
      return FALSE;
    }
    return parent::validate($value);
  }

  /**
   * Returns the label for the list of set values if available.
   */
  public function label() {
    if ($options = $this
      ->optionsList('view')) {
      $options = entity_property_options_flatten($options);
      $labels = array_intersect_key($options, array_flip((array) parent::value()));
    }
    else {

      // Get each label on its own, e.g. to support getting labels of a list
      // of entities.
      $labels = array();
      foreach ($this as $key => $property) {
        $label = $property
          ->label();
        if (!$label) {
          return NULL;
        }
        $labels[] = $label;
      }
    }
    return isset($labels) ? implode(', ', $labels) : NULL;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntityListWrapper::$isEntityList protected property Whether this is a list of entities with a known entity type, i.e. for generic list of entities (list<entity>) this is FALSE.
EntityListWrapper::$itemType protected property The type of contained items.
EntityListWrapper::count public function
EntityListWrapper::get public function Get the wrapper for a single item.
EntityListWrapper::getIterator public function If we wrap a list, we return an iterator over the data list.
EntityListWrapper::getPropertyRaw protected function
EntityListWrapper::getPropertyValue protected function
EntityListWrapper::label public function Returns the label for the list of set values if available. Overrides EntityMetadataWrapper::label
EntityListWrapper::offsetExists public function
EntityListWrapper::offsetGet public function Implements the ArrayAccess interface.
EntityListWrapper::offsetSet public function
EntityListWrapper::offsetUnset public function
EntityListWrapper::propertyAccess protected function
EntityListWrapper::set public function Set a new data value. Overrides EntityMetadataWrapper::set
EntityListWrapper::setProperty protected function
EntityListWrapper::validate public function Overridden. Overrides EntityMetadataWrapper::validate
EntityListWrapper::value public function Returns the list as numerically indexed array. Overrides EntityMetadataWrapper::value
EntityListWrapper::__construct public function Construct a new wrapper object. Overrides EntityMetadataWrapper::__construct
EntityMetadataWrapper::$cache protected property
EntityMetadataWrapper::$data protected property
EntityMetadataWrapper::$info protected property
EntityMetadataWrapper::$type protected property 1
EntityMetadataWrapper::access public function 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: 1
EntityMetadataWrapper::clear protected function Clears the data value and the wrapper cache. 1
EntityMetadataWrapper::dataAvailable protected function Returns whether data is available to work with.
EntityMetadataWrapper::debugIdentifierLocation public function Returns a string to use to identify this wrapper in error messages. 1
EntityMetadataWrapper::info public function Gets info about the wrapped data.
EntityMetadataWrapper::optionsList public function Returns the options list specifying possible values for the property, if defined.
EntityMetadataWrapper::raw public function 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().
EntityMetadataWrapper::type public function Gets the (entity)type of the wrapped data. 1
EntityMetadataWrapper::updateParent protected function Updates the parent data structure of a data property with the latest data value.
EntityMetadataWrapper::__sleep public function Prepare for serializiation. 1
EntityMetadataWrapper::__toString public function