Issue #1867856 by fubhy the cat, EclipseGc, Berdir: Use annotation discovery for data type plugins.

8.0.x
Alex Pott 2013-06-29 15:48:52 +01:00
parent 9144713de3
commit 2c2f5f59f5
54 changed files with 656 additions and 621 deletions

View File

@ -198,6 +198,7 @@ services:
arguments: [slave]
typed_data:
class: Drupal\Core\TypedData\TypedDataManager
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
calls:
- [setValidationConstraintManager, ['@validation.constraint']]
validation.constraint:

View File

@ -583,13 +583,13 @@ function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\Ent
/**
* Control access to fields.
*
* This hook is invoked from \Drupal\Core\Entity\Field\Type\Field::access() to
* This hook is invoked from \Drupal\Core\Entity\Field\Field::access() to
* let modules grant or deny operations on fields.
*
* @param string $operation
* The operation to be performed. See
* \Drupal\Core\TypedData\AccessibleInterface::access() for possible values.
* @param \Drupal\Core\Entity\Field\Type\Field $field
* @param \Drupal\Core\Entity\Field\Field $field
* The entity field object on which the operation is to be performed.
* @param \Drupal\Core\Session\AccountInterface $account
* The user account to check.
@ -617,7 +617,7 @@ function hook_entity_field_access($operation, $field, \Drupal\Core\Session\Accou
* @param array $context
* Context array on the performed operation with the following keys:
* - operation: The operation to be performed (string).
* - field: The entity field object (\Drupal\Core\Entity\Field\Type\Field).
* - field: The entity field object (\Drupal\Core\Entity\Field\Field).
* - account: The user account to check access for
* (Drupal\user\Plugin\Core\Entity\User).
*/

View File

@ -1,122 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Config\Schema\SchemaDiscovery.
*/
namespace Drupal\Core\Config\Schema;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Component\Utility\NestedArray;
/**
* A discovery mechanism that reads plugin definitions from schema data
* in YAML format.
*/
class SchemaDiscovery implements DiscoveryInterface {
/**
* A storage controller instance for reading configuration schema data.
*
* @var Drupal\Core\Config\StorageInterface
*/
protected $storage;
/**
* The array of plugin definitions, keyed by plugin id.
*
* @var array
*/
protected $definitions = array();
/**
* Public constructor.
*
* @param Drupal\Core\Config\StorageInterface $storage
* The storage controller object to use for reading schema data
*/
public function __construct($storage) {
$this->storage = $storage;
$this->loadAllSchema();
}
/**
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
*/
public function getDefinition($base_plugin_id) {
if (isset($this->definitions[$base_plugin_id])) {
$type = $base_plugin_id;
}
elseif (strpos($base_plugin_id, '.') && $name = $this->getFallbackName($base_plugin_id)) {
// Found a generic name, replacing the last element by '*'.
$type = $name;
}
else {
// If we don't have definition, return the 'default' element.
// This should map to 'undefined' type by default, unless overridden.
$type = 'default';
}
$definition = $this->definitions[$type];
// Check whether this type is an extension of another one and compile it.
if (isset($definition['type'])) {
$merge = $this->getDefinition($definition['type']);
$definition = NestedArray::mergeDeep($merge, $definition);
// Unset type so we try the merge only once per type.
unset($definition['type']);
$this->definitions[$type] = $definition;
}
return $definition;
}
/**
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
*/
public function getDefinitions() {
return $this->definitions;
}
/**
* Load schema for module / theme.
*/
protected function loadAllSchema() {
foreach ($this->storage->listAll() as $name) {
if ($schema = $this->storage->read($name)) {
foreach ($schema as $type => $definition) {
$this->definitions[$type] = $definition;
}
}
}
}
/**
* Gets fallback metadata name.
*
* @param string $name
* Configuration name or key.
*
* @return null|string
* Same name with the last part(s) replaced by the filesystem marker.
* for example, breakpoint.breakpoint.module.toolbar.narrow check for
* definition in below order:
* breakpoint.breakpoint.module.toolbar.*
* breakpoint.breakpoint.module.*.*
* breakpoint.breakpoint.*.*.*
* breakpoint.*.*.*.*
* Returns null, if no matching element.
*/
protected function getFallbackName($name) {
// Check for definition of $name with filesystem marker.
$replaced = preg_replace('/(\.[^\.]+)([\.\*]*)$/', '.*\2', $name);
if ($replaced != $name ) {
if (isset($this->definitions[$replaced])) {
return $replaced;
}
else {
// No definition for this level(for example, breakpoint.breakpoint.*),
// check for next level (which is, breakpoint.*.*).
return self::getFallbackName($replaced);
}
}
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\Config\TypedConfigElementFactory.
*/
namespace Drupal\Core\Config;
use Drupal\Core\TypedData\TypedDataFactory;
/**
* A factory for typed config element objects.
*
* This factory merges the type definition into the element definition prior to
* creating the instance.
*/
class TypedConfigElementFactory extends TypedDataFactory {
/**
* Overrides Drupal\Core\TypedData\TypedDataFactory::createInstance().
*/
public function createInstance($plugin_id, array $configuration, $name = NULL, $parent = NULL) {
$type_definition = $this->discovery->getDefinition($plugin_id);
$configuration += $type_definition;
return parent::createInstance($plugin_id, $configuration, $name, $parent);
}
}

View File

@ -7,13 +7,13 @@
namespace Drupal\Core\Config;
use Drupal\Core\Config\Schema\SchemaDiscovery;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Component\Utility\NestedArray;
/**
* Manages config type plugins.
*/
class TypedConfigManager extends TypedDataManager {
class TypedConfigManager extends PluginManagerBase {
/**
* A storage controller instance for reading configuration data.
@ -22,6 +22,20 @@ class TypedConfigManager extends TypedDataManager {
*/
protected $configStorage;
/**
* A storage controller instance for reading configuration schema data.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $schemaStorage;
/**
* The array of plugin definitions, keyed by plugin id.
*
* @var array
*/
protected $definitions = array();
/**
* Creates a new typed configuration manager.
*
@ -32,8 +46,8 @@ class TypedConfigManager extends TypedDataManager {
*/
public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage) {
$this->configStorage = $configStorage;
$this->discovery = new SchemaDiscovery($schemaStorage);
$this->factory = new TypedConfigElementFactory($this->discovery);
$this->schemaStorage = $schemaStorage;
$this->loadAllSchema();
}
/**
@ -78,7 +92,116 @@ class TypedConfigManager extends TypedDataManager {
$definition['type'] = $this->replaceName($definition['type'], $replace);
}
// Create typed config object.
return parent::create($definition, $value, $name, $parent);
$wrapper = $this->createInstance($definition['type'], $definition, $name, $parent);
if (isset($value)) {
$wrapper->setValue($value, FALSE);
}
return $wrapper;
}
/**
* Overrides Drupal\Core\TypedData\TypedDataFactory::createInstance().
*/
public function createInstance($plugin_id, array $configuration, $name = NULL, $parent = NULL) {
$type_definition = $this->getDefinition($plugin_id);
$configuration += $type_definition;
if (!isset($type_definition)) {
throw new InvalidArgumentException(format_string('Invalid data type %plugin_id has been given.', array('%plugin_id' => $plugin_id)));
}
// Allow per-data definition overrides of the used classes, i.e. take over
// classes specified in the data definition.
$key = empty($configuration['list']) ? 'class' : 'list class';
if (isset($configuration[$key])) {
$class = $configuration[$key];
}
elseif (isset($type_definition[$key])) {
$class = $type_definition[$key];
}
if (!isset($class)) {
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
}
return new $class($configuration, $name, $parent);
}
/**
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
*/
public function getDefinition($base_plugin_id) {
if (isset($this->definitions[$base_plugin_id])) {
$type = $base_plugin_id;
}
elseif (strpos($base_plugin_id, '.') && $name = $this->getFallbackName($base_plugin_id)) {
// Found a generic name, replacing the last element by '*'.
$type = $name;
}
else {
// If we don't have definition, return the 'default' element.
// This should map to 'undefined' type by default, unless overridden.
$type = 'default';
}
$definition = $this->definitions[$type];
// Check whether this type is an extension of another one and compile it.
if (isset($definition['type'])) {
$merge = $this->getDefinition($definition['type']);
$definition = NestedArray::mergeDeep($merge, $definition);
// Unset type so we try the merge only once per type.
unset($definition['type']);
$this->definitions[$type] = $definition;
}
return $definition;
}
/**
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
*/
public function getDefinitions() {
return $this->definitions;
}
/**
* Load schema for module / theme.
*/
protected function loadAllSchema() {
foreach ($this->schemaStorage->listAll() as $name) {
if ($schema = $this->schemaStorage->read($name)) {
foreach ($schema as $type => $definition) {
$this->definitions[$type] = $definition;
}
}
}
}
/**
* Gets fallback metadata name.
*
* @param string $name
* Configuration name or key.
*
* @return null|string
* Same name with the last part(s) replaced by the filesystem marker.
* for example, breakpoint.breakpoint.module.toolbar.narrow check for
* definition in below order:
* breakpoint.breakpoint.module.toolbar.*
* breakpoint.breakpoint.module.*.*
* breakpoint.breakpoint.*.*.*
* breakpoint.*.*.*.*
* Returns null, if no matching element.
*/
protected function getFallbackName($name) {
// Check for definition of $name with filesystem marker.
$replaced = preg_replace('/(\.[^\.]+)([\.\*]*)$/', '.*\2', $name);
if ($replaced != $name ) {
if (isset($this->definitions[$replaced])) {
return $replaced;
}
else {
// No definition for this level(for example, breakpoint.breakpoint.*),
// check for next level (which is, breakpoint.*.*).
return self::getFallbackName($replaced);
}
}
}
/**

View File

@ -369,7 +369,7 @@ class EntityNG extends Entity {
/**
* Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslation().
*
* @return \Drupal\Core\Entity\Field\Type\EntityTranslation
* @return \Drupal\Core\Entity\Plugin\DataType\EntityTranslation
*/
public function getTranslation($langcode, $strict = TRUE) {
// If the default language is Language::LANGCODE_NOT_SPECIFIED, the entity is not

View File

@ -2,10 +2,10 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\Field.
* Contains \Drupal\Core\Entity\Field\Field.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Field;
use Drupal\Core\Entity\Field\FieldInterface;
use Drupal\Core\Session\AccountInterface;

View File

@ -8,7 +8,7 @@
namespace Drupal\Core\Entity\Field;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\TypedData\Type\Map;
use Drupal\Core\TypedData\Plugin\DataType\Map;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\user;
@ -80,7 +80,7 @@ abstract class FieldItemBase extends Map implements FieldItemInterface {
}
/**
* Overrides \Drupal\Core\TypedData\Type\Map::set().
* {@inheritdoc}
*/
public function set($property_name, $value, $notify = TRUE) {
// Notify the parent of any changes to be made.

View File

@ -1,28 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\UuidItem.
*/
namespace Drupal\Core\Entity\Field\Type;
use Drupal\Component\Uuid\Uuid;
/**
* Defines the 'uuid_field' entity field item.
*
* The field uses a newly generated UUID as default value.
*/
class UuidItem extends StringItem {
/**
* {@inheritdoc}
*/
public function applyDefaultValue($notify = TRUE) {
// Default to one field item with a generated UUID.
$uuid = new Uuid();
$this->setValue(array('value' => $uuid->generate()), $notify);
return $this;
}
}

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\BooleanItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\BooleanItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'boolean_field' entity field item.
*
* @DataType(
* id = "boolean_field",
* label = @Translation("Boolean field item"),
* description = @Translation("An entity field containing a boolean value."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class BooleanItem extends FieldItemBase {

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\DateItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\DateItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'date_field' entity field item.
*
* @DataType(
* id = "date_field",
* label = @Translation("Date field item"),
* description = @Translation("An entity field containing a date value."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class DateItem extends FieldItemBase {

View File

@ -2,15 +2,25 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\EmailItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\EmailItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
/**
* Defines the 'email_field' entity field item.
*
* @DataType(
* id = "email_field",
* label = @Translation("E-mail field item"),
* description = @Translation("An entity field containing an e-mail value."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class EmailItem extends LegacyConfigFieldItem {
@ -37,6 +47,7 @@ class EmailItem extends LegacyConfigFieldItem {
return static::$propertyDefinitions;
}
/**
* {@inheritdoc}
*/

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\EntityReferenceItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
use Drupal\Core\TypedData\TypedDataInterface;
@ -15,6 +17,13 @@ use Drupal\Core\TypedData\TypedDataInterface;
*
* Required settings (below the definition's 'settings' key) are:
* - target_type: The entity type to reference.
*
* @DataType(
* id = "entity_reference_field",
* label = @Translation("Entity reference field item"),
* description = @Translation("An entity field containing an entity reference."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class EntityReferenceItem extends FieldItemBase {

View File

@ -2,17 +2,18 @@
/**
* @file
* Contains \Drupal\Core\Entity\Type\EntityTranslation.
* Contains \Drupal\Core\Entity\Plugin\DataType\EntityTranslation.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\AccessibleInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\TypedData;
use ArrayIterator;
use Drupal\Core\TypedData\TypedDataInterface;
use IteratorAggregate;
use InvalidArgumentException;
@ -21,6 +22,12 @@ use InvalidArgumentException;
*
* Via this object translated entity fields may be read and updated in the same
* way as untranslatable entity fields on the entity object.
*
* @DataType(
* id = "entity_translation",
* label = @Translation("Entity translation"),
* description = @Translation("A translation of an entity.")
* )
*/
class EntityTranslation extends TypedData implements IteratorAggregate, AccessibleInterface, ComplexDataInterface {

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\EntityWrapper.
* Contains \Drupal\Core\Entity\Plugin\DataType\EntityWrapper.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\TypedData;
@ -34,6 +36,12 @@ use InvalidArgumentException;
* Supported settings (below the definition's 'settings' key) are:
* - id source: If used as computed property, the ID property used to load
* the entity object.
*
* @DataType(
* id = "entity",
* label = @Translation("Entity"),
* description = @Translation("All kind of entities, e.g. nodes, comments or users.")
* )
*/
class EntityWrapper extends TypedData implements IteratorAggregate, ComplexDataInterface {

View File

@ -38,11 +38,6 @@ class FieldDataTypeDerivative implements DerivativeInterface {
*/
public function getDerivativeDefinitions(array $base_plugin_definition) {
foreach (\Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions() as $plugin_id => $definition) {
// Typed data API expects a 'list class' property, but annotations do not
// support spaces in property names.
$definition['list class'] = $definition['list_class'];
unset($definition['list_class']);
$this->derivatives[$plugin_id] = $definition;
}
return $this->derivatives;

View File

@ -0,0 +1,26 @@
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Plugin\DataType\FieldItem.
*/
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Component\Plugin\PluginBase;
/**
* Defines the base plugin definition for field type typed data types.
*
* @DataType(
* id = "field_item",
* label = @Translation("Field item"),
* list_class = "\Drupal\Core\Entity\Field\Field",
* derivative = "Drupal\Core\Entity\Plugin\DataType\FieldDataTypeDerivative"
* )
*/
class FieldItem extends PluginBase {
}

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\IntegerItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\IntegerItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'integer_field' entity field item.
*
* @DataType(
* id = "integer_field",
* label = @Translation("Integer field item"),
* description = @Translation("An entity field containing an integer value."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class IntegerItem extends FieldItemBase {

View File

@ -2,16 +2,30 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\LanguageItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\LanguageItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
use Drupal\Core\Language\Language;
/**
* Defines the 'language_field' entity field item.
*
* @DataType(
* id = "language_field",
* label = @Translation("Language field item"),
* description = @Translation("An entity field referencing a language."),
* list_class = "\Drupal\Core\Entity\Field\Field",
* constraints = {
* "ComplexData" = {
* "value" = {"Length" = {"max" = 12}}
* }
* }
* )
*/
class LanguageItem extends FieldItemBase {

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\StringItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\StringItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'string_field' entity field item.
*
* @DataType(
* id = "string_field",
* label = @Translation("String field item"),
* description = @Translation("An entity field containing a string value."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class StringItem extends FieldItemBase {

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\Core\Entity\Field\Type\UriItem.
* Contains \Drupal\Core\Entity\Plugin\DataType\UriItem.
*/
namespace Drupal\Core\Entity\Field\Type;
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'uri_field' entity field item.
*
* @DataType(
* id = "uri_field",
* label = @Translation("URI field item"),
* description = @Translation("An entity field containing a URI."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class UriItem extends FieldItemBase {

View File

@ -0,0 +1,42 @@
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Plugin\DataType\UuidItem.
*/
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Component\Uuid\Uuid;
/**
* Defines the 'uuid_field' entity field item.
*
* The field uses a newly generated UUID as default value.
*
* @DataType(
* id = "uuid_field",
* label = @Translation("UUID field item"),
* description = @Translation("An entity field containing a UUID."),
* list_class = "\Drupal\Core\Entity\Field\Field",
* constraints = {
* "ComplexData" = {
* "value" = {"Length" = {"max" = 128}}
* }
* }
* )
*/
class UuidItem extends StringItem {
/**
* {@inheritdoc}
*/
public function applyDefaultValue($notify = TRUE) {
// Default to one field item with a generated UUID.
$uuid = new Uuid();
$this->setValue(array('value' => $uuid->generate()), $notify);
return $this;
}
}

View File

@ -8,7 +8,7 @@
namespace Drupal\Core\Plugin\Context;
use Drupal\Component\Plugin\Context\Context as ComponentContext;
use Drupal\Core\Entity\Field\Type\EntityWrapper;
use Drupal\Core\Entity\Plugin\DataType\EntityWrapper;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\ListInterface;
use Drupal\Core\TypedData\TypedDataInterface;

View File

@ -0,0 +1,91 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\Annotation\DataType.
*/
namespace Drupal\Core\TypedData\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines a data type annotation object.
*
* The typed data API allows modules to support any kind of data based upon
* pre-defined primitive types and interfaces for complex data and lists.
*
* Defined data types may map to one of the pre-defined primitive types in
* \Drupal\Core\TypedData\Primitive or may be complex data types, containing on
* or more data properties. Typed data objects for complex data types have to
* implement the \Drupal\Core\TypedData\ComplexDataInterface. Further interface
* that may be implemented are:
* - \Drupal\Core\TypedData\AccessibleInterface
* - \Drupal\Core\TypedData\TranslatableInterface
*
* Furthermore, lists of data items are represented by objects implementing the
* \Drupal\Core\TypedData\ListInterface. A list contains items of the same data
* type, is ordered and may contain duplicates. The classed used for a list of
* items of a certain type may be specified using the 'list class' key.
*
* @see \Drupal::typedData()
* @see Drupal\Core\TypedData\TypedDataManager::create()
* @see hook_data_type_info_alter()
*
* @Annotation
*/
class DataType extends Plugin {
/**
* The data type plugin ID.
*
* @var string
*/
public $id;
/**
* The human-readable name of the data type.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $label;
/**
* The description of the data type.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $description;
/**
* The typed data class used for wrapping multiple data items of the type.
* Must implement the \Drupal\Core\TypedData\ListInterface.
*
* @var string
*/
public $list_class = '\Drupal\Core\TypedData\ItemList';
/**
* The pre-defined primitive type that this data type maps to.
*
* If set, it must be a constant defined by \Drupal\Core\TypedData\Primitive
* such as \Drupal\Core\TypedData\Primitive::STRING.
*
* @var string
*/
public $primitive_type;
/**
* An array of validation constraints for this type.
*
* @var array
*
* @see \Drupal\Core\TypedData\TypedDataManager::getConstraints().
*/
public $constraints;
}

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Any.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Any.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
@ -15,6 +17,11 @@ use Drupal\Core\TypedData\TypedData;
* The "any" data type does not implement a list or complex data interface, nor
* is it mappable to any primitive type. Thus, it may contain any PHP data for
* which no further metadata is available.
*
* @DataType(
* id = "any",
* label = @Translation("Any data")
* )
*/
class Any extends TypedData {

View File

@ -2,13 +2,14 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Binary.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Binary.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
use InvalidArgumentException;
/**
* The binary data type.
@ -16,6 +17,12 @@ use InvalidArgumentException;
* The plain value of binary data is a PHP file resource, see
* http://php.net/manual/en/language.types.resource.php. For setting the value
* a PHP file resource or a (absolute) stream resource URI may be passed.
*
* @DataType(
* id = "binary",
* label = @Translation("Binary"),
* primitive_type = 8
* )
*/
class Binary extends TypedData {

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Boolean.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Boolean.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
@ -14,6 +16,12 @@ use Drupal\Core\TypedData\TypedData;
*
* The plain value of a boolean is a regular PHP boolean. For setting the value
* any PHP variable that casts to a boolean may be passed.
*
* @DataType(
* id = "boolean",
* label = @Translation("Boolean"),
* primitive_type = 1
* )
*/
class Boolean extends TypedData {

View File

@ -2,14 +2,15 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Date.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Date.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\TypedData\TypedData;
use InvalidArgumentException;
/**
* The date data type.
@ -18,6 +19,12 @@ use InvalidArgumentException;
* setting the value any value supported by the __construct() of the
* DrupalDateTime class will work, including a DateTime object, a timestamp, a
* string date, or an array of date parts.
*
* @DataType(
* id = "date",
* label = @Translation("Date"),
* primitive_type = 5
* )
*/
class Date extends TypedData {

View File

@ -2,14 +2,15 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Duration.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Duration.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
use DateInterval;
use InvalidArgumentException;
/**
* The duration data type.
@ -18,6 +19,12 @@ use InvalidArgumentException;
* setting the value an instance of the DateInterval class, a ISO8601 string as
* supported by DateInterval::__construct, or an integer in seconds may be
* passed.
*
* @DataType(
* id = "duration",
* label = @Translation("Duration"),
* primitive_type = 6
* )
*/
class Duration extends TypedData {

View File

@ -0,0 +1,27 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\Plugin\DataType\Email.
*/
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
/**
* The Email data type.
*
* The plain value of Email is the email address represented as PHP string.
*
* @DataType(
* id = "email",
* label = @Translation("Email"),
* primitive_type = 2,
* constraints = {"Email" = TRUE}
* )
*/
class Email extends String {
}

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Float.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Float.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
@ -14,6 +16,12 @@ use Drupal\Core\TypedData\TypedData;
*
* The plain value of a float is a regular PHP float. For setting the value
* any PHP variable that casts to a float may be passed.
*
* @DataType(
* id = "float",
* label = @Translation("Float"),
* primitive_type = 4
* )
*/
class Float extends TypedData {

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Integer.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Integer.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
@ -14,6 +16,12 @@ use Drupal\Core\TypedData\TypedData;
*
* The plain value of an integer is a regular PHP integer. For setting the value
* any PHP variable that casts to an integer may be passed.
*
* @DataType(
* id = "integer",
* label = @Translation("Integer"),
* primitive_type = 3
* )
*/
class Integer extends TypedData {

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Language.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Language.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use InvalidArgumentException;
use Drupal\Core\Language\Language as LanguageObject;
use Drupal\Core\TypedData\TypedData;
@ -24,6 +26,12 @@ use Drupal\Core\TypedData\TypedData;
* Supported settings (below the definition's 'settings' key) are:
* - langcode source: If used as computed property, the langcode property used
* to load the language object.
*
* @DataType(
* id = "language",
* label = @Translation("Language"),
* description = @Translation("A language object.")
* )
*/
class Language extends TypedData {

View File

@ -2,14 +2,15 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Map.
* Contains \Drupal\Core\TypedData\Plugin\DataType\Map.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\TypedDataInterface;
/**
* The "map" data type.
@ -20,6 +21,11 @@ use Drupal\Core\TypedData\TypedDataInterface;
*
* By default there is no metadata for contained properties. Extending classes
* may want to override Map::getPropertyDefinitions() to define it.
*
* @DataType(
* id = "map",
* label = @Translation("Map")
* )
*/
class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface {

View File

@ -2,11 +2,13 @@
/**
* @file
* Contains \Drupal\Core\TypedData\Type\String.
* Contains \Drupal\Core\TypedData\Plugin\DataType\String.
*/
namespace Drupal\Core\TypedData\Type;
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
@ -14,6 +16,12 @@ use Drupal\Core\TypedData\TypedData;
*
* The plain value of a string is a regular PHP string. For setting the value
* any PHP variable that casts to a string may be passed.
*
* @DataType(
* id = "string",
* label = @Translation("String"),
* primitive_type = 2
* )
*/
class String extends TypedData {

View File

@ -0,0 +1,33 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\Plugin\DataType\Uri.
*/
namespace Drupal\Core\TypedData\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\TypedData\TypedData;
/**
* The URI data type.
*
* The plain value of a URI is an absolute URI represented as PHP string.
*
* @DataType(
* id = "uri",
* label = @Translation("URI"),
* primitive_type = 7
* )
*/
class Uri extends TypedData {
/**
* The data value.
*
* @var string
*/
protected $value;
}

View File

@ -15,56 +15,56 @@ final class Primitive {
/**
* The BOOLEAN primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Boolean
* @see \Drupal\Core\TypedData\Plugin\DataType\Boolean
*/
const BOOLEAN = 1;
/**
* The STRING primitive data type.
*
* @see \Drupal\Core\TypedData\Type\String
* @see \Drupal\Core\TypedData\Plugin\DataType\String
*/
const STRING = 2;
/**
* The INTEGER primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Integer
* @see \Drupal\Core\TypedData\Plugin\DataType\Integer
*/
const INTEGER = 3;
/**
* The FLOAT primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Float
* @see \Drupal\Core\TypedData\Plugin\DataType\Float
*/
const FLOAT = 4;
/**
* The DATE primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Date
* @see \Drupal\Core\TypedData\Plugin\DataType\Date
*/
const DATE = 5;
/**
* The DURATION primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Duration
* @see \Drupal\Core\TypedData\Plugin\DataType\Duration
*/
const DURATION = 6;
/**
* The URI primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Uri
* @see \Drupal\Core\TypedData\Plugin\DataType\Uri
*/
const URI = 7;
/**
* The BINARY primitive data type.
*
* @see \Drupal\Core\TypedData\Type\Binary
* @see \Drupal\Core\TypedData\Plugin\DataType\Binary
*/
const BINARY = 8;
}

View File

@ -1,17 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Email.
*/
namespace Drupal\Core\TypedData\Type;
/**
* The Email data type.
*
* The plain value of Email is the email address represented as PHP string.
*/
class Email extends String {
}

View File

@ -1,25 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\Type\Uri.
*/
namespace Drupal\Core\TypedData\Type;
use Drupal\Core\TypedData\TypedData;
/**
* The URI data type.
*
* The plain value of a URI is an absolute URI represented as PHP string.
*/
class Uri extends TypedData {
/**
* The data value.
*
* @var string
*/
protected $value;
}

View File

@ -1,62 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\TypedData\TypedDataFactory.
*/
namespace Drupal\Core\TypedData;
use InvalidArgumentException;
use Drupal\Component\Plugin\Factory\DefaultFactory;
use Drupal\Component\Plugin\Exception\PluginException;
/**
* A factory for typed data objects.
*
* The factory incorporates list classes if the typed data is a list as well as
* class overrides that are specified in data definitions.
*/
class TypedDataFactory extends DefaultFactory {
/**
* Implements \Drupal\Component\Plugin\Factory\FactoryInterface::createInstance().
*
* @param string $plugin_id
* The id of a plugin, i.e. the data type.
* @param array $configuration
* The plugin configuration, i.e. the data definition.
* @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.
*/
public function createInstance($plugin_id, array $configuration, $name = NULL, $parent = NULL) {
$type_definition = $this->discovery->getDefinition($plugin_id);
if (!isset($type_definition)) {
throw new InvalidArgumentException(format_string('Invalid data type %plugin_id has been given.', array('%plugin_id' => $plugin_id)));
}
// Allow per-data definition overrides of the used classes, i.e. take over
// classes specified in the data definition.
$key = empty($configuration['list']) ? 'class' : 'list class';
if (isset($configuration[$key])) {
$class = $configuration[$key];
}
elseif (isset($type_definition[$key])) {
$class = $type_definition[$key];
}
if (!isset($class)) {
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
}
return new $class($configuration, $name, $parent);
}
}

View File

@ -7,12 +7,11 @@
namespace Drupal\Core\TypedData;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
use InvalidArgumentException;
use Drupal\Component\Plugin\Discovery\ProcessDecorator;
use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Core\Plugin\Discovery\CacheDecorator;
use Drupal\Core\Plugin\Discovery\HookDiscovery;
use Drupal\Core\TypedData\Validation\MetadataFactory;
use Drupal\Core\Validation\ConstraintManager;
use Drupal\Core\Validation\DrupalTranslator;
@ -22,7 +21,7 @@ use Symfony\Component\Validator\Validation;
/**
* Manages data type plugins.
*/
class TypedDataManager extends PluginManagerBase {
class TypedDataManager extends DefaultPluginManager {
/**
* The validator used for validating typed data.
@ -38,17 +37,6 @@ class TypedDataManager extends PluginManagerBase {
*/
protected $constraintManager;
/**
* Type definition defaults which are merged in by the ProcessDecorator.
*
* @see \Drupal\Component\Plugin\PluginManagerBase::processDefinition()
*
* @var array
*/
protected $defaults = array(
'list class' => '\Drupal\Core\TypedData\ItemList',
);
/**
* An array of typed data property prototypes.
*
@ -56,13 +44,14 @@ class TypedDataManager extends PluginManagerBase {
*/
protected $prototypes = array();
public function __construct() {
$this->discovery = new HookDiscovery('data_type_info');
$this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
$this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
$this->discovery = new CacheDecorator($this->discovery, 'typed_data:types');
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$this->alterInfo($module_handler, 'data_type_info');
$this->setCacheBackend($cache_backend, $language_manager, 'typed_data:types');
$this->factory = new TypedDataFactory($this->discovery);
$annotation_namespaces = array(
'Drupal\Core\TypedData\Annotation' => DRUPAL_ROOT . '/core/lib',
);
parent::__construct('DataType', $namespaces, $annotation_namespaces, 'Drupal\Core\TypedData\Annotation\DataType');
}
/**
@ -84,7 +73,26 @@ class TypedDataManager extends PluginManagerBase {
* The instantiated typed data object.
*/
public function createInstance($plugin_id, array $configuration, $name = NULL, $parent = NULL) {
return $this->factory->createInstance($plugin_id, $configuration, $name, $parent);
$type_definition = $this->getDefinition($plugin_id);
if (!isset($type_definition)) {
throw new InvalidArgumentException(format_string('Invalid data type %plugin_id has been given.', array('%plugin_id' => $plugin_id)));
}
// Allow per-data definition overrides of the used classes, i.e. take over
// classes specified in the data definition.
$key = empty($configuration['list']) ? 'class' : 'list_class';
if (isset($configuration[$key])) {
$class = $configuration[$key];
}
elseif (isset($type_definition[$key])) {
$class = $type_definition[$key];
}
if (!isset($class)) {
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
}
return new $class($configuration, $name, $parent);
}
/**
@ -104,13 +112,13 @@ class TypedDataManager extends PluginManagerBase {
* - class: If set and 'list' is FALSE, the class to use for creating the
* typed data object; otherwise the default class of the data type will be
* used.
* - list class: If set and 'list' is TRUE, the class to use for creating
* - list_class: If set and 'list' is TRUE, the class to use for creating
* the typed data object; otherwise the default list class of the data
* type will be used.
* - settings: An array of settings, as required by the used 'class'. See
* the documentation of the class for supported or required settings.
* - list settings: An array of settings as required by the used
* 'list class'. See the documentation of the list class for support or
* - list_settings: An array of settings as required by the used
* 'list_class'. See the documentation of the list class for support or
* required settings.
* - constraints: An array of validation constraints. See
* \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details.
@ -134,18 +142,18 @@ class TypedDataManager extends PluginManagerBase {
*
* @see \Drupal::typedData()
* @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
* @see \Drupal\Core\TypedData\Type\Integer
* @see \Drupal\Core\TypedData\Type\Float
* @see \Drupal\Core\TypedData\Type\String
* @see \Drupal\Core\TypedData\Type\Boolean
* @see \Drupal\Core\TypedData\Type\Duration
* @see \Drupal\Core\TypedData\Type\Date
* @see \Drupal\Core\TypedData\Type\Uri
* @see \Drupal\Core\TypedData\Type\Binary
* @see \Drupal\Core\TypedData\Plugin\DataType\Integer
* @see \Drupal\Core\TypedData\Plugin\DataType\Float
* @see \Drupal\Core\TypedData\Plugin\DataType\String
* @see \Drupal\Core\TypedData\Plugin\DataType\Boolean
* @see \Drupal\Core\TypedData\Plugin\DataType\Duration
* @see \Drupal\Core\TypedData\Plugin\DataType\Date
* @see \Drupal\Core\TypedData\Plugin\DataType\Uri
* @see \Drupal\Core\TypedData\Plugin\DataType\Binary
* @see \Drupal\Core\Entity\Field\EntityWrapper
*/
public function create(array $definition, $value = NULL, $name = NULL, $parent = NULL) {
$wrapper = $this->factory->createInstance($definition['type'], $definition, $name, $parent);
$wrapper = $this->createInstance($definition['type'], $definition, $name, $parent);
if (isset($value)) {
$wrapper->setValue($value, FALSE);
}
@ -349,12 +357,16 @@ class TypedDataManager extends PluginManagerBase {
$type_definition = $this->getDefinition($definition['type']);
// Auto-generate a constraint for the primitive type if we have a mapping.
if (isset($type_definition['primitive type'])) {
$constraints[] = $validation_manager->create('PrimitiveType', array('type' => $type_definition['primitive type']));
if (isset($type_definition['primitive_type'])) {
$constraints[] = $validation_manager->create('PrimitiveType', array('type' => $type_definition['primitive_type']));
}
// Add in constraints specified by the data type.
if (isset($type_definition['constraints'])) {
foreach ($type_definition['constraints'] as $name => $options) {
// Annotations do not support empty arrays.
if ($options === TRUE) {
$options = array();
}
$constraints[] = $validation_manager->create($name, $options);
}
}

View File

@ -7,7 +7,7 @@
namespace Drupal\comment;
use Drupal\Core\Entity\Field\Type\IntegerItem;
use Drupal\Core\Entity\Plugin\DataType\IntegerItem;
/**
* The field item for the 'new' field.

View File

@ -66,7 +66,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
$definition = $config['testitem']->getDefinition();
$expected = array();
$expected['label'] = 'Test item';
$expected['class'] = '\Drupal\Core\TypedData\Type\String';
$expected['class'] = '\Drupal\Core\TypedData\Plugin\DataType\String';
$expected['type'] = 'string';
$this->assertEqual($definition, $expected, 'Automatic type detection on string item worked.');
$definition = $config['testlist']->getDefinition();
@ -162,12 +162,12 @@ class ConfigSchemaTest extends DrupalUnitTestBase {
// Try some simple properties.
$meta = config_typed()->get('system.site');
$property = $meta->get('name');
$this->assertTrue(is_a($property, 'Drupal\Core\TypedData\Type\String'), 'Got the right wrapper fo the site name property.');
$this->assertTrue(is_a($property, 'Drupal\Core\TypedData\Plugin\DataType\String'), 'Got the right wrapper fo the site name property.');
$this->assertEqual($property->getType(), 'label', 'Got the right string type for site name data.');
$this->assertEqual($property->getValue(), 'Drupal', 'Got the right string value for site name data.');
$property = $meta->get('page')->get('front');
$this->assertTrue(is_a($property, 'Drupal\Core\TypedData\Type\String'), 'Got the right wrapper fo the page.front property.');
$this->assertTrue(is_a($property, 'Drupal\Core\TypedData\Plugin\DataType\String'), 'Got the right wrapper fo the page.front property.');
$this->assertEqual($property->getType(), 'path', 'Got the right type for page.front data (undefined).');
$this->assertEqual($property->getValue(), 'user', 'Got the right value for page.front data.');

View File

@ -28,7 +28,7 @@ function email_field_info() {
'description' => t('This field stores an e-mail address in the database.'),
'default_widget' => 'email_default',
'default_formatter' => 'email_mailto',
'class' => 'Drupal\Core\Entity\Field\Type\EmailItem',
'class' => 'Drupal\Core\Entity\Plugin\DataType\EmailItem',
),
);
}

View File

@ -40,7 +40,7 @@ function entity_reference_field_info() {
*
* Set the "target_type" property definition for entity reference fields.
*
* @see \Drupal\Core\Entity\Field\Type\EntityReferenceItem::getPropertyDefinitions()
* @see \Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem::getPropertyDefinitions()
*
* @param array $info
* The property info array as returned by hook_entity_field_info().

View File

@ -7,7 +7,7 @@
namespace Drupal\entity_reference\Type;
use Drupal\Core\Entity\Field\Type\EntityReferenceItem;
use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
use Drupal\field\Plugin\Type\FieldType\ConfigEntityReferenceItemBase;
use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface;

View File

@ -7,7 +7,7 @@
namespace Drupal\field\Plugin\Type\FieldType;
use Drupal\Core\Entity\Field\Type\EntityReferenceItem;
use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface;
use Drupal\field\Plugin\Core\Entity\Field;

View File

@ -8,7 +8,7 @@
namespace Drupal\field\Plugin\Type\FieldType;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\Entity\Field\Type\Field;
use Drupal\Core\Entity\Field\Field;
use Drupal\field\Field as FieldAPI;
/**

View File

@ -19,7 +19,7 @@ class EntityReferenceItemNormalizer extends FieldItemNormalizer implements UuidR
*
* @var string
*/
protected $supportedInterfaceOrClass = 'Drupal\Core\Entity\Field\Type\EntityReferenceItem';
protected $supportedInterfaceOrClass = 'Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem';
/**
* Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()

View File

@ -2,15 +2,24 @@
/**
* @file
* Contains \Drupal\path\Type\PathItem.
* Contains \Drupal\path\Plugin\DataType\PathItem.
*/
namespace Drupal\path\Type;
namespace Drupal\path\Plugin\DataType;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'path_field' entity field item.
*
* @DataType(
* id = "path_field",
* label = @Translation("Path field item"),
* description = @Translation("An entity field containing a path alias and related data."),
* list_class = "\Drupal\Core\Entity\Field\Field"
* )
*/
class PathItem extends FieldItemBase {

View File

@ -262,19 +262,6 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
}
}
/**
* Implements hook_data_type_info().
*/
function path_data_type_info() {
$info['path_field'] = array(
'label' => t('Path field item'),
'description' => t('An entity field containing a path alias and related data.'),
'class' => '\Drupal\path\Type\PathItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
);
return $info;
}
/**
* Implements hook_entity_field_info().
*/

View File

@ -1,22 +1,22 @@
# Basic scalar data types from typed data.
boolean:
label: 'Boolean'
class: '\Drupal\Core\TypedData\Type\Boolean'
class: '\Drupal\Core\TypedData\Plugin\DataType\Boolean'
email:
label: 'Email'
class: '\Drupal\Core\TypedData\Type\Email'
class: '\Drupal\Core\TypedData\Plugin\DataType\Email'
integer:
label: 'Integer'
class: '\Drupal\Core\TypedData\Type\Integer'
class: '\Drupal\Core\TypedData\Plugin\DataType\Integer'
float:
label: 'Float'
class: '\Drupal\Core\TypedData\Type\Float'
class: '\Drupal\Core\TypedData\Plugin\DataType\Float'
string:
label: 'String'
class: '\Drupal\Core\TypedData\Type\String'
class: '\Drupal\Core\TypedData\Plugin\DataType\String'
uri:
label: 'Uri'
class: '\Drupal\Core\TypedData\Type\Uri'
class: '\Drupal\Core\TypedData\Plugin\DataType\Uri'
# Basic data types for configuration.
undefined:

View File

@ -131,57 +131,6 @@ function hook_cron() {
}
}
/**
* Defines available data types for the typed data API.
*
* The typed data API allows modules to support any kind of data based upon
* pre-defined primitive types and interfaces for complex data and lists.
*
* Defined data types may map to one of the pre-defined primitive types in
* \Drupal\Core\TypedData\Primitive or may be complex data types, containing one
* or more data properties. Typed data objects for complex data types have to
* implement the \Drupal\Core\TypedData\ComplexDataInterface. Further interfaces
* that may be implemented are:
* - \Drupal\Core\TypedData\AccessibleInterface
* - \Drupal\Core\TypedData\TranslatableInterface
*
* Furthermore, lists of data items are represented by objects implementing
* the \Drupal\Core\TypedData\ListInterface. A list contains items of the same
* data type, is ordered and may contain duplicates. The classed used for a list
* of items of a certain type may be specified using the 'list class' key.
*
* @return array
* An associative array where the key is the data type name and the value is
* again an associative array. Supported keys are:
* - label: The human readable label of the data type.
* - class: The associated typed data class. Must implement the
* \Drupal\Core\TypedData\TypedDataInterface.
* - list class: (optional) A typed data class used for wrapping multiple
* data items of the type. Must implement the
* \Drupal\Core\TypedData\ListInterface. Defaults to
* \Drupal\Core\TypedData\ItemList;
* - primitive type: (optional) Maps the data type to one of the pre-defined
* primitive types in \Drupal\Core\TypedData\Primitive. If set, it must be
* a constant defined by \Drupal\Core\TypedData\Primitive such as
* \Drupal\Core\TypedData\Primitive::STRING.
* - constraints: An array of validation constraints for this type. See
* \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details.
*
* @see \Drupal::typedData()
* @see Drupal\Core\TypedData\TypedDataManager::create()
* @see hook_data_type_info_alter()
*/
function hook_data_type_info() {
return array(
'email' => array(
'label' => t('Email'),
'class' => '\Drupal\email\Type\Email',
'primitive type' => \Drupal\Core\TypedData\Primitive::STRING,
'constraints' => array('Email' => array()),
),
);
}
/**
* Alter available data types for typed data wrappers.
*

View File

@ -2161,152 +2161,6 @@ function system_stream_wrappers() {
return $wrappers;
}
/**
* Implements hook_data_type_info().
*/
function system_data_type_info() {
return array(
'boolean' => array(
'label' => t('Boolean'),
'class' => '\Drupal\Core\TypedData\Type\Boolean',
'primitive type' => Primitive::BOOLEAN,
),
'string' => array(
'label' => t('String'),
'class' => '\Drupal\Core\TypedData\Type\String',
'primitive type' => Primitive::STRING,
),
'integer' => array(
'label' => t('Integer'),
'class' => '\Drupal\Core\TypedData\Type\Integer',
'primitive type' => Primitive::INTEGER,
),
'float' => array(
'label' => t('Float'),
'class' => '\Drupal\Core\TypedData\Type\Float',
'primitive type' => Primitive::FLOAT,
),
'date' => array(
'label' => t('Date'),
'class' => '\Drupal\Core\TypedData\Type\Date',
'primitive type' => Primitive::DATE,
),
'duration' => array(
'label' => t('Duration'),
'class' => '\Drupal\Core\TypedData\Type\Duration',
'primitive type' => Primitive::DURATION,
),
'uri' => array(
'label' => t('URI'),
'class' => '\Drupal\Core\TypedData\Type\Uri',
'primitive type' => Primitive::URI,
),
'email' => array(
'label' => t('Email'),
'class' => '\Drupal\Core\TypedData\Type\Email',
'primitive type' => Primitive::STRING,
'constraints' => array('Email' => array()),
),
'binary' => array(
'label' => t('Binary'),
'class' => '\Drupal\Core\TypedData\Type\Binary',
'primitive type' => Primitive::BINARY,
),
'map' => array(
'label' => t('Map'),
'class' => '\Drupal\Core\TypedData\Type\Map',
),
'any' => array(
'label' => t('Any data'),
'class' => '\Drupal\Core\TypedData\Type\Any',
),
'language' => array(
'label' => t('Language'),
'description' => t('A language object.'),
'class' => '\Drupal\Core\TypedData\Type\Language',
),
'entity' => array(
'label' => t('Entity'),
'description' => t('All kind of entities, e.g. nodes, comments or users.'),
'class' => '\Drupal\Core\Entity\Field\Type\EntityWrapper',
),
'entity_translation' => array(
'label' => t('Entity translation'),
'description' => t('A translation of an entity'),
'class' => '\Drupal\Core\Entity\Field\Type\EntityTranslation',
),
'boolean_field' => array(
'label' => t('Boolean field item'),
'description' => t('An entity field containing a boolean value.'),
'class' => '\Drupal\Core\Entity\Field\Type\BooleanItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'string_field' => array(
'label' => t('String field item'),
'description' => t('An entity field containing a string value.'),
'class' => '\Drupal\Core\Entity\Field\Type\StringItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'email_field' => array(
'label' => t('E-mail field item'),
'description' => t('An entity field containing an e-mail value.'),
'class' => '\Drupal\Core\Entity\Field\Type\EmailItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'integer_field' => array(
'label' => t('Integer field item'),
'description' => t('An entity field containing an integer value.'),
'class' => '\Drupal\Core\Entity\Field\Type\IntegerItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'date_field' => array(
'label' => t('Date field item'),
'description' => t('An entity field containing a date value.'),
'class' => '\Drupal\Core\Entity\Field\Type\DateItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'language_field' => array(
'label' => t('Language field item'),
'description' => t('An entity field referencing a language.'),
'class' => '\Drupal\Core\Entity\Field\Type\LanguageItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
'constraints' => array(
'ComplexData' => array(
'value' => array('Length' => array('max' => 12)),
),
),
),
'entity_reference_field' => array(
'label' => t('Entity reference field item'),
'description' => t('An entity field containing an entity reference.'),
'class' => '\Drupal\Core\Entity\Field\Type\EntityReferenceItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'uri_field' => array(
'label' => t('URI field item'),
'description' => t('An entity field containing a URI'),
'class' => '\Drupal\Core\Entity\Field\Type\UriItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
),
'uuid_field' => array(
'label' => t('UUID field item'),
'description' => t('An entity field containing a UUID.'),
'class' => '\Drupal\Core\Entity\Field\Type\UuidItem',
'list class' => '\Drupal\Core\Entity\Field\Type\Field',
'constraints' => array(
'ComplexData' => array(
'value' => array('Length' => array('max' => 128)),
),
),
),
// Expose each field type as a data type. We add one single entry, which
// will be expanded through plugin derivatives.
'field_item' => array(
'derivative' => '\Drupal\Core\Entity\Plugin\DataType\FieldDataTypeDerivative',
),
);
}
/**
* Menu item access callback - only enabled themes can be accessed.
*/