Issue #2488568 by Jose Reyero, alexpott, Gábor Hojtsy, tstoeckler: Add a TypedDataManagerInterface and use it for typed parameters

8.0.x
effulgentsia 2015-10-05 14:31:21 -07:00
parent 641eb3f8d7
commit b6707fca2e
17 changed files with 335 additions and 306 deletions

View File

@ -459,7 +459,7 @@ class Drupal {
*
* Use the typed data manager service for creating typed data objects.
*
* @return \Drupal\Core\TypedData\TypedDataManager
* @return \Drupal\Core\TypedData\TypedDataManagerInterface
* The typed data manager.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()

View File

@ -7,27 +7,10 @@
namespace Drupal\Core\Config\Schema;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\TypedData\TypedData;
/**
* Defines a generic configuration element that contains multiple properties.
*/
abstract class ArrayElement extends TypedData implements \IteratorAggregate, TypedConfigInterface {
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfig;
/**
* The configuration value.
*
* @var mixed
*/
protected $value;
abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
/**
* Parsed elements.
@ -152,7 +135,7 @@ abstract class ArrayElement extends TypedData implements \IteratorAggregate, Typ
* @return \Drupal\Core\TypedData\TypedDataInterface
*/
protected function createElement($definition, $value, $key) {
return $this->typedConfig->create($definition, $value, $key, $this);
return $this->getTypedDataManager()->create($definition, $value, $key, $this);
}
/**
@ -170,20 +153,7 @@ abstract class ArrayElement extends TypedData implements \IteratorAggregate, Typ
* @return \Drupal\Core\TypedData\DataDefinitionInterface
*/
protected function buildDataDefinition($definition, $value, $key) {
return $this->typedConfig->buildDataDefinition($definition, $value, $key, $this);
}
/**
* Sets the typed config manager on the instance.
*
* This must be called immediately after construction to enable
* self::parseElement() and self::buildDataDefinition() to work.
*
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
*/
public function setTypedConfig(TypedConfigManagerInterface $typed_config) {
$this->typedConfig = $typed_config;
return $this->getTypedDataManager()->buildDataDefinition($definition, $value, $key, $this);
}
/**

View File

@ -7,7 +7,9 @@
namespace Drupal\Core\Config\Schema;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\TypedData\TypedData;
use Drupal\Core\TypedData\TypedDataManagerInterface;
/**
* Defines a generic configuration element.
@ -21,4 +23,41 @@ abstract class Element extends TypedData {
*/
protected $value;
/**
* Gets the typed configuration manager.
*
* Overrides \Drupal\Core\TypedData\TypedDataTrait::getTypedDataManager() to
* ensure the typed configuration manager is returned.
*
* @return \Drupal\Core\Config\TypedConfigManagerInterface
* The typed configuration manager.
*/
public function getTypedDataManager() {
if (empty($this->typedDataManager)) {
$this->setTypedDataManager(\Drupal::service('config.typed'));
}
return $this->typedDataManager;
}
/**
* Sets the typed config manager.
*
* Overrides \Drupal\Core\TypedData\TypedDataTrait::setTypedDataManager() to
* ensure that only typed configuration manager can be used.
*
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed config manager. This must be an instance of
* \Drupal\Core\Config\TypedConfigManagerInterface. If it is not, then this
* method will error when assertions are enabled. We can not narrow the
* typehint as this will cause PHP errors.
*
* @return $this
*/
public function setTypedDataManager(TypedDataManagerInterface $typed_data_manager) {
assert($typed_data_manager instanceof TypedConfigManagerInterface, '$typed_data_manager should be an instance of \Drupal\Core\Config\TypedConfigManagerInterface.');
$this->typedDataManager = $typed_data_manager;
return $this;
}
}

View File

@ -71,13 +71,7 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
/**
* Gets typed configuration data.
*
* @param string $name
* Configuration object name.
*
* @return \Drupal\Core\Config\Schema\TypedConfigInterface
* Typed configuration data.
* {@inheritdoc}
*/
public function get($name) {
$data = $this->configStorage->read($name);
@ -342,17 +336,4 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
}
}
/**
* {@inheritdoc}
*/
public function createInstance($data_type, array $configuration = array()) {
$instance = parent::createInstance($data_type, $configuration);
// Enable elements to construct their own definitions using the typed config
// manager.
if ($instance instanceof ArrayElement) {
$instance->setTypedConfig($this);
}
return $instance;
}
}

View File

@ -7,9 +7,7 @@
namespace Drupal\Core\Config;
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface;
/**
* Defines an interface for managing config schema type plugins.
@ -19,7 +17,7 @@ use Drupal\Core\TypedData\DataDefinitionInterface;
* @see hook_config_schema_info_alter()
* @see https://www.drupal.org/node/1905070
*/
Interface TypedConfigManagerInterface extends PluginManagerInterface, CachedDiscoveryInterface {
Interface TypedConfigManagerInterface extends TypedDataManagerInterface {
/**
* Gets typed configuration data.
@ -32,48 +30,6 @@ Interface TypedConfigManagerInterface extends PluginManagerInterface, CachedDisc
*/
public function get($name);
/**
* Instantiates a typed configuration object.
*
* @param string $data_type
* The data type, for which a typed configuration object should be
* instantiated.
* @param array $configuration
* The plugin configuration array, i.e. an array with the following keys:
* - data definition: The data definition object, i.e. an instance of
* \Drupal\Core\TypedData\DataDefinitionInterface.
* - name: (optional) If a property or list item is to be created, the name
* of the property or the delta of the list item.
* - parent: (optional) If a property or list item is to be created, the
* parent typed data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\Config\Schema\Element
* The instantiated typed configuration object.
*/
public function createInstance($data_type, array $configuration = array());
/**
* Creates a new typed configuration object instance.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
* The data definition of the typed data object.
* @param mixed $value
* The data value. If set, it has to match one of the supported
* data type format as documented for the data type classes.
* @param string $name
* (optional) If a property or list item is to be created, the name of the
* property or the delta of the list item.
* @param mixed $parent
* (optional) If a property or list item is to be created, the parent typed
* data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\Config\Schema\Element
* The instantiated typed data object.
*/
public function create(DataDefinitionInterface $definition, $value, $name = NULL, $parent = NULL);
/**
* Creates a new data definition object from a type definition array and
* actual configuration data. Since type definitions may contain variables

View File

@ -32,7 +32,7 @@ use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@ -111,7 +111,7 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
/**
* The typed data manager.
*
* @var \Drupal\Core\TypedData\TypedDataManager
* @var \Drupal\Core\TypedData\TypedDataManagerInterface
*/
protected $typedDataManager;
@ -193,14 +193,14 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
* The string translationManager.
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
* The class resolver.
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed data manager.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
* The keyvalue factory.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
*/
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManager $typed_data_manager, KeyValueFactoryInterface $key_value_factory, EventDispatcherInterface $event_dispatcher) {
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManagerInterface $typed_data_manager, KeyValueFactoryInterface $key_value_factory, EventDispatcherInterface $event_dispatcher) {
parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityInterface');
$this->setCacheBackend($cache, 'entity_type', array('entity_types'));

View File

@ -281,7 +281,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
// widgets.
$cardinality = $this->getFieldDefinition()->getFieldStorageDefinition()->getCardinality();
if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$constraints[] = \Drupal::typedDataManager()
$constraints[] = $this->getTypedDataManager()
->getValidationConstraintManager()
->create('Count', array(
'max' => $cardinality,

View File

@ -13,7 +13,7 @@ use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\CategorizingPluginManagerTrait;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Core\TypedData\TypedDataManagerInterface;
/**
* Plugin manager for 'field type' plugins.
@ -27,7 +27,7 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
/**
* The typed data manager.
*
* @var \Drupal\Core\TypedData\TypedDataManager
* @var \Drupal\Core\TypedData\TypedDataManagerInterface
*/
protected $typedDataManager;
@ -41,10 +41,10 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
* Cache backend instance to use.
* @param \Drupal\Core\Extension\ModuleHandlerInterface
* The module handler.
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed data manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManager $typed_data_manager) {
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManagerInterface $typed_data_manager) {
parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\FieldItemInterface', 'Drupal\Core\Field\Annotation\FieldType');
$this->alterInfo('field_info');
$this->setCacheBackend($cache_backend, 'field_types_plugins');

View File

@ -48,7 +48,7 @@ abstract class DataReferenceBase extends TypedData implements DataReferenceInter
* {@inheritdoc}
*/
public function setValue($value, $notify = TRUE) {
$this->target = \Drupal::typedDataManager()->create($this->definition->getTargetDefinition(), $value);
$this->target = $this->getTypedDataManager()->create($this->definition->getTargetDefinition(), $value);
// Notify the parent of any changes.
if ($notify && isset($this->parent)) {
$this->parent->onChange($this->name);

View File

@ -222,7 +222,7 @@ class ItemList extends TypedData implements \IteratorAggregate, ListInterface {
* @return \Drupal\Core\TypedData\TypedDataInterface
*/
protected function createItem($offset = 0, $value = NULL) {
return \Drupal::typedDataManager()->getPropertyInstance($this, $offset, $value);
return $this->getTypedDataManager()->getPropertyInstance($this, $offset, $value);
}
/**

View File

@ -118,7 +118,7 @@ class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface
$value = $this->values[$property_name];
}
// If the property is unknown, this will throw an exception.
$this->properties[$property_name] = \Drupal::typedDataManager()->getPropertyInstance($this, $property_name, $value);
$this->properties[$property_name] = $this->getTypedDataManager()->getPropertyInstance($this, $property_name, $value);
}
return $this->properties[$property_name];
}

View File

@ -21,6 +21,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
abstract class TypedData implements TypedDataInterface, PluginInspectionInterface {
use StringTranslationTrait;
use TypedDataTrait;
/**
* The data definition.
@ -85,7 +86,7 @@ abstract class TypedData implements TypedDataInterface, PluginInspectionInterfac
* {@inheritdoc}
*/
public function getPluginDefinition() {
return \Drupal::typedDataManager()->getDefinition($this->definition->getDataType());
return $this->getTypedDataManager()->getDefinition($this->definition->getDataType());
}
/**
@ -124,8 +125,7 @@ abstract class TypedData implements TypedDataInterface, PluginInspectionInterfac
* {@inheritdoc}
*/
public function getConstraints() {
// @todo: Add the typed data manager as proper dependency.
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
$constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager();
$constraints = array();
foreach ($this->definition->getConstraints() as $name => $options) {
$constraints[] = $constraint_manager->create($name, $options);
@ -137,8 +137,7 @@ abstract class TypedData implements TypedDataInterface, PluginInspectionInterfac
* {@inheritdoc}
*/
public function validate() {
// @todo: Add the typed data manager as proper dependency.
return \Drupal::typedDataManager()->getValidator()->validate($this);
return $this->getTypedDataManager()->getValidator()->validate($this);
}
/**

View File

@ -23,7 +23,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Manages data type plugins.
*/
class TypedDataManager extends DefaultPluginManager {
class TypedDataManager extends DefaultPluginManager implements TypedDataManagerInterface {
use DependencySerializationTrait;
/**
@ -76,24 +76,7 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Instantiates a typed data object.
*
* @param string $data_type
* The data type, for which a typed object should be instantiated.
* @param array $configuration
* The plugin configuration array, i.e. an array with the following keys:
* - data_definition: The data definition object, i.e. an instance of
* \Drupal\Core\TypedData\DataDefinitionInterface.
* - name: (optional) If a property or list item is to be created, the name
* of the property or the delta of the list item.
* - parent: (optional) If a property or list item is to be created, the
* parent typed data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The instantiated typed data object.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()
* {@inheritdoc}
*/
public function createInstance($data_type, array $configuration = array()) {
$data_definition = $configuration['data_definition'];
@ -110,39 +93,13 @@ class TypedDataManager extends DefaultPluginManager {
if (!isset($class)) {
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type));
}
return $class::createInstance($data_definition, $configuration['name'], $configuration['parent']);
$typed_data = $class::createInstance($data_definition, $configuration['name'], $configuration['parent']);
$typed_data->setTypedDataManager($this);
return $typed_data;
}
/**
* Creates a new typed data object instance.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
* The data definition of the typed data object. For backwards-compatibility
* an array representation of the data definition may be passed also.
* @param mixed $value
* (optional) The data value. If set, it has to match one of the supported
* data type format as documented for the data type classes.
* @param string $name
* (optional) If a property or list item is to be created, the name of the
* property or the delta of the list item.
* @param mixed $parent
* (optional) If a property or list item is to be created, the parent typed
* data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The instantiated typed data object.
*
* @see \Drupal::typedDataManager()
* @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
* @see \Drupal\Core\TypedData\Plugin\DataType\BinaryData
* @see \Drupal\Core\TypedData\Plugin\DataType\BooleanData
* @see \Drupal\Core\TypedData\Plugin\DataType\Date
* @see \Drupal\Core\TypedData\Plugin\DataType\Duration
* @see \Drupal\Core\TypedData\Plugin\DataType\FloatData
* @see \Drupal\Core\TypedData\Plugin\DataType\IntegerData
* @see \Drupal\Core\TypedData\Plugin\DataType\StringData
* @see \Drupal\Core\TypedData\Plugin\DataType\Uri
* {@inheritdoc}
*/
public function create(DataDefinitionInterface $definition, $value = NULL, $name = NULL, $parent = NULL) {
$typed_data = $this->createInstance($definition->getDataType(), array(
@ -157,27 +114,7 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Creates a new data definition object.
*
* While data definitions objects may be created directly if the definition
* class used by a data type is known, this method allows the creation of data
* definitions for any given data type.
*
* E.g., if a definition for a map is to be created, the following code
* could be used instead of calling this method with the argument 'map':
* @code
* $map_definition = \Drupal\Core\TypedData\MapDataDefinition::create();
* @endcode
*
* @param string $data_type
* The data type plugin ID, for which a data definition object should be
* created.
*
* @return \Drupal\Core\TypedData\DataDefinitionInterface
* A data definition object for the given data type. The class of this
* object is provided by the definition_class in the plugin annotation.
*
* @see \Drupal\Core\TypedData\TypedDataManager::createListDataDefinition()
* {@inheritdoc}
*/
public function createDataDefinition($data_type) {
$type_definition = $this->getDefinition($data_type);
@ -189,15 +126,7 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Creates a new list data definition for items of the given data type.
*
* @param string $item_type
* The item type, for which a list data definition should be created.
*
* @return \Drupal\Core\TypedData\ListDataDefinitionInterface
* A list definition for items of the given data type.
*
* @see \Drupal\Core\TypedData\TypedDataManager::createDataDefinition()
* {@inheritdoc}
*/
public function createListDataDefinition($item_type) {
$type_definition = $this->getDefinition($item_type);
@ -209,59 +138,14 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Implements \Drupal\Component\Plugin\PluginManagerInterface::getInstance().
*
* @param array $options
* An array of options with the following keys:
* - object: The parent typed data object, implementing the
* TypedDataInterface and either the ListInterface or the
* ComplexDataInterface.
* - property: The name of the property to instantiate, or the delta of the
* the list item to instantiate.
* - value: The value to set. If set, it has to match one of the supported
* data type formats as documented by the data type classes.
*
* @throws \InvalidArgumentException
* If the given property is not known, or the passed object does not
* implement the ListInterface or the ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The new property instance.
*
* @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
* {@inheritdoc}
*/
public function getInstance(array $options) {
return $this->getPropertyInstance($options['object'], $options['property'], $options['value']);
}
/**
* Get a typed data instance for a property of a given typed data object.
*
* This method will use prototyping for fast and efficient instantiation of
* many property objects with the same property path; e.g.,
* when multiple comments are used comment_body.0.value needs to be
* instantiated very often.
* Prototyping is done by the root object's data type and the given
* 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
* The parent typed data object, implementing the TypedDataInterface and
* either the ListInterface or the ComplexDataInterface.
* @param string $property_name
* The name of the property to instantiate, or the delta of an list item.
* @param mixed $value
* (optional) The data value. If set, it has to match one of the supported
* data type formats as documented by the data type classes.
*
* @throws \InvalidArgumentException
* If the given property is not known, or the passed object does not
* implement the ListInterface or the ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The new property instance.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()
* {@inheritdoc}
*/
public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL) {
// For performance, try to reuse existing prototypes instead of
@ -329,10 +213,7 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Gets the validator for validating typed data.
*
* @return \Symfony\Component\Validator\Validator\ValidatorInterface
* The validator object.
* {@inheritdoc}
*/
public function getValidator() {
if (!isset($this->validator)) {
@ -346,43 +227,21 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Sets the validation constraint manager.
*
* The validation constraint manager is used to instantiate validation
* constraint plugins.
*
* @param \Drupal\Core\Validation\ConstraintManager
* The constraint manager to set.
* {@inheritdoc}
*/
public function setValidationConstraintManager(ConstraintManager $constraintManager) {
$this->constraintManager = $constraintManager;
}
/**
* Gets the validation constraint manager.
*
* @return \Drupal\Core\Validation\ConstraintManager
* The constraint manager.
* {@inheritdoc}
*/
public function getValidationConstraintManager() {
return $this->constraintManager;
}
/**
* Gets default constraints for the given data definition.
*
* This generates default constraint definitions based on the data definition;
* e.g. a NotNull constraint is generated if the data is defined as required.
* Besides that any constraints defined for the data type, i.e. below the
* 'constraint' key of the type's plugin definition, are taken into account.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
* A data definition.
*
* @return array
* An array of validation constraint definitions, keyed by constraint name.
* Each constraint definition can be used for instantiating
* \Symfony\Component\Validator\Constraint objects.
* {@inheritdoc}
*/
public function getDefaultConstraints(DataDefinitionInterface $definition) {
$constraints = array();
@ -416,30 +275,7 @@ class TypedDataManager extends DefaultPluginManager {
}
/**
* Gets the canonical representation of a TypedData object.
*
* The canonical representation is typically used when data is passed on to
* other code components. In many use cases, the TypedData object is mostly
* unified adapter wrapping a primary value (e.g. a string, an entity...)
* which is the canonical representation that consuming code like constraint
* validators are really interested in. For some APIs, though, the domain
* object (e.g. Field API's FieldItem and FieldItemList) directly implements
* TypedDataInterface, and the canonical representation is thus the data
* object itself.
*
* When a TypedData object gets validated, for example, its canonical
* representation is passed on to constraint validators, which thus receive
* an Entity unwrapped, but a FieldItem as is.
*
* Data types specify whether their data objects need unwrapping by using the
* 'unwrap_for_canonical_representation' property in the data definition
* (defaults to TRUE).
*
* @param \Drupal\Core\TypedData\TypedDataInterface $data
* The data.
*
* @return mixed
* The canonical representation of the passed data.
* {@inheritdoc}
*/
public function getCanonicalRepresentation(TypedDataInterface $data) {
$data_definition = $data->getDataDefinition();

View File

@ -0,0 +1,248 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\TypedDataManagerInterface.
*/
namespace Drupal\Core\TypedData;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
use Drupal\Core\Validation\ConstraintManager;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Defines an interface for typed data manager.
*/
interface TypedDataManagerInterface extends PluginManagerInterface, CachedDiscoveryInterface {
/**
* Instantiates a typed data object.
*
* @param string $data_type
* The data type, for which a typed object should be instantiated.
* @param array $configuration
* The plugin configuration array, i.e. an array with the following keys:
* - data_definition: The data definition object, i.e. an instance of
* \Drupal\Core\TypedData\DataDefinitionInterface.
* - name: (optional) If a property or list item is to be created, the name
* of the property or the delta of the list item.
* - parent: (optional) If a property or list item is to be created, the
* parent typed data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The instantiated typed data object.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()
*/
public function createInstance($data_type, array $configuration = array());
/**
* Creates a new typed data object instance.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
* The data definition of the typed data object. For backwards-compatibility
* an array representation of the data definition may be passed also.
* @param mixed $value
* (optional) The data value. If set, it has to match one of the supported
* data type format as documented for the data type classes.
* @param string $name
* (optional) If a property or list item is to be created, the name of the
* property or the delta of the list item.
* @param mixed $parent
* (optional) If a property or list item is to be created, the parent typed
* data object implementing either the ListInterface or the
* ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The instantiated typed data object.
*
* @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
* @see \Drupal\Core\TypedData\Plugin\DataType\BinaryData
* @see \Drupal\Core\TypedData\Plugin\DataType\BooleanData
* @see \Drupal\Core\TypedData\Plugin\DataType\Date
* @see \Drupal\Core\TypedData\Plugin\DataType\Duration
* @see \Drupal\Core\TypedData\Plugin\DataType\FloatData
* @see \Drupal\Core\TypedData\Plugin\DataType\IntegerData
* @see \Drupal\Core\TypedData\Plugin\DataType\StringData
* @see \Drupal\Core\TypedData\Plugin\DataType\Uri
*/
public function create(DataDefinitionInterface $definition, $value = NULL, $name = NULL, $parent = NULL);
/**
* Creates a new data definition object.
*
* While data definitions objects may be created directly if the definition
* class used by a data type is known, this method allows the creation of data
* definitions for any given data type.
*
* E.g., if a definition for a map is to be created, the following code
* could be used instead of calling this method with the argument 'map':
* @code
* $map_definition = \Drupal\Core\TypedData\MapDataDefinition::create();
* @endcode
*
* @param string $data_type
* The data type plugin ID, for which a data definition object should be
* created.
*
* @return \Drupal\Core\TypedData\DataDefinitionInterface
* A data definition object for the given data type. The class of this
* object is provided by the definition_class in the plugin annotation.
*
* @see \Drupal\Core\TypedData\TypedDataManager::createListDataDefinition()
*/
public function createDataDefinition($data_type);
/**
* Creates a new list data definition for items of the given data type.
*
* @param string $item_type
* The item type, for which a list data definition should be created.
*
* @return \Drupal\Core\TypedData\ListDataDefinitionInterface
* A list definition for items of the given data type.
*
* @see \Drupal\Core\TypedData\TypedDataManager::createDataDefinition()
*/
public function createListDataDefinition($item_type);
/**
* {@inheritdoc}
*
* @param array $options
* An array of options with the following keys:
* - object: The parent typed data object, implementing the
* TypedDataInterface and either the ListInterface or the
* ComplexDataInterface.
* - property: The name of the property to instantiate, or the delta of the
* the list item to instantiate.
* - value: The value to set. If set, it has to match one of the supported
* data type formats as documented by the data type classes.
*
* @throws \InvalidArgumentException
* If the given property is not known, or the passed object does not
* implement the ListInterface or the ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The new property instance.
*
* @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
*/
public function getInstance(array $options);
/**
* Get a typed data instance for a property of a given typed data object.
*
* This method will use prototyping for fast and efficient instantiation of
* many property objects with the same property path; e.g.,
* when multiple comments are used comment_body.0.value needs to be
* instantiated very often.
* Prototyping is done by the root object's data type and the given
* 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
* The parent typed data object, implementing the TypedDataInterface and
* either the ListInterface or the ComplexDataInterface.
* @param string $property_name
* The name of the property to instantiate, or the delta of an list item.
* @param mixed $value
* (optional) The data value. If set, it has to match one of the supported
* data type formats as documented by the data type classes.
*
* @throws \InvalidArgumentException
* If the given property is not known, or the passed object does not
* implement the ListInterface or the ComplexDataInterface.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The new property instance.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()
*/
public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL);
/**
* Gets the validator for validating typed data.
*
* @return \Symfony\Component\Validator\Validator\ValidatorInterface
* The validator object.
*/
public function getValidator();
/**
* Sets the validator for validating typed data.
*
* @param \Symfony\Component\Validator\Validator\ValidatorInterface $validator
* The validator object to set.
*/
public function setValidator(ValidatorInterface $validator);
/**
* Gets the validation constraint manager.
*
* @return \Drupal\Core\Validation\ConstraintManager
* The constraint manager.
*/
public function getValidationConstraintManager();
/**
* Sets the validation constraint manager.
*
* The validation constraint manager is used to instantiate validation
* constraint plugins.
*
* @param \Drupal\Core\Validation\ConstraintManager
* The constraint manager to set.
*/
public function setValidationConstraintManager(ConstraintManager $constraintManager);
/**
* Gets default constraints for the given data definition.
*
* This generates default constraint definitions based on the data definition;
* e.g. a NotNull constraint is generated if the data is defined as required.
* Besides that any constraints defined for the data type, i.e. below the
* 'constraint' key of the type's plugin definition, are taken into account.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
* A data definition.
*
* @return array
* An array of validation constraint definitions, keyed by constraint name.
* Each constraint definition can be used for instantiating
* \Symfony\Component\Validator\Constraint objects.
*/
public function getDefaultConstraints(DataDefinitionInterface $definition);
/**
* Gets the canonical representation of a TypedData object.
*
* The canonical representation is typically used when data is passed on to
* other code components. In many use cases, the TypedData object is mostly
* unified adapter wrapping a primary value (e.g. a string, an entity...)
* which is the canonical representation that consuming code like constraint
* validators are really interested in. For some APIs, though, the domain
* object (e.g. Field API's FieldItem and FieldItemList) directly implements
* TypedDataInterface, and the canonical representation is thus the data
* object itself.
*
* When a TypedData object gets validated, for example, its canonical
* representation is passed on to constraint validators, which thus receive
* an Entity unwrapped, but a FieldItem as is.
*
* Data types specify whether their data objects need unwrapping by using the
* 'unwrap_for_canonical_representation' property in the data definition
* (defaults to TRUE).
*
* @param \Drupal\Core\TypedData\TypedDataInterface $data
* The data.
*
* @return mixed
* The canonical representation of the passed data.
*/
public function getCanonicalRepresentation(TypedDataInterface $data);
}

View File

@ -15,19 +15,19 @@ trait TypedDataTrait {
/**
* The typed data manager used for creating the data types.
*
* @var \Drupal\Core\TypedData\TypedDataManager
* @var \Drupal\Core\TypedData\TypedDataManagerInterface
*/
protected $typedDataManager;
/**
* Sets the typed data manager.
*
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed data manager.
*
* @return $this
*/
public function setTypedDataManager(TypedDataManager $typed_data_manager) {
public function setTypedDataManager(TypedDataManagerInterface $typed_data_manager) {
$this->typedDataManager = $typed_data_manager;
return $this;
}
@ -35,7 +35,7 @@ trait TypedDataTrait {
/**
* Gets the typed data manager.
*
* @return \Drupal\Core\TypedData\TypedDataManager
* @return \Drupal\Core\TypedData\TypedDataManagerInterface
* The typed data manager.
*/
public function getTypedDataManager() {

View File

@ -10,7 +10,7 @@ namespace Drupal\Core\TypedData\Validation;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\ListInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
@ -64,10 +64,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface {
* The metadata factory.
* @param \Symfony\Component\Validator\ConstraintValidatorFactoryInterface $validator_factory
* The constraint validator factory.
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed data manager.
*/
public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadata_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManager $typed_data_manager) {
public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadata_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManagerInterface $typed_data_manager) {
$this->context = $context;
$this->metadataFactory = $metadata_factory;
$this->constraintValidatorFactory = $validator_factory;

View File

@ -8,7 +8,7 @@
namespace Drupal\Core\TypedData\Validation;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
@ -44,10 +44,10 @@ class RecursiveValidator implements ValidatorInterface {
* The factory for creating new contexts.
* @param \Symfony\Component\Validator\ConstraintValidatorFactoryInterface $validator_factory
* The constraint validator factory.
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
* The typed data manager.
*/
public function __construct(ExecutionContextFactoryInterface $context_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManager $typed_data_manager) {
public function __construct(ExecutionContextFactoryInterface $context_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManagerInterface $typed_data_manager) {
$this->contextFactory = $context_factory;
$this->constraintValidatorFactory = $validator_factory;
$this->typedDataManager = $typed_data_manager;