diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php index f801c28..4d9711e 100644 --- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php +++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php @@ -12,6 +12,7 @@ use \Countable; use \IteratorAggregate; use \Traversable; +use Drupal\Core\TypedData\PrimitiveInterface; /** * Defines a generic configuration element that contains multiple properties. @@ -55,7 +56,7 @@ protected function getAllKeys() { protected abstract function parse(); /** - * Implements TypedDataInterface::validate(). + * {@inheritdoc} */ public function validate() { foreach ($this->getElements() as $element) { @@ -85,7 +86,7 @@ public function offsetGet($offset) { * Implements ArrayAccess::offsetSet(). */ public function offsetSet($offset, $value) { - if ($value instanceof TypedDataInterface) { + if ($value instanceof PrimitiveInterface) { $value = $value->getValue(); } $this->value[$offset] = $value; diff --git a/core/lib/Drupal/Core/Config/Schema/Element.php b/core/lib/Drupal/Core/Config/Schema/Element.php index d4e29db..bb748cf 100644 --- a/core/lib/Drupal/Core/Config/Schema/Element.php +++ b/core/lib/Drupal/Core/Config/Schema/Element.php @@ -28,4 +28,27 @@ protected function parseElement($key, $data, $definition) { return config_typed()->create($definition, $data, $key, $this); } + /** + * @todo + * Temporarily copied this method from TypedData where it's been removed + * because TypedDataInterface is removed. This will be fixed with + * https://drupal.org/node/1928868 + */ + public function getValue() { + return $this->value; + } + + /** + * @todo + * Temporarily copied this method from TypedData where it's been removed + * because TypedDataInterface is removed. This will be fixed with + * https://drupal.org/node/1928868 + */ + public function setValue($value, $notify = TRUE) { + $this->value = $value; + // Notify the parent of any changes. + if ($notify && isset($this->parent)) { + $this->parent->onChange($this->name); + } + } } diff --git a/core/lib/Drupal/Core/Config/Schema/Mapping.php b/core/lib/Drupal/Core/Config/Schema/Mapping.php index 9701df0..1509421 100644 --- a/core/lib/Drupal/Core/Config/Schema/Mapping.php +++ b/core/lib/Drupal/Core/Config/Schema/Mapping.php @@ -9,7 +9,6 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\TypedData\ComplexDataInterface; -use Drupal\Core\TypedData\TypedDataInterface; use \InvalidArgumentException; /** diff --git a/core/lib/Drupal/Core/Config/Schema/Property.php b/core/lib/Drupal/Core/Config/Schema/Property.php index d7e4b60..d9ceacd 100644 --- a/core/lib/Drupal/Core/Config/Schema/Property.php +++ b/core/lib/Drupal/Core/Config/Schema/Property.php @@ -13,7 +13,7 @@ class Property extends Element { /** - * Implements TypedDataInterface::validate(). + * {@inheritdoc} */ public function validate() { return isset($this->value); diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index 3fc660d..408313e 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -10,7 +10,6 @@ use Drupal\Component\Uuid\Uuid; use Drupal\Core\Language\Language; use Drupal\Core\TypedData\TranslatableInterface; -use Drupal\Core\TypedData\TypedDataInterface; use IteratorAggregate; use Drupal\Core\Session\AccountInterface; @@ -446,31 +445,6 @@ public function getDefinition() { /** * {@inheritdoc} */ - public function getValue() { - // @todo: This does not make much sense, so remove once TypedDataInterface - // is removed. See https://drupal.org/node/2002138. - return $this->getPropertyValues(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setValue(). - */ - public function setValue($value, $notify = TRUE) { - // @todo: This does not make much sense, so remove once TypedDataInterface - // is removed. See https://drupal.org/node/2002138. - $this->setPropertyValues($value); - } - - /** - * {@inheritdoc} - */ - public function getString() { - return $this->label(); - } - - /** - * {@inheritdoc} - */ public function getConstraints() { return array(); } @@ -500,37 +474,37 @@ public function onChange($property_name) { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getName(). + * {@inheritdoc} */ public function getName() { return NULL; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getRoot(). + * {@inheritdoc} */ public function getRoot() { return $this; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getPropertyPath(). + * {@inheritdoc} */ public function getPropertyPath() { return ''; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getParent(). + * {@inheritdoc} */ public function getParent() { return NULL; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setContext(). + * {@inheritdoc} */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL) { + public function setContext($name = NULL, $parent = NULL) { // As entities are always the root of the tree of typed data, we do not need // to set any parent or name. } diff --git a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php index b0be82e..5af242f 100644 --- a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php +++ b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php @@ -10,7 +10,6 @@ use Drupal\Core\Language\Language; use IteratorAggregate; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\Session\AccountInterface; /** @@ -502,7 +501,7 @@ public function getParent() { /** * Forwards the call to the decorated entity. */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL) { + public function setContext($name = NULL, $parent = NULL) { $this->decorated->setContext($name, $parent); } diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php index ac975d1..1a49e30 100644 --- a/core/lib/Drupal/Core/Entity/EntityNG.php +++ b/core/lib/Drupal/Core/Entity/EntityNG.php @@ -9,7 +9,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; -use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\Entity\Field\FieldInterface; use ArrayIterator; use InvalidArgumentException; @@ -732,7 +732,7 @@ public function &__get($name) { */ public function __set($name, $value) { // Support setting values via property objects. - if ($value instanceof TypedDataInterface && !$value instanceof EntityInterface) { + if ($value instanceof FieldInterface && !$value instanceof EntityInterface) { $value = $value->getValue(); } // If this is an entity field, handle it accordingly. We first check whether diff --git a/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php index 0ff36d7..96c5a17 100644 --- a/core/lib/Drupal/Core/Entity/Field/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Field.php @@ -9,7 +9,6 @@ use Drupal\Core\Entity\Field\FieldInterface; use Drupal\Core\Session\AccountInterface; -use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\ItemList; /** @@ -39,7 +38,7 @@ class Field extends ItemList implements FieldInterface { /** * Overrides TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct(array $definition, $name = NULL, $parent = NULL) { parent::__construct($definition, $name, $parent); // Always initialize one empty item as most times a value for at least one // item will be present. That way prototypes created by diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index c021c57..cb1182d 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\TypedData\Plugin\DataType\Map; -use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\user; /** @@ -25,7 +25,7 @@ /** * Overrides \Drupal\Core\TypedData\TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct(array $definition, $name = NULL, $parent = NULL) { parent::__construct($definition, $name, $parent); // Initialize computed properties by default, such that they get cloned // with the whole item. @@ -135,7 +135,7 @@ public function set($property_name, $value, $notify = TRUE) { public function __set($name, $value) { // Support setting values via property objects, but take care in as the // value of the 'entity' property is typed data also. - if ($value instanceof TypedDataInterface && !($value instanceof EntityInterface)) { + if ($value instanceof PrimitiveInterface && !($value instanceof EntityInterface)) { $value = $value->getValue(); } $this->set($name, $value); diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php index 3e67f7e..ae84ceb 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReferenceItem.php @@ -10,7 +10,6 @@ use Drupal\Core\TypedData\Annotation\DataType; use Drupal\Core\Annotation\Translation; use Drupal\Core\Entity\Field\FieldItemBase; -use Drupal\Core\TypedData\TypedDataInterface; /** * Defines the 'entity_reference_item' entity field item. diff --git a/core/lib/Drupal/Core/Plugin/Context/Context.php b/core/lib/Drupal/Core/Plugin/Context/Context.php index fbdf658..8d67080 100644 --- a/core/lib/Drupal/Core/Plugin/Context/Context.php +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php @@ -11,7 +11,7 @@ use Drupal\Core\Entity\Plugin\DataType\EntityWrapper; use Drupal\Core\TypedData\ComplexDataInterface; use Drupal\Core\TypedData\ListInterface; -use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\Core\Validation\DrupalTranslator; use Symfony\Component\Validator\Validation; @@ -37,7 +37,7 @@ public function getContextValue() { $is_complex = $typed_value[0] instanceof ComplexDataInterface; } // @todo We won't need the getType == entity check once #1868004 lands. - if ($typed_value instanceof TypedDataInterface && (!$is_complex || $typed_value instanceof EntityWrapper)) { + if ($typed_value instanceof PrimitiveInterface && (!$is_complex || $typed_value instanceof EntityWrapper)) { return $typed_value->getValue(); } return $typed_value; @@ -48,7 +48,7 @@ public function getContextValue() { */ public function setContextValue($value) { // Make sure the value set is a typed data object. - if (!empty($this->contextDefinition['type']) && !$value instanceof TypedDataInterface) { + if (!empty($this->contextDefinition['type']) && !\Drupal::typedData()->isTypedData($value)) { $value = \Drupal::typedData()->create($this->contextDefinition, $value); } parent::setContextValue($value); diff --git a/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php b/core/lib/Drupal/Core/TypedData/AnyInterface.php similarity index 83% copy from core/lib/Drupal/Core/TypedData/PrimitiveInterface.php copy to core/lib/Drupal/Core/TypedData/AnyInterface.php index b2293e2..ea94811 100644 --- a/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php +++ b/core/lib/Drupal/Core/TypedData/AnyInterface.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Core\TypedData\PrimitiveInterface. + * Contains \Drupal\Core\TypedData\Type\AnyInterface. */ namespace Drupal\Core\TypedData; @@ -10,7 +10,7 @@ /** * Interface for primitive data. */ -interface PrimitiveInterface { +interface AnyInterface { /** * Gets the primitive data value. diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php index a681ffe..7cb6037 100644 --- a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php @@ -21,7 +21,7 @@ * When implementing this interface which extends Traversable, make sure to list * IteratorAggregate or Iterator before this interface in the implements clause. */ -interface ComplexDataInterface extends Traversable, TypedDataInterface { +interface ComplexDataInterface extends Traversable, TypedDataInterface, ContextAwareInterface { /** * Gets a property object. diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/ContextAwareInterface.php similarity index 50% copy from core/lib/Drupal/Core/TypedData/TypedDataInterface.php copy to core/lib/Drupal/Core/TypedData/ContextAwareInterface.php index bbdf4ea..dc835c0 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/ContextAwareInterface.php @@ -2,86 +2,16 @@ /** * @file - * Contains \Drupal\Core\TypedData\TypedDataInterface. + * Contains \Drupal\Core\TypedData\ContextAwareInterface. */ namespace Drupal\Core\TypedData; -use Drupal\user; - /** - * Interface for typed data objects. + * Interface for typed data objects that are aware of its own property name and + * parent context. */ -interface TypedDataInterface { - - /** - * Gets the data definition. - * - * @return array - * The data definition array. - */ - public function getDefinition(); - - /** - * Gets the data value. - * - * @return mixed - */ - public function getValue(); - - /** - * Sets the data value. - * - * @param mixed|null $value - * The value to set in the format as documented for the data type or NULL to - * unset the data value. - * @param bool $notify - * (optional) Whether to notify the parent object of the change. Defaults to - * TRUE. If a property is updated from a parent object, set it to FALSE to - * avoid being notified again. - * - * @throws \Drupal\Core\TypedData\ReadOnlyException - * If the data is read-only. - */ - public function setValue($value, $notify = TRUE); - - /** - * Returns a string representation of the data. - * - * @return string - */ - public function getString(); - - /** - * Gets a list of validation constraints. - * - * @return array - * Array of constraints, each being an instance of - * \Symfony\Component\Validator\Constraint. - */ - public function getConstraints(); - - /** - * Validates the currently set data value. - * - * @return \Symfony\Component\Validator\ConstraintViolationListInterface - * A list of constraint violations. If the list is empty, validation - * succeeded. - */ - public function validate(); - - /** - * Applies the default value. - * - * @param bool $notify - * (optional) Whether to notify the parent object of the change. Defaults to - * TRUE. If a property is updated from a parent object, set it to FALSE to - * avoid being notified again. - * - * @return \Drupal\Core\TypedData\TypedDataInterface - * Returns itself to allow for chaining. - */ - public function applyDefaultValue($notify = TRUE); +interface ContextAwareInterface { /** * Returns the name of a property or item. @@ -137,5 +67,6 @@ public function getPropertyPath(); * (optional) The parent object of the data property, or NULL if it is the * root of a typed data tree. Defaults to NULL. */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL); + public function setContext($name = NULL, $parent = NULL); + } diff --git a/core/lib/Drupal/Core/TypedData/DefaultableInterface.php b/core/lib/Drupal/Core/TypedData/DefaultableInterface.php new file mode 100644 index 0000000..99e3783 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/DefaultableInterface.php @@ -0,0 +1,28 @@ +getValue(); } $this->offsetGet($offset)->setValue($value); diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Any.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Any.php index 9236b22..e16715f 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Any.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Any.php @@ -10,6 +10,7 @@ use Drupal\Core\TypedData\Annotation\DataType; use Drupal\Core\Annotation\Translation; use Drupal\Core\TypedData\TypedData; +use Drupal\Core\TypedData\AnyInterface; /** * The "any" data type. @@ -23,7 +24,7 @@ * label = @Translation("Any data") * ) */ -class Any extends TypedData { +class Any extends TypedData implements AnyInterface { /** * The data value. @@ -31,4 +32,22 @@ class Any extends TypedData { * @var mixed */ protected $value; + + /** + * {@inheritdoc} + */ + public function getValue() { + return $this->value; + } + + /** + * {@inheritdoc} + */ + public function setValue($value, $notify = TRUE) { + $this->value = $value; + // Notify the parent of any changes. + if ($notify && isset($this->parent)) { + $this->parent->onChange($this->name); + } + } } diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Language.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Language.php index 87d0bdf..7aab65a 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Language.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Language.php @@ -12,6 +12,7 @@ use InvalidArgumentException; use Drupal\Core\Language\Language as LanguageObject; use Drupal\Core\TypedData\IdentifiableInterface; +use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\Core\TypedData\TypedData; /** @@ -27,7 +28,7 @@ * description = @Translation("A language object.") * ) */ -class Language extends TypedData implements IdentifiableInterface { +class Language extends TypedData implements PrimitiveInterface, IdentifiableInterface { /** * The id of the language. diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index 180003c..6a7ea4f 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -26,6 +26,10 @@ * id = "map", * label = @Translation("Map") * ) + * + * @todo Map should not implement get/setValue() to instead stick tighter to the + * contract of ComplexDataInterface. Or, it should implement its own interface + * where get/setValue() is defined. */ class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface { @@ -101,18 +105,6 @@ public function setValue($values, $notify = TRUE) { } /** - * 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) { diff --git a/core/lib/Drupal/Core/TypedData/PrimitiveBase.php b/core/lib/Drupal/Core/TypedData/PrimitiveBase.php index dae6dbe..7b0201e 100644 --- a/core/lib/Drupal/Core/TypedData/PrimitiveBase.php +++ b/core/lib/Drupal/Core/TypedData/PrimitiveBase.php @@ -36,4 +36,11 @@ public function setValue($value, $notify = TRUE) { $this->parent->onChange($this->name); } } + + /** + * {@inheritdoc} + */ + public function getString() { + return (string) $this->getValue(); + } } diff --git a/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php b/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php index b2293e2..35f16bd 100644 --- a/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php +++ b/core/lib/Drupal/Core/TypedData/PrimitiveInterface.php @@ -10,7 +10,7 @@ /** * Interface for primitive data. */ -interface PrimitiveInterface { +interface PrimitiveInterface extends StringableInterface { /** * Gets the primitive data value. diff --git a/core/lib/Drupal/Core/TypedData/StringableInterface.php b/core/lib/Drupal/Core/TypedData/StringableInterface.php new file mode 100644 index 0000000..06b9064 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/StringableInterface.php @@ -0,0 +1,22 @@ +definition = $definition; $this->parent = $parent; $this->name = $name; @@ -80,32 +80,7 @@ public function getDefinition() { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getValue(). - */ - public function getValue() { - return $this->value; - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setValue(). - */ - public function setValue($value, $notify = TRUE) { - $this->value = $value; - // Notify the parent of any changes. - if ($notify && isset($this->parent)) { - $this->parent->onChange($this->name); - } - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getString(). - */ - public function getString() { - return (string) $this->getValue(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getConstraints(). + * {@inheritdoc} */ public function getConstraints() { // @todo: Add the typed data manager as proper dependency. @@ -113,7 +88,7 @@ public function getConstraints() { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::validate(). + * {@inheritdoc} */ public function validate() { // @todo: Add the typed data manager as proper dependency. @@ -130,22 +105,22 @@ public function applyDefaultValue($notify = TRUE) { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setContext(). + * {@inheritdoc} */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL) { + public function setContext($name = NULL, $parent = NULL) { $this->parent = $parent; $this->name = $name; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getName(). + * {@inheritdoc} */ public function getName() { return $this->name; } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getRoot(). + * {@inheritdoc} */ public function getRoot() { if (isset($this->parent)) { @@ -156,7 +131,7 @@ public function getRoot() { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getPropertyPath(). + * {@inheritdoc} */ public function getPropertyPath() { if (isset($this->parent)) { @@ -174,9 +149,7 @@ public function getPropertyPath() { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getParent(). - * - * @return \Drupal\Core\Entity\Field\FieldInterface + * {@inheritdoc} */ public function getParent() { return $this->parent; diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php index bbdf4ea..66ac1a5 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -7,8 +7,6 @@ namespace Drupal\Core\TypedData; -use Drupal\user; - /** * Interface for typed data objects. */ @@ -21,121 +19,4 @@ * The data definition array. */ public function getDefinition(); - - /** - * Gets the data value. - * - * @return mixed - */ - public function getValue(); - - /** - * Sets the data value. - * - * @param mixed|null $value - * The value to set in the format as documented for the data type or NULL to - * unset the data value. - * @param bool $notify - * (optional) Whether to notify the parent object of the change. Defaults to - * TRUE. If a property is updated from a parent object, set it to FALSE to - * avoid being notified again. - * - * @throws \Drupal\Core\TypedData\ReadOnlyException - * If the data is read-only. - */ - public function setValue($value, $notify = TRUE); - - /** - * Returns a string representation of the data. - * - * @return string - */ - public function getString(); - - /** - * Gets a list of validation constraints. - * - * @return array - * Array of constraints, each being an instance of - * \Symfony\Component\Validator\Constraint. - */ - public function getConstraints(); - - /** - * Validates the currently set data value. - * - * @return \Symfony\Component\Validator\ConstraintViolationListInterface - * A list of constraint violations. If the list is empty, validation - * succeeded. - */ - public function validate(); - - /** - * Applies the default value. - * - * @param bool $notify - * (optional) Whether to notify the parent object of the change. Defaults to - * TRUE. If a property is updated from a parent object, set it to FALSE to - * avoid being notified again. - * - * @return \Drupal\Core\TypedData\TypedDataInterface - * Returns itself to allow for chaining. - */ - public function applyDefaultValue($notify = TRUE); - - /** - * Returns the name of a property or item. - * - * @return string - * If the data is a property of some complex data, the name of the property. - * If the data is an item of a list, the name is the numeric position of the - * item in the list, starting with 0. Otherwise, NULL is returned. - */ - public function getName(); - - /** - * Returns the parent data structure; i.e. either complex data or a list. - * - * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface - * The parent data structure, either complex data or a list; or NULL if this - * is the root of the typed data tree. - */ - public function getParent(); - - /** - * Returns the root of the typed data tree. - * - * Returns the root data for a tree of typed data objects; e.g. for an entity - * field item the root of the tree is its parent entity object. - * - * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface - * The root data structure, either complex data or a list. - */ - public function getRoot(); - - /** - * Returns the property path of the data. - * - * The trail of property names relative to the root of the typed data tree, - * separated by dots; e.g. 'field_text.0.format'. - * - * @return string - * The property path relative to the root of the typed tree, or an empty - * string if this is the root. - */ - public function getPropertyPath(); - - /** - * Sets the context of a property or item via a context aware parent. - * - * This method is supposed to be called by the factory only. - * - * @param string $name - * (optional) The name of the property or the delta of the list item, - * or NULL if it is the root of a typed data tree. Defaults to NULL. - * @param \Drupal\Core\TypedData\TypedDataInterface $parent - * (optional) The parent object of the data property, or NULL if it is the - * root of a typed data tree. Defaults to NULL. - */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL); } diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index f217fa5..0c631a0 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -14,6 +14,8 @@ use Drupal\Core\Plugin\DefaultPluginManager; use InvalidArgumentException; use Drupal\Core\TypedData\Validation\MetadataFactory; +use Drupal\Core\TypedData\ContextAwareInterface; +use Drupal\Core\TypedData\AnyInterface; use Drupal\Core\Validation\ConstraintManager; use Drupal\Core\Validation\DrupalTranslator; use Symfony\Component\Validator\ValidatorInterface; @@ -198,7 +200,7 @@ public function getInstance(array $options) { * property path, i.e. all property instances having the same property path * and inheriting from the same data type are prototyped. * - * @param \Drupal\Core\TypedData\TypedDataInterface $object + * @param \Drupal\Core\TypedData\ContextAwareInterface $object * The parent typed data object, implementing the TypedDataInterface and * either the ListInterface or the ComplexDataInterface. * @param string $property_name @@ -219,7 +221,7 @@ public function getInstance(array $options) { * @todo: Add type-hinting to $object once entities implement the * TypedDataInterface. */ - public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL) { + public function getPropertyInstance(ContextAwareInterface $object, $property_name, $value = NULL) { $definition = $object->getRoot()->getDefinition(); $key = $definition['type']; if (isset($definition['settings'])) { @@ -382,4 +384,32 @@ public function getConstraints($definition) { } return $constraints; } + + /** + * Decided whether or not an object is typed data or not. + * + * @param mixed $object + * + * @return boolean + * Returns TRUE if $object is an instance of any of the typed data + * interfaces, else FALSE. + */ + public function isTypedData($object) { + if ($object instanceof ComplexDataInterface) { + return TRUE; + } + elseif ($object instanceof ListInterface) { + return TRUE; + } + elseif ($object instanceof PrimitiveInterface) { + return TRUE; + } + elseif ($object instanceof AnyInterface) { + return TRUE; + } + elseif ($object instanceof DataReferenceInterface) { + return TRUE; + } + return FALSE; + } } diff --git a/core/lib/Drupal/Core/TypedData/ValidatableInterface.php b/core/lib/Drupal/Core/TypedData/ValidatableInterface.php new file mode 100644 index 0000000..ac0af19 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/ValidatableInterface.php @@ -0,0 +1,33 @@ +typedData = $typed_data; $this->name = $name; $this->factory = $factory; diff --git a/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php b/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php index 2858daf..44af36f 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php +++ b/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php @@ -9,7 +9,6 @@ use Drupal\Core\TypedData\ComplexDataInterface; use Drupal\Core\TypedData\ListInterface; -use Drupal\Core\TypedData\TypedDataInterface; use Symfony\Component\Validator\MetadataFactoryInterface; /** @@ -27,7 +26,7 @@ class MetadataFactory implements MetadataFactoryInterface { * the data is the root of the typed data tree. */ public function getMetadataFor($typed_data, $name = '') { - if (!$typed_data instanceof TypedDataInterface) { + if (!\Drupal::typedData()->isTypedData($typed_data)) { throw new \InvalidArgumentException('The passed value must be a typed data object.'); } $is_container = $typed_data instanceof ComplexDataInterface || $typed_data instanceof ListInterface; @@ -39,6 +38,6 @@ public function getMetadataFor($typed_data, $name = '') { * Implements MetadataFactoryInterface::hasMetadataFor(). */ public function hasMetadataFor($value) { - return $value instanceof TypedDataInterface; + return \Drupal::typedData()->isTypedData($value); } } diff --git a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php index 1295776..2177580 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php +++ b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php @@ -15,6 +15,7 @@ * A computed property for the integer value of the 'new' field. * * @todo: Declare the list of allowed values once supported. + * @todo Need to implement a proper interface. */ class CommentNewValue extends TypedData { diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php index 29ce028..fccdb4d 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php @@ -7,7 +7,6 @@ namespace Drupal\field\Plugin\Type\FieldType; -use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\Entity\Field\Field; use Drupal\field\Field as FieldAPI; @@ -26,7 +25,7 @@ class ConfigField extends Field implements ConfigFieldInterface { /** * {@inheritdoc} */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct(array $definition, $name = NULL, $parent = NULL) { parent::__construct($definition, $name, $parent); if (isset($definition['instance'])) { $this->instance = $definition['instance']; diff --git a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php index 5d6b200..9dca634 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php @@ -8,7 +8,6 @@ namespace Drupal\locale; use Drupal\Core\Language\Language; -use Drupal\Core\TypedData\ContextAwareInterface; use Drupal\Core\Config\Schema\Element; use Drupal\Core\Config\Schema\ArrayElement; @@ -168,7 +167,7 @@ protected function getArrayTranslation(ArrayElement $element, array $options) { * @return bool * Whether the element fits the translation criteria. */ - protected function translateElement(\Drupal\Core\TypedData\TypedDataInterface $element, array $options) { + protected function translateElement($element, array $options) { if ($this->canTranslate($options['source'], $options['target'])) { $definition = $element->getDefinition(); $value = $element->getValue(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 297b00c..d0c855a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -12,7 +12,7 @@ use Drupal\Core\Entity\Field\FieldItemInterface; use Drupal\Core\Language\Language; use Drupal\Core\TypedData\Type\StringInterface; -use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\PrimitiveInterface; /** * Tests Entity API base functionality. @@ -434,7 +434,7 @@ protected function assertIterator($entity_type) { $this->assertTrue($field[0] instanceof FieldItemInterface, $entity_type . ": Item $delta of field $name implements interface."); foreach ($item as $value_name => $value_property) { - $this->assertTrue($value_property instanceof TypedDataInterface, $entity_type . ": Value $value_name of item $delta of field $name implements interface."); + $this->assertTrue($value_property instanceof PrimitiveInterface, $entity_type . ": Value $value_name of item $delta of field $name implements interface."); $value = $value_property->getValue(); $this->assertTrue(!isset($value) || is_scalar($value) || $value instanceof EntityInterface, $entity_type . ": Value $value_name of item $delta of field $name is a primitive or an entity."); @@ -491,7 +491,7 @@ protected function assertDataStructureInterfaces($entity_type) { * Recursive helper for getting all contained strings, * i.e. properties of type string. */ - public function getContainedStrings(TypedDataInterface $wrapper, $depth, array &$strings) { + public function getContainedStrings($wrapper, $depth, array &$strings) { if ($wrapper instanceof StringInterface) { $strings[] = $wrapper->getValue(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php index f00a35b..c6a69ba 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php @@ -10,7 +10,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Field\FieldInterface; use Drupal\Core\Entity\Field\FieldItemInterface; -use Drupal\Core\TypedData\TypedDataInterface; /** * Tests Entity API base functionality. diff --git a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php index c8e3cac..5212572 100644 --- a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php @@ -53,7 +53,12 @@ public function setUp() { */ protected function createTypedData($definition, $value = NULL, $name = NULL) { $data = $this->typedData->create($definition, $value, $name); - $this->assertTrue($data instanceof \Drupal\Core\TypedData\TypedDataInterface, 'Typed data object is an instance of the typed data interface.'); + // Assert the definition of the wrapper. + $this->assertTrue(\Drupal::typedData()->isTypedData($data), 'Typed data object is an instance of a typed data interface.'); + $definition = $data->getDefinition(); + $this->assertTrue(!empty($definition['type']), format_string('!type data definition was returned.', array('!type' => $definition['type']))); + // Assert that the correct type was constructed. + $this->assertEqual($data->getPluginId(), $definition['type'], format_string('!type object returned type.', array('!type' => $definition['type']))); return $data; } @@ -295,7 +300,6 @@ public function testGetAndSet() { $new_value = 'test@example.com'; $typed_data->setValue($new_value); $this->assertIdentical($typed_data->getValue(), $new_value, 'Any value was changed.'); - $this->assertTrue(is_string($typed_data->getString()), 'Any value was converted to string'); $this->assertEqual($typed_data->validate()->count(), 0); $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'Any wrapper is null-able.'); @@ -322,7 +326,7 @@ public function testTypedDataLists() { // Test iterating. $count = 0; foreach ($typed_data as $item) { - $this->assertTrue($item instanceof \Drupal\Core\TypedData\TypedDataInterface); + $this->assertTrue($item instanceof \Drupal\Core\TypedData\Plugin\DataType\String); $count++; } $this->assertEqual($count, 3); @@ -416,7 +420,7 @@ public function testTypedDataMaps() { // Test iterating. $count = 0; foreach ($typed_data as $item) { - $this->assertTrue($item instanceof \Drupal\Core\TypedData\TypedDataInterface); + $this->assertTrue($item instanceof \Drupal\Core\TypedData\AnyInterface); $count++; } $this->assertEqual($count, 3); @@ -452,10 +456,6 @@ public function testTypedDataMaps() { $typed_data->setValue(array('foo' => 'bar')); $this->assertEqual(array_keys($typed_data->getProperties()), array('foo')); - // Test getting the string representation. - $typed_data->setValue(array('one' => 'eins', 'two' => '', 'three' => 'drei')); - $this->assertEqual($typed_data->getString(), 'eins, drei'); - // Test isEmpty and cloning. $this->assertFalse($typed_data->isEmpty()); $clone = clone $typed_data; @@ -508,6 +508,9 @@ public function testTypedDataValidation() { 'Range' => array('min' => 5), ), ); + $integer = $this->typedData->create($definition, 7); + $this->assertTrue($integer instanceof \Drupal\Core\TypedData\ValidatableInterface); + $violations = $this->typedData->create($definition, 10)->validate(); $this->assertEqual($violations->count(), 0); @@ -617,4 +620,46 @@ public function testTypedDataValidation() { $this->assertEqual($violations[0]->getInvalidValue(), 'string'); $this->assertIdentical($violations[0]->getPropertyPath(), '0.value'); } + + /** + * Tests typed data contexts. + */ + function testTypedDataContext() { + // Test working with a simple map. + $value = array( + 'one' => 'ett', + 'two' => 'två', + 'three' => 'tre', + ); + $typed_data = $this->createTypedData(array( + 'type' => 'map', + ), $value); + + $this->assertTrue($typed_data instanceof \Drupal\Core\TypedData\ContextAwareInterface); + + $item = $typed_data->get('one'); + $this->assertEqual($item->getName(), 'one'); + $this->assertEqual($item->getPropertyPath(), 'one'); + $this->assertTrue($item->getParent() instanceof \Drupal\Core\TypedData\Plugin\DataType\Map); + $this->assertTrue($item->getRoot() instanceof \Drupal\Core\TypedData\Plugin\DataType\Map); + } + + /** + * Tests the typed data manager. + */ + function testTypedDataManager() { + // Test working with a simple map. + $value = array( + 'one' => 'första', + 'two' => 'andra', + 'three' => 'tredje', + ); + $typed_data = $this->createTypedData(array( + 'type' => 'map', + ), $value); + + $item = $this->typedData->getPropertyInstance($typed_data, 'two', 'prototyped value'); + $this->assertTrue($item instanceof \Drupal\Core\TypedData\AnyInterface); + $this->assertEqual($item->getValue(), 'prototyped value'); + } } diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php index 9a1910f..446a005 100644 --- a/core/modules/text/lib/Drupal/text/TextProcessed.php +++ b/core/modules/text/lib/Drupal/text/TextProcessed.php @@ -7,7 +7,6 @@ namespace Drupal\text; -use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedData; use Drupal\Core\TypedData\ReadOnlyException; use InvalidArgumentException; @@ -37,7 +36,7 @@ class TextProcessed extends TypedData { /** * Overrides TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct(array $definition, $name = NULL, $parent = NULL) { parent::__construct($definition, $name, $parent); if (!isset($definition['settings']['text source'])) { @@ -48,7 +47,7 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface /** * Overrides TypedData::setContext(). */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL) { + public function setContext($name = NULL, $parent = NULL) { parent::setContext($name, $parent); if (isset($parent)) { $this->text = $parent->get($this->definition['settings']['text source']); diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php index f591782..7c2f3b0 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php @@ -11,7 +11,6 @@ use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\views\ViewExecutable; use Drupal\Core\Database\Database; -use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\Session\AccountInterface; use Drupal\views\Plugin\views\query\Sql; use Drupal\views\Plugin\Core\Entity\View; @@ -1088,77 +1087,42 @@ public function getDefinition() { } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getValue(). - */ - public function getValue() { - return $this->storage->getValue(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setValue(). - */ - public function setValue($value, $notify = TRUE) { - return $this->storage->setValue($value, $notify); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getString(). - */ - public function getString() { - return $this->storage->getString(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getConstraints(). - */ - public function getConstraints() { - return $this->storage->getConstraints(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::validate(). - */ - public function validate() { - return $this->storage->validate(); - } - - /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getName(). + * {@inheritdoc} */ public function getName() { return $this->storage->getName(); } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getRoot(). + * {@inheritdoc} */ public function getRoot() { return $this->storage->getRoot(); } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getPropertyPath(). + * {@inheritdoc} */ public function getPropertyPath() { return $this->storage->getPropertyPath(); } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::getParent(). + * {@inheritdoc} */ public function getParent() { return $this->storage->getParent(); } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::setContext(). + * {@inheritdoc} */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL) { + public function setContext($name = NULL, $parent = NULL) { return $this->storage->setContext($name, $parent); } /** - * Implements \Drupal\Core\TypedData\TypedDataInterface::onChange(). + * {@inheritdoc} */ public function onChange($property_name) { $this->storage->onChange($property_name);