diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index 1bb5486..c102d60 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -280,4 +280,13 @@ public static function onDependencyRemoval(FieldDefinitionInterface $field_defin return FALSE; } + /** + * {@inheritdoc} + */ + public function unwrap() { + // Field items directly implement the TypedDataInterface, so keep the object + // when Typed Data is unwrapped. + return $this; + } + } diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php index 930b4e1..d888ad3 100644 --- a/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -370,4 +370,13 @@ protected function defaultValueWidget(FormStateInterface $form_state) { return $form_state->get('default_value_widget'); } + /** + * {@inheritdoc} + */ + public function unwrap() { + // Field item lists directly implement the TypedDataInterface, so keep the + // object when Typed Data is unwrapped. + return $this; + } + } diff --git a/core/lib/Drupal/Core/Field/Plugin/DataType/Deriver/FieldItemDeriver.php b/core/lib/Drupal/Core/Field/Plugin/DataType/Deriver/FieldItemDeriver.php index 58fce03..ef15e33 100644 --- a/core/lib/Drupal/Core/Field/Plugin/DataType/Deriver/FieldItemDeriver.php +++ b/core/lib/Drupal/Core/Field/Plugin/DataType/Deriver/FieldItemDeriver.php @@ -79,7 +79,6 @@ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($this->fieldTypePluginManager->getDefinitions() as $plugin_id => $definition) { $definition['definition_class'] = '\Drupal\Core\Field\TypedData\FieldItemDataDefinition'; $definition['list_definition_class'] = '\Drupal\Core\Field\BaseFieldDefinition'; - $definition['wrapped'] = FALSE; $this->derivatives[$plugin_id] = $definition; } return $this->derivatives; diff --git a/core/lib/Drupal/Core/Field/Plugin/DataType/FieldItem.php b/core/lib/Drupal/Core/Field/Plugin/DataType/FieldItem.php index 7327eb2..bcca2ec 100644 --- a/core/lib/Drupal/Core/Field/Plugin/DataType/FieldItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/DataType/FieldItem.php @@ -18,8 +18,7 @@ * id = "field_item", * label = @Translation("Field item"), * list_class = "\Drupal\Core\Field\FieldItemList", - * deriver = "Drupal\Core\Field\Plugin\DataType\Deriver\FieldItemDeriver", - * wrapped = false + * deriver = "Drupal\Core\Field\Plugin\DataType\Deriver\FieldItemDeriver" * ) */ abstract class FieldItem { diff --git a/core/lib/Drupal/Core/TypedData/Annotation/DataType.php b/core/lib/Drupal/Core/TypedData/Annotation/DataType.php index 49d9fcd..332c3ed 100644 --- a/core/lib/Drupal/Core/TypedData/Annotation/DataType.php +++ b/core/lib/Drupal/Core/TypedData/Annotation/DataType.php @@ -106,19 +106,4 @@ class DataType extends Plugin { */ public $constraints; - /** - * Whether data of this type is wrapped by typed data objects. - * - * Mostly, typed data objects wrap a data value to make it usable based - * on the Typed Data API. However, data which is already represented by PHP - * objects may opt to implement the Typed Data interface directly, such that - * a wrapping object becomes unnecessary. In that case, this variable should - * be set to FALSE. - * - * @var bool - * - * @see \Drupal\Core\TypedData\TypedDataManager::unwrap() - */ - public $wrapped = TRUE; - } diff --git a/core/lib/Drupal/Core/TypedData/TypedData.php b/core/lib/Drupal/Core/TypedData/TypedData.php index 72815e9..7633d48 100644 --- a/core/lib/Drupal/Core/TypedData/TypedData.php +++ b/core/lib/Drupal/Core/TypedData/TypedData.php @@ -202,27 +202,10 @@ public function getParent() { } /** - * Unwraps a data object if needed. - * - * Unwraps the object unless the data object directly implements the Typed - * Data API. See \Drupal\Core\TypedData\Annotation\DataType::$wrapped. - * - * This may be used to ensure data is in the right representation before it is - * passed on to other code components. E.g., when typed data is validated it - * gets unwrapped before it is passed on to constraint validators, such that - * entity objects get passed unwrapped and fields stay objects (which directly - * implemented TypedDataInterface). - * - * @param \Drupal\Core\TypedData\TypedDataInterface $data - * The data object to unwrap. - * - * @return mixed - * The data, without any wrapping Typed Data object. + * {@inheritdoc} */ public function unwrap() { - if (!empty($this->definition['wrapped'])) { - return $data->getValue(); - } - return $data; + return $this->getValue(); } + } diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php index 7b038e5..95d9c7f 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -164,4 +164,24 @@ public function getPropertyPath(); * root of a typed data tree. Defaults to NULL. */ public function setContext($name = NULL, TraversableTypedDataInterface $parent = NULL); + + /** + * Unwraps a data object if needed. + * + * Unwrapping removes any Typed Data objects wrapping the data in its regular + * representation; e.g., a string or an array. However, if data is regularly + * represented as an object and this objects directly implement the Typed + * Data API, there is no wrapping object to remove and the object itself is + * returned. + * + * This may be used to ensure data is in the right representation before it is + * passed on to other code components. E.g., when typed data is validated it + * gets unwrapped before it is passed on to constraint validators, such that + * entity objects get passed unwrapped and fields stay objects (which directly + * implemented TypedDataInterface). + * + * @return mixed + * The data, without any wrapping Typed Data object. + */ + public function unwrap(); } diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index 5c20e5f..7fe362e 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -332,7 +332,7 @@ public function setValidator(ValidatorInterface $validator) { public function getValidator() { if (!isset($this->validator)) { $this->validator = Validation::createValidatorBuilder() - ->setMetadataFactory(new MetadataFactory($this)) + ->setMetadataFactory(new MetadataFactory()) ->setTranslator(new DrupalTranslator()) ->setConstraintValidatorFactory(new ConstraintValidatorFactory($this->classResolver)) ->setApiVersion(Validation::API_VERSION_2_4) @@ -414,4 +414,5 @@ public function clearCachedDefinitions() { parent::clearCachedDefinitions(); $this->prototypes = array(); } + } diff --git a/core/lib/Drupal/Core/TypedData/Validation/Metadata.php b/core/lib/Drupal/Core/TypedData/Validation/Metadata.php index ccb6eec..e5613f4 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/Metadata.php +++ b/core/lib/Drupal/Core/TypedData/Validation/Metadata.php @@ -8,7 +8,6 @@ namespace Drupal\Core\TypedData\Validation; use Drupal\Core\TypedData\TypedDataInterface; -use Drupal\Core\TypedData\TypedDataManager; use Symfony\Component\Validator\ValidationVisitorInterface; use Symfony\Component\Validator\PropertyMetadataInterface; @@ -39,13 +38,6 @@ class Metadata implements PropertyMetadataInterface { protected $factory; /** - * The typed data manager. - * - * @var \Drupal\Core\TypedData\TypedDataManager - */ - protected $typedDataManager; - - /** * Constructs the object. * * @param \Drupal\Core\TypedData\TypedDataInterface $typed_data @@ -55,14 +47,11 @@ class Metadata implements PropertyMetadataInterface { * the data is the root of the typed data tree. * @param \Drupal\Core\TypedData\Validation\MetadataFactory $factory * The factory to use for instantiating property metadata. - * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager - * The typed data manager. */ - public function __construct(TypedDataInterface $typed_data, $name = '', MetadataFactory $factory, TypedDataManager $typed_data_manager) { + public function __construct(TypedDataInterface $typed_data, $name = '', MetadataFactory $factory) { $this->typedData = $typed_data; $this->name = $name; $this->factory = $factory; - $this->typedDataManager = $typed_data_manager; } /** @@ -73,7 +62,7 @@ public function accept(ValidationVisitorInterface $visitor, $typed_data, $group, // @todo: Do we have to care about groups? Symfony class metadata has // $propagatedGroup. - $visitor->visit($this, $typedData->unwrap(), $group, $propertyPath); + $visitor->visit($this, $typed_data->unwrap(), $group, $propertyPath); } /** diff --git a/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php b/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php index fcd0557..2858daf 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php +++ b/core/lib/Drupal/Core/TypedData/Validation/MetadataFactory.php @@ -10,7 +10,6 @@ use Drupal\Core\TypedData\ComplexDataInterface; use Drupal\Core\TypedData\ListInterface; use Drupal\Core\TypedData\TypedDataInterface; -use Drupal\Core\TypedData\TypedDataManager; use Symfony\Component\Validator\MetadataFactoryInterface; /** @@ -19,24 +18,7 @@ class MetadataFactory implements MetadataFactoryInterface { /** - * The typed data manager. - * - * @var \Drupal\Core\TypedData\TypedDataManager - */ - protected $typedDataManager; - - /** - * Constructs the object. - * - * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager - * The typed data manager. - */ - public function __construct(TypedDataManager $typed_data_manager) { - $this->typedDataManager = $typed_data_manager; - } - - /** - * {@inheritdoc} + * Implements MetadataFactoryInterface::getMetadataFor(). * * @param \Drupal\Core\TypedData\TypedDataInterface $typed_data * Some typed data object containing the value to validate. @@ -50,7 +32,7 @@ public function getMetadataFor($typed_data, $name = '') { } $is_container = $typed_data instanceof ComplexDataInterface || $typed_data instanceof ListInterface; $class = '\Drupal\Core\TypedData\Validation\\' . ($is_container ? 'PropertyContainerMetadata' : 'Metadata'); - return new $class($typed_data, $name, $this, $this->typedDataManager); + return new $class($typed_data, $name, $this); } /** diff --git a/core/lib/Drupal/Core/TypedData/Validation/PropertyContainerMetadata.php b/core/lib/Drupal/Core/TypedData/Validation/PropertyContainerMetadata.php index 3378e13..cbbbb2d 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/PropertyContainerMetadata.php +++ b/core/lib/Drupal/Core/TypedData/Validation/PropertyContainerMetadata.php @@ -28,7 +28,7 @@ public function accept(ValidationVisitorInterface $visitor, $typed_data, $group, $data = NULL; } else { - $data = $typedData->unwrap(); + $data = $typed_data->unwrap(); } $visitor->visit($this, $data, $group, $propertyPath); $pathPrefix = isset($propertyPath) && $propertyPath !== '' ? $propertyPath . '.' : ''; @@ -60,10 +60,10 @@ public function hasPropertyMetadata($property_name) { */ public function getPropertyMetadata($property_name) { if ($this->typedData instanceof ListInterface) { - return array(new Metadata($this->typedData[$property_name], $property_name, $this->factory, $this->typedDataManager)); + return array(new Metadata($this->typedData[$property_name], $property_name)); } elseif ($this->typedData instanceof ComplexDataInterface) { - return array(new Metadata($this->typedData->get($property_name), $property_name, $this->factory, $this->typedDataManager)); + return array(new Metadata($this->typedData->get($property_name), $property_name)); } else { throw new \LogicException("There are no known properties."); diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php index add46eb..31ffc5b 100644 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php +++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php @@ -8,7 +8,6 @@ namespace Drupal\Core\Validation\Plugin\Validation\Constraint; use Drupal\Core\TypedData\ComplexDataInterface; -use Drupal\Core\TypedData\TypedDataInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -26,10 +25,6 @@ public function validate($value, Constraint $constraint) { return; } - // If un-wrapped data has been passed, fetch the typed data object first. - if (!$value instanceof TypedDataInterface) { - $value = $this->context->getMetadata()->getTypedData(); - } if (!$value instanceof ComplexDataInterface) { throw new UnexpectedTypeException($value, 'ComplexData'); }