class Map

The "map" data type.

The "map" data type represent a simple complex data type, e.g. for representing associative arrays. It can also serve as base class for any complex data type.

By default there is no metadata for contained properties. Extending classes may want to override Map::getPropertyDefinitions() to define it.

Hierarchy

Expanded class hierarchy of Map

1 file declares its use of Map
FieldItemBase.php in drupal/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php
Contains \Drupal\Core\Entity\Field\FieldItemBase.
1 string reference to 'Map'
system_data_type_info in drupal/core/modules/system/system.module
Implements hook_data_type_info().

File

drupal/core/lib/Drupal/Core/TypedData/Type/Map.php, line 24
Contains \Drupal\Core\TypedData\Type\Map.

Namespace

Drupal\Core\TypedData\Type
View source
class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface {

  /**
   * An array of values for the contained properties.
   *
   * @var array
   */
  protected $values = array();

  /**
   * The array of properties, each implementing the TypedDataInterface.
   *
   * @var array
   */
  protected $properties = array();

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
   */
  public function getPropertyDefinitions() {
    $definitions = array();
    foreach ($this->values as $name => $value) {
      $definitions[$name] = array(
        'type' => 'any',
      );
    }
    return $definitions;
  }

  /**
   * Overrides \Drupal\Core\TypedData\TypedData::getValue().
   */
  public function getValue() {

    // Update the values and return them.
    foreach ($this->properties as $name => $property) {
      $definition = $property
        ->getDefinition();
      if (empty($definition['computed'])) {
        $value = $property
          ->getValue();

        // Only write NULL values if the whole map is not NULL.
        if (isset($this->values) || isset($value)) {
          $this->values[$name] = $value;
        }
      }
    }
    return $this->values;
  }

  /**
   * Overrides \Drupal\Core\TypedData\TypedData::setValue().
   *
   * @param array|null $values
   *   An array of property values.
   */
  public function setValue($values, $notify = TRUE) {
    if (isset($values) && !is_array($values)) {
      throw new \InvalidArgumentException("Invalid values given. Values must be represented as an associative array.");
    }

    // Notify the parent of any changes to be made.
    if ($notify && isset($this->parent)) {
      $this->parent
        ->onChange($this->name);
    }
    $this->values = $values;

    // Update any existing property objects.
    foreach ($this->properties as $name => $property) {
      $value = NULL;
      if (isset($values[$name])) {
        $value = $values[$name];
      }
      $property
        ->setValue($value, FALSE);
    }
  }

  /**
   * Overrides \Drupal\Core\TypedData\TypedData::getString().
   */
  public function getString() {
    $strings = array();
    foreach ($this
      ->getProperties() as $property) {
      $strings[] = $property
        ->getString();
    }

    // Remove any empty strings resulting from empty items.
    return implode(', ', array_filter($strings, 'drupal_strlen'));
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::get().
   */
  public function get($property_name) {
    if (!isset($this->properties[$property_name])) {
      $value = NULL;
      if (isset($this->values[$property_name])) {
        $value = $this->values[$property_name];
      }

      // If the property is unknown, this will throw an exception.
      $this->properties[$property_name] = \Drupal::typedData()
        ->getPropertyInstance($this, $property_name, $value);
    }
    return $this->properties[$property_name];
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
   */
  public function set($property_name, $value, $notify = TRUE) {

    // Notify the parent of any changes to be made.
    if ($notify && isset($this->parent)) {
      $this->parent
        ->onChange($this->name);
    }
    if ($this
      ->getPropertyDefinition($property_name)) {
      $this
        ->get($property_name)
        ->setValue($value);
    }
    else {

      // Just set the plain value, which allows adding a new entry to the map.
      $this->values[$property_name] = $value;
    }
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getProperties().
   */
  public function getProperties($include_computed = FALSE) {
    $properties = array();
    foreach ($this
      ->getPropertyDefinitions() as $name => $definition) {
      if ($include_computed || empty($definition['computed'])) {
        $properties[$name] = $this
          ->get($name);
      }
    }
    return $properties;
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyValues().
   */
  public function getPropertyValues() {
    $values = array();
    foreach ($this
      ->getProperties() as $name => $property) {
      $values[$name] = $property
        ->getValue();
    }
    return $values;
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::setPropertyValues().
   */
  public function setPropertyValues($values) {
    foreach ($values as $name => $value) {
      $this
        ->get($name)
        ->setValue($value);
    }
  }

  /**
   * Implements \IteratorAggregate::getIterator().
   */
  public function getIterator() {
    return new \ArrayIterator($this
      ->getProperties());
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition().
   */
  public function getPropertyDefinition($name) {
    $definitions = $this
      ->getPropertyDefinitions();
    if (isset($definitions[$name])) {
      return $definitions[$name];
    }
    else {
      return FALSE;
    }
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty().
   */
  public function isEmpty() {
    foreach ($this->properties as $property) {
      $definition = $property
        ->getDefinition();
      if (empty($definition['computed']) && $property
        ->getValue() !== NULL) {
        return FALSE;
      }
    }
    if (isset($this->values)) {
      foreach ($this->values as $name => $value) {
        if (isset($value) && !isset($this->properties[$name])) {
          return FALSE;
        }
      }
    }
    return TRUE;
  }

  /**
   * Magic method: Implements a deep clone.
   */
  public function __clone() {
    foreach ($this->properties as $name => $property) {
      $this->properties[$name] = clone $property;
      $this->properties[$name]
        ->setContext($name, $this);
    }
  }

  /**
   * Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange().
   */
  public function onChange($property_name) {

    // Notify the parent of changes.
    if (isset($this->parent)) {
      $this->parent
        ->onChange($this->name);
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Map::$properties protected property The array of properties, each implementing the TypedDataInterface.
Map::$values protected property An array of values for the contained properties.
Map::get public function Implements \Drupal\Core\TypedData\ComplexDataInterface::get(). Overrides ComplexDataInterface::get 1
Map::getIterator public function Implements \IteratorAggregate::getIterator().
Map::getProperties public function Implements \Drupal\Core\TypedData\ComplexDataInterface::getProperties(). Overrides ComplexDataInterface::getProperties
Map::getPropertyDefinition public function Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition(). Overrides ComplexDataInterface::getPropertyDefinition
Map::getPropertyDefinitions public function Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions(). Overrides ComplexDataInterface::getPropertyDefinitions 21
Map::getPropertyValues public function Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyValues(). Overrides ComplexDataInterface::getPropertyValues
Map::getString public function Overrides \Drupal\Core\TypedData\TypedData::getString(). Overrides TypedData::getString
Map::getValue public function Overrides \Drupal\Core\TypedData\TypedData::getValue(). Overrides TypedData::getValue
Map::isEmpty public function Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty(). Overrides ComplexDataInterface::isEmpty 1
Map::onChange public function Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange(). Overrides ComplexDataInterface::onChange 1
Map::set public function Implements \Drupal\Core\TypedData\ComplexDataInterface::set(). Overrides ComplexDataInterface::set 1
Map::setPropertyValues public function Implements \Drupal\Core\TypedData\ComplexDataInterface::setPropertyValues(). Overrides ComplexDataInterface::setPropertyValues
Map::setValue public function Overrides \Drupal\Core\TypedData\TypedData::setValue(). Overrides TypedData::setValue 1
Map::__clone public function Magic method: Implements a deep clone.
TypedData::$definition protected property The data definition.
TypedData::$name protected property The property name.
TypedData::$parent protected property The parent typed data object.
TypedData::getConstraints public function Implements \Drupal\Core\TypedData\TypedDataInterface::getConstraints(). Overrides TypedDataInterface::getConstraints 2
TypedData::getDefinition public function Implements \Drupal\Core\TypedData\TypedDataInterface::getDefinition(). Overrides TypedDataInterface::getDefinition
TypedData::getName public function Implements \Drupal\Core\TypedData\TypedDataInterface::getName(). Overrides TypedDataInterface::getName
TypedData::getParent public function Implements \Drupal\Core\TypedData\TypedDataInterface::getParent(). Overrides TypedDataInterface::getParent
TypedData::getPropertyPath public function Implements \Drupal\Core\TypedData\TypedDataInterface::getPropertyPath(). Overrides TypedDataInterface::getPropertyPath
TypedData::getRoot public function Implements \Drupal\Core\TypedData\TypedDataInterface::getRoot(). Overrides TypedDataInterface::getRoot
TypedData::getType public function Implements \Drupal\Core\TypedData\TypedDataInterface::getType(). Overrides TypedDataInterface::getType
TypedData::setContext public function Implements \Drupal\Core\TypedData\TypedDataInterface::setContext(). Overrides TypedDataInterface::setContext 1
TypedData::validate public function Implements \Drupal\Core\TypedData\TypedDataInterface::validate(). Overrides TypedDataInterface::validate 3
TypedData::__construct public function Constructs a TypedData object given its definition and context. 5