diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index e9808d2..f552c54 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -10,6 +10,7 @@ use Drupal\Component\Plugin\PluginManagerBase; use Drupal\Component\Plugin\Factory\DefaultFactory; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Entity\Field\FieldDefinition; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageManager; use Drupal\Core\Language\Language; @@ -456,15 +457,8 @@ public function getAdminRouteInfo($entity_type, $bundle) { * is passed, no bundle-specific fields are included. Defaults to NULL. * * @return array - * An array of field definitions of entity fields, keyed by field - * name. In addition to the typed data definition keys as described at - * \Drupal\Core\TypedData\TypedDataManager::create() the following keys are - * supported: - * - queryable: Whether the field is queryable via QueryInterface. - * Defaults to TRUE if 'computed' is FALSE or not set, to FALSE otherwise. - * - translatable: Whether the field is translatable. Defaults to FALSE. - * - configurable: A boolean indicating whether the field is configurable - * via field.module. Defaults to FALSE. + * An array of entity field definitions, keyed by field name. See + * \Drupal\Core\Entity\Field\FieldDefinitionInterface. * * @see \Drupal\Core\TypedData\TypedDataManager::create() * @see \Drupal\Core\Entity\EntityManager::getFieldDefinitionsByConstraints() @@ -477,6 +471,7 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) { $this->entityFieldInfo[$entity_type] = $cache->data; } else { + // @todo: Refactor to allow for per-bundle overrides. $class = $this->factory->getPluginClass($entity_type, $this->getDefinition($entity_type)); $this->entityFieldInfo[$entity_type] = array( 'definitions' => $class::baseFieldDefinitions($entity_type), @@ -496,12 +491,18 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) { $hooks = array('entity_field_info', $entity_type . '_field_info'); $this->moduleHandler->alter($hooks, $this->entityFieldInfo[$entity_type], $entity_type); - // Enforce fields to be multiple by default. - foreach ($this->entityFieldInfo[$entity_type]['definitions'] as &$definition) { - $definition['list'] = TRUE; + // Enforce field definitions to be objects. + foreach ($this->entityFieldInfo[$entity_type]['definitions'] as $field_name => &$definition) { + if (is_array($definition)) { + $definition = FieldDefinition::createFromOldStyleDefinition($definition) + ->setFieldName($field_name); + } } - foreach ($this->entityFieldInfo[$entity_type]['optional'] as &$definition) { - $definition['list'] = TRUE; + foreach ($this->entityFieldInfo[$entity_type]['optional'] as $field_name => &$definition) { + if (is_array($definition)) { + $definition = FieldDefinition::createFromOldStyleDefinition($definition) + ->setFieldName($field_name); + } } $this->cache->set($cid, $this->entityFieldInfo[$entity_type], CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE, 'entity_field_info' => TRUE)); } diff --git a/core/lib/Drupal/Core/Entity/Field/FieldDefinition.php b/core/lib/Drupal/Core/Entity/Field/FieldDefinition.php index ef79967..226a9ca 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldDefinition.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldDefinition.php @@ -6,34 +6,21 @@ */ namespace Drupal\Core\Entity\Field; + use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\TypedData\DataDefinition; +use Drupal\Core\TypedData\ListDefinition; /** * A class for defining entity fields. */ -class FieldDefinition implements FieldDefinitionInterface { - - /** - * The array holding values for all definition keys. - * - * @var array - */ - protected $definition = array(); - - /** - * Constructs a new FieldDefinition object. - * - * @param array $definition - * (optional) If given, a definition represented as array. - */ - public function __construct(array $definition = array()) { - $this->definition = $definition; - } +class FieldDefinition extends ListDefinition implements FieldDefinitionInterface, \ArrayAccess { /** * {@inheritdoc} */ public function getFieldName() { + // @todo: Should "name" be part of the data definition also? return $this->definition['field_name']; } @@ -56,7 +43,7 @@ public function setFieldName($name) { */ public function getFieldType() { // Cut of the leading field_item: prefix from 'field_item:FIELD_TYPE'. - $parts = explode(':', $this->definition['type']); + $parts = explode(':', $this->getItemDefinition()->getDataType()); return $parts[1]; } @@ -70,43 +57,60 @@ public function getFieldType() { * The object itself for chaining. */ public function setFieldType($type) { - $this->definition['type'] = 'field_item:' . $type; + $this->getItemDefinition()->setDataType('field_item:' . $type); return $this; } /** - * Sets a field setting. + * {@inheritdoc} + */ + public function getFieldSettings() { + return $this->getItemDefinition()->getSettings(); + } + + /** + * Sets field settings. * - * @param string $type - * The field type to set. + * @param array $settings + * The value to set. * * @return \Drupal\Core\Entity\Field\FieldDefinition * The object itself for chaining. */ - public function setFieldSetting($setting_name, $value) { - $this->definition['settings'][$setting_name] = $value; - return $this; + public function setFieldSettings(array $settings) { + return $this->getItemDefinition()->setSettings($settings); } /** * {@inheritdoc} */ - public function getFieldSettings() { - return $this->definition['settings']; + public function getFieldSetting($setting_name) { + $settings = $this->getFieldSettings(); + return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL; } /** - * {@inheritdoc} + * Sets a field setting. + * + * @param string $setting_name + * The field setting to set. + * @param mixed $value + * The value to set. + * + * @return \Drupal\Core\Entity\Field\FieldDefinition + * The object itself for chaining. */ - public function getFieldSetting($setting_name) { - return isset($this->definition['settings'][$setting_name]) ? $this->definition['settings'][$setting_name] : NULL; + public function setFieldSetting($setting_name, $value) { + $settings = $this->getFieldSettings(); + $settings[$setting_name] = $value; + return $this->setFieldSettings($settings); } /** * {@inheritdoc} */ public function getFieldPropertyNames() { - return array_keys(\Drupal::typedData()->create($this->definition['type'])->getPropertyDefinitions()); + return array_keys(\Drupal::typedData()->create($this->getItemDefinition())->getPropertyDefinitions()); } /** @@ -134,42 +138,28 @@ public function setTranslatable($translatable) { * {@inheritdoc} */ public function getFieldLabel() { - return $this->definition['label']; + return $this->getLabel(); } /** - * Sets the field label. - * - * @param string $label - * The field label to set. - * - * @return \Drupal\Core\Entity\Field\FieldDefinition - * The object itself for chaining. + * {@inheritdoc} */ public function setFieldLabel($label) { - $this->definition['label'] = $label; - return $this; + return $this->setLabel($label); } /** * {@inheritdoc} */ public function getFieldDescription() { - return $this->definition['description']; + return $this->getDescription(); } /** - * Sets the field label. - * - * @param string $description - * The field label to set. - * - * @return \Drupal\Core\Entity\Field\FieldDefinition - * The object itself for chaining. + * {@inheritdoc} */ public function setFieldDescription($description) { - $this->definition['description'] = $description; - return $this; + return $this->setDescription($description); } /** @@ -184,21 +174,40 @@ public function getFieldCardinality() { * {@inheritdoc} */ public function isFieldRequired() { - return !empty($this->definition['required']); + return $this->isRequired(); } /** * Sets whether the field is required. * - * @param bool $required - * TRUE if the field is required, FALSE otherwise. + * @param boolean $required + * Whether the field is required. * * @return \Drupal\Core\Entity\Field\FieldDefinition * The object itself for chaining. */ public function setFieldRequired($required) { - $this->definition['required'] = $required; - return $this; + return $this->setRequired($required); + } + + /** + * {@inheritdoc} + */ + public function isFieldQueryable() { + return isset($this->definition['queryable']) ? $this->definition['queryable'] : !$this->isComputed(); + } + + /** + * Sets whether the field is queryable. + * + * @param boolean $queryable + * Whether the field is queryable. + * + * @return \Drupal\Core\Entity\Field\FieldDefinition + * The object itself for chaining. + */ + public function setFieldQueryable($queryable) { + return $this->setRequired($queryable); } /** @@ -213,7 +222,9 @@ public function setFieldRequired($required) { * The object itself for chaining. */ public function setPropertyConstraints($name, array $constraints) { - $this->definition['item_definition']['constraints']['ComplexData'][$name] = $constraints; + $item_constraints = $this->getItemDefinition()->getConstraints(); + $item_constraints['ComplexData'][$name] = $constraints; + $this->getItemDefinition()->setConstraints($item_constraints); return $this; } @@ -231,4 +242,68 @@ public function getFieldDefaultValue(EntityInterface $entity) { return $this->getFieldSetting('default_value'); } + /** + * Allows creating field definition objects from old style definition arrays. + * + * @todo: Remove once no old-style definition arrays need to be supported. + */ + public static function createFromOldStyleDefinition(array $definition) { + unset($definition['list']); + + // Separate the list item definition from the list definition. + $list_definition = $definition; + $list_definition['type'] = 'entity_field'; + + // Constraints and settings apply to the list item. + unset($list_definition['constraints']); + unset($list_definition['settings']); + + $field_definition = new FieldDefinition($list_definition); + if (isset($definition['list_class'])) { + $field_definition->setClass($definition['list_class']); + } + else { + $type_definition = \Drupal::typedData()->getDefinition($definition['type']); + if (isset($type_definition['list_class'])) { + $field_definition->setClass($type_definition['list_class']); + } + } + + // Take care of the item definition. + $item_definition = new DataDefinition($definition); + if (isset($definition['settings'])) { + $item_definition->setSettings($definition['settings']); + } + if (isset($definition['constraints'])) { + $item_definition->setConstraints($definition['constraints']); + } + $field_definition->setItemDefinition($item_definition); + return $field_definition; + } + + /** + * {@inheritdoc} + */ + public function &offsetGet($offset) { + if ($offset == 'type') { + // What previously was "type" is now the type of the list item. + $type = &$this->itemDefinition->offsetGet('type'); + return $type; + } + if (!isset($this->definition[$offset])) { + $this->definition[$offset] = NULL; + } + return $this->definition[$offset]; + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) { + if ($offset == 'type') { + // What previously was "type" is now the type of the list item. + $this->itemDefinition['type'] = $value; + } + $this->definition[$offset] = $value; + } } diff --git a/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php index b8dc354..c2bc4ce 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php @@ -13,9 +13,10 @@ * Defines an interface for entity field definitions. * * An entity field is a data object that holds the values of a particular field - * for a particular entity (see \Drupal\Core\Entity\Field\FieldItemListInterface). For - * example, $node_1->body and $node_2->body contain different data and therefore - * are different field objects. + * for a particular entity (see + * \Drupal\Core\Entity\Field\FieldItemListInterface). For example, $node_1->body + * and $node_2->body contain different data and therefore are different field + * objects. * * In contrast, an entity field *definition* is an object that returns * information *about* a field (e.g., its type and settings) rather than its @@ -36,10 +37,9 @@ * * However, entity base fields, such as $node->title, are not managed by * field.module and its "field_entity"/"field_instance" configuration entities. - * Therefore, their definitions are provided by different objects that implement - * this interface. - * @todo That is still in progress: https://drupal.org/node/1949932. Update this - * documentation with details when that's implemented. + * Therefore, their definitions are provided by different objects based on the + * class \Drupal\Core\Entity\Field\FieldDefinition, which implements this + * interface as well. * * Field definitions may fully define a concrete data object (e.g., * $node_1->body), or may provide a best-guess definition for a data object that @@ -50,6 +50,8 @@ * abstractly, and present Views configuration options to the administrator * based on that abstract definition, even though that abstract definition can * differ from the concrete definition of any particular node's body field. + * + * @todo Extends this from DataDefinitionInterface. */ interface FieldDefinitionInterface { @@ -129,6 +131,13 @@ public function isFieldTranslatable(); public function isFieldConfigurable(); /** + * Determines whether the field is queryable via QueryInterface. + * + * @return bool + */ + public function isFieldQueryable(); + + /** * Returns the human-readable label for the field. * * @return string diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index 15744c0..d459c49 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -8,6 +8,8 @@ namespace Drupal\Core\Entity\Field; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\TypedData\DataDefinition; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\Plugin\DataType\Map; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\user; @@ -23,9 +25,16 @@ abstract class FieldItemBase extends Map implements FieldItemInterface { /** + * The field's definition. + * + * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface + */ + protected $definition; + + /** * Overrides \Drupal\Core\TypedData\TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent); // Initialize computed properties by default, such that they get cloned // with the whole item. diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemList.php b/core/lib/Drupal/Core/Entity/Field/FieldItemList.php index 4b4e1eb..a2b308c 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemList.php @@ -10,7 +10,7 @@ use Drupal\Core\Entity\Field\FieldItemListInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\TypedDataInterface; -use Drupal\Core\TypedData\ItemList; +use Drupal\Core\TypedData\Plugin\DataType\ItemList; use Drupal\Core\Language\Language; /** @@ -45,7 +45,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface { /** * Overrides TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent); $this->definition['field_name'] = $name; // Always initialize one empty item as most times a value for at least one @@ -80,7 +80,7 @@ public function getLangcode() { * {@inheritdoc} */ public function getFieldDefinition() { - return new FieldDefinition($this->definition); + return $this->definition; } /** @@ -109,7 +109,7 @@ public function getValue($include_computed = FALSE) { } /** - * Overrides \Drupal\Core\TypedData\ItemList::setValue(). + * Overrides \Drupal\Core\TypedData\Plugin\DataType\ItemList::setValue(). */ public function setValue($values, $notify = TRUE) { if (!isset($values) || $values === array()) { @@ -214,10 +214,8 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N * {@inheritdoc} */ public function applyDefaultValue($notify = TRUE) { - // @todo Remove getDefaultValue() and directly call - // FieldDefinition::getFieldDefaultValue() here, once - // https://drupal.org/node/2047229 is fixed. - $value = $this->getDefaultValue(); + $value = $this->getFieldDefinition()->getFieldDefaultValue($this->getEntity()); + // NULL or array() mean "no default value", but 0, '0' and the empty string // are valid default values. if (!isset($value) || (is_array($value) && empty($value))) { @@ -231,18 +229,6 @@ public function applyDefaultValue($notify = TRUE) { } /** - * Returns the default value for the field. - * - * @return array - * The default value for the field. - */ - protected function getDefaultValue() { - if (isset($this->definition['settings']['default_value'])) { - return $this->definition['settings']['default_value']; - } - } - - /** * {@inheritdoc} */ public function getConstraints() { diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/FieldItemList.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/FieldItemList.php new file mode 100644 index 0000000..b3ce264 --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/FieldItemList.php @@ -0,0 +1,27 @@ +definition = $definition; + } + + /** + * {@inheritdoc} + */ + public function getDataType() { + return $this->definition['type']; + } + + /** + * Sets the data type. + * + * @param string $type + * The data type to set. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setDataType($type) { + $this->definition['type'] = $type; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getLabel() { + return isset($this->definition['label']) ? $this->definition['label'] : NULL; + } + + /** + * Sets the human-readable label. + * + * @param string $label + * The label to set. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setLabel($label) { + $this->definition['label'] = $label; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getDescription() { + return isset($this->definition['description']) ? $this->definition['description'] : NULL; + } + + /** + * Sets the human-readable description. + * + * @param string $description + * The description to set. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setDescription($description) { + $this->definition['description'] = $description; + return $this; + } + + /** + * {@inheritdoc} + */ + public function isList() { + return ($this instanceof ListDefinitionInterface); + } + + /** + * {@inheritdoc} + */ + public function isReadOnly() { + if (!isset($this->definition['read-only'])) { + // Default to read-only if the data value is computed. + return $this->isComputed(); + } + return $this->definition['read-only']; + } + + /** + * Sets whether the data is read-only. + * + * @param boolean $read-only + * Whether the data is read-only. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setReadOnly($read_only) { + $this->definition['read-only'] = $read_only; + return $this; + } + + /** + * {@inheritdoc} + */ + public function isComputed() { + return !empty($this->definition['computed']); + } + + /** + * Sets whether the data is computed. + * + * @param boolean $computed + * Whether the data is computed. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setComputed($computed) { + $this->definition['computed'] = $computed; + return $this; + } + + /** + * {@inheritdoc} + */ + public function isRequired() { + return !empty($this->definition['required']); + } + + /** + * Sets whether the data is required. + * + * @param boolean $required + * Whether the data is required. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setRequired($required) { + $this->definition['required'] = $required; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getClass() { + return isset($this->definition['class']) ? $this->definition['class'] : NULL; + } + + /** + * Sets the class used for creating the typed data object. + * + * @param string|null $class + * The class to use. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setClass($class) { + $this->definition['class'] = $class; + return $this; + } + + /** + * Returns the array of settings, as required by the used class. + * + * See the documentation of the class for supported or required settings. + * + * @return array + * The array of settings. + */ + public function getSettings() { + return isset($this->definition['settings']) ? $this->definition['settings'] : array(); + } + + /** + * Sets the array of settings, as required by the used class. + * + * @param array $settings + * The array of settings. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setSettings(array $settings) { + $this->definition['settings'] = $settings; + return $this; + } + + /** + * Returns an array of validation constraints. + * + * See \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details. + * + * @return array + * Array of constraints, each being an instance of + * \Symfony\Component\Validator\Constraint. + */ + public function getConstraints() { + return isset($this->definition['constraints']) ? $this->definition['constraints'] : array(); + } + + /** + * Sets the array of validation constraints. + * + * See \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details. + * + * @param array $constraints + * The array of constraints. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function setConstraints(array $constraints) { + $this->definition['constraints'] = $constraints; + return $this; + } + + /** + * Adds a validation constraint. + * + * See \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details. + * + * @param string $constraint_name + * The name of the constraint to add, i.e. its plugin id. + * @param array|null $options + * The constraint options as required by the constraint plugin, or NULL. + * + * @return \Drupal\Core\TypedData\DataDefinition + * The object itself for chaining. + */ + public function addConstraint($constraint_name, $options = NULL) { + $this->definition['constraints'][$constraint_name] = $options; + return $this; + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) { + // PHP's array access does not work correctly with isset(), so we have to + // bake isset() in here. See https://bugs.php.net/bug.php?id=41727. + return array_key_exists($offset, $this->definition) && isset($this->definition[$offset]); + } + + /** + * {@inheritdoc} + */ + public function &offsetGet($offset) { + if (!isset($this->definition[$offset])) { + $this->definition[$offset] = NULL; + } + return $this->definition[$offset]; + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) { + $this->definition[$offset] = $value; + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) { + unset($this->definition[$offset]); + } + + /** + * Returns all definition values as array. + * + * @return array + */ + public function toArray() { + return $this->definition; + } + + /** + * Allows creating data definition objects from old style definition arrays. + * + * @todo: Remove once no old-style definition arrays need to be supported. + */ + public static function createFromOldStyleDefinition(array $definition) { + if (empty($definition['list'])) { + return new DataDefinition($definition); + } + + // If the definition describes a list, separate the list item definition + // from the list definition. + unset($definition['list']); + + $list_definition = $definition; + $list_definition['type'] = 'list'; + + // Constraints and settings apply to the list item. + unset($list_definition['constraints']); + unset($list_definition['settings']); + + $list_definition = new ListDefinition($list_definition); + if (isset($definition['list_class'])) { + $list_definition->setClass($definition['list_class']); + } + else { + $type_definition = \Drupal::typedData()->getDefinition($definition['type']); + if (isset($type_definition['list_class'])) { + $list_definition->setClass($type_definition['list_class']); + } + } + + // Take care of the item definition. + $item_definition = new DataDefinition($definition); + if (isset($definition['settings'])) { + $item_definition->setSettings($definition['settings']); + } + if (isset($definition['constraints'])) { + $item_definition->setConstraints($definition['constraints']); + } + $list_definition->setItemDefinition($item_definition); + return $list_definition; + } +} diff --git a/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php b/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php new file mode 100644 index 0000000..d866d15 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php @@ -0,0 +1,115 @@ +list)) { - $values = array(); - foreach ($this->list as $delta => $item) { - $values[$delta] = $item->getValue(); - } - return $values; - } - } - - /** - * Overrides \Drupal\Core\TypedData\TypedData::setValue(). - * - * @param array|null $values - * An array of values of the field items, or NULL to unset the field. - */ - public function setValue($values, $notify = TRUE) { - if (!isset($values) || $values === array()) { - $this->list = $values; - } - else { - if (!is_array($values)) { - throw new \InvalidArgumentException('Cannot set a list with a non-array value.'); - } - - // Clear the values of properties for which no value has been passed. - if (isset($this->list)) { - $this->list = array_intersect_key($this->list, $values); - } - - // Set the values. - foreach ($values as $delta => $value) { - if (!is_numeric($delta)) { - throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.'); - } - elseif (!isset($this->list[$delta])) { - $this->list[$delta] = $this->createItem($delta, $value); - } - else { - $this->list[$delta]->setValue($value); - } - } - } - // Notify the parent of any changes. - if ($notify && isset($this->parent)) { - $this->parent->onChange($this->name); - } - } - - /** - * Overrides \Drupal\Core\TypedData\TypedData::getString(). - */ - public function getString() { - $strings = array(); - if (isset($this->list)) { - foreach ($this->list as $item) { - $strings[] = $item->getString(); - } - // Remove any empty strings resulting from empty items. - return implode(', ', array_filter($strings, 'drupal_strlen')); - } - } - - /** - * Overrides \Drupal\Core\TypedData\TypedData::getConstraints(). - */ - public function getConstraints() { - // Apply the constraints to the list items only. - return array(); - } - - /** - * Implements \ArrayAccess::offsetExists(). - */ - public function offsetExists($offset) { - return isset($this->list) && array_key_exists($offset, $this->list) && $this->offsetGet($offset)->getValue() !== NULL; - } - - /** - * Implements \ArrayAccess::offsetUnset(). - */ - public function offsetUnset($offset) { - if (isset($this->list)) { - unset($this->list[$offset]); - } - } - - /** - * Implements \ArrayAccess::offsetGet(). - */ - public function offsetGet($offset) { - if (!is_numeric($offset)) { - throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.'); - } - // Allow getting not yet existing items as well. - // @todo: Maybe add a public createItem() method in addition? - elseif (!isset($this->list[$offset])) { - $this->list[$offset] = $this->createItem($offset); - } - return $this->list[$offset]; - } - - /** - * Helper for creating a list item object. - * - * @return \Drupal\Core\TypedData\TypedDataInterface - */ - protected function createItem($offset = 0, $value = NULL) { - return \Drupal::typedData()->getPropertyInstance($this, $offset, $value); - } - - /** - * Implements \Drupal\Core\TypedData\ListInterface::getItemDefinition(). - */ - public function getItemDefinition() { - return array('list' => FALSE) + $this->definition; - } - - /** - * Implements \ArrayAccess::offsetSet(). - */ - public function offsetSet($offset, $value) { - if (!isset($offset)) { - // The [] operator has been used so point at a new entry. - $offset = $this->list ? max(array_keys($this->list)) + 1 : 0; - } - if (is_numeric($offset)) { - // Support setting values via typed data objects. - if ($value instanceof TypedDataInterface) { - $value = $value->getValue(); - } - $this->offsetGet($offset)->setValue($value); - } - else { - throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.'); - } - } - - /** - * Implements \IteratorAggregate::getIterator(). - */ - public function getIterator() { - if (isset($this->list)) { - return new \ArrayIterator($this->list); - } - return new \ArrayIterator(array()); - } - - /** - * Implements \Countable::count(). - */ - public function count() { - return isset($this->list) ? count($this->list) : 0; - } - - /** - * Implements \Drupal\Core\TypedData\ListInterface::isEmpty(). - */ - public function isEmpty() { - if (isset($this->list)) { - foreach ($this->list as $item) { - if ($item instanceof ComplexDataInterface || $item instanceof ListInterface) { - if (!$item->isEmpty()) { - return FALSE; - } - } - // Other items are treated as empty if they have no value only. - elseif ($item->getValue() !== NULL) { - return FALSE; - } - } - } - return TRUE; - } - - /** - * Implements \Drupal\Core\TypedData\ListInterface::onChange(). - */ - public function onChange($delta) { - // Notify the parent of changes. - if (isset($this->parent)) { - $this->parent->onChange($this->name); - } - } - - /** - * Magic method: Implements a deep clone. - */ - public function __clone() { - if (isset($this->list)) { - foreach ($this->list as $delta => $item) { - $this->list[$delta] = clone $item; - $this->list[$delta]->setContext($delta, $this); - } - } - } -} diff --git a/core/lib/Drupal/Core/TypedData/ListDefinition.php b/core/lib/Drupal/Core/TypedData/ListDefinition.php new file mode 100644 index 0000000..fc6b557 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/ListDefinition.php @@ -0,0 +1,44 @@ +itemDefinition = new DataDefinition(); + } + + /** + * {@inheritdoc} + */ + public function getItemDefinition() { + return $this->itemDefinition; + } + + /** + * Sets the item definition. + */ + public function setItemDefinition(DataDefinitionInterface $definition) { + $this->itemDefinition = $definition; + return $this; + } +} diff --git a/core/lib/Drupal/Core/TypedData/ListDefinitionInterface.php b/core/lib/Drupal/Core/TypedData/ListDefinitionInterface.php new file mode 100644 index 0000000..c07d60e --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/ListDefinitionInterface.php @@ -0,0 +1,26 @@ +list)) { + $values = array(); + foreach ($this->list as $delta => $item) { + $values[$delta] = $item->getValue(); + } + return $values; + } + } + + /** + * Overrides \Drupal\Core\TypedData\TypedData::setValue(). + * + * @param array|null $values + * An array of values of the field items, or NULL to unset the field. + */ + public function setValue($values, $notify = TRUE) { + if (!isset($values) || $values === array()) { + $this->list = $values; + } + else { + if (!is_array($values)) { + throw new \InvalidArgumentException('Cannot set a list with a non-array value.'); + } + + // Clear the values of properties for which no value has been passed. + if (isset($this->list)) { + $this->list = array_intersect_key($this->list, $values); + } + + // Set the values. + foreach ($values as $delta => $value) { + if (!is_numeric($delta)) { + throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.'); + } + elseif (!isset($this->list[$delta])) { + $this->list[$delta] = $this->createItem($delta, $value); + } + else { + $this->list[$delta]->setValue($value); + } + } + } + // Notify the parent of any changes. + if ($notify && isset($this->parent)) { + $this->parent->onChange($this->name); + } + } + + /** + * Overrides \Drupal\Core\TypedData\TypedData::getString(). + */ + public function getString() { + $strings = array(); + if (isset($this->list)) { + foreach ($this->list as $item) { + $strings[] = $item->getString(); + } + // Remove any empty strings resulting from empty items. + return implode(', ', array_filter($strings, 'drupal_strlen')); + } + } + + /** + * Overrides \Drupal\Core\TypedData\TypedData::getConstraints(). + */ + public function getConstraints() { + if (isset($this->definition['item_definition']) && isset($this->definition['constraints'])) { + return $this->definition['constraints']; + } + // BC: If no item definition is specified, we apply possibly specified + // constraints to the list items only. + return array(); + } + + /** + * Implements \ArrayAccess::offsetExists(). + */ + public function offsetExists($offset) { + return isset($this->list) && array_key_exists($offset, $this->list) && $this->offsetGet($offset)->getValue() !== NULL; + } + + /** + * Implements \ArrayAccess::offsetUnset(). + */ + public function offsetUnset($offset) { + if (isset($this->list)) { + unset($this->list[$offset]); + } + } + + /** + * Implements \ArrayAccess::offsetGet(). + */ + public function offsetGet($offset) { + if (!is_numeric($offset)) { + throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.'); + } + // Allow getting not yet existing items as well. + // @todo: Maybe add a public createItem() method in addition? + elseif (!isset($this->list[$offset])) { + $this->list[$offset] = $this->createItem($offset); + } + return $this->list[$offset]; + } + + /** + * Helper for creating a list item object. + * + * @return \Drupal\Core\TypedData\TypedDataInterface + */ + protected function createItem($offset = 0, $value = NULL) { + return \Drupal::typedData()->getPropertyInstance($this, $offset, $value); + } + + /** + * Implements \Drupal\Core\TypedData\ListInterface::getItemDefinition(). + */ + public function getItemDefinition() { + return $this->definition->getItemDefinition(); + } + + /** + * Implements \ArrayAccess::offsetSet(). + */ + public function offsetSet($offset, $value) { + if (!isset($offset)) { + // The [] operator has been used so point at a new entry. + $offset = $this->list ? max(array_keys($this->list)) + 1 : 0; + } + if (is_numeric($offset)) { + // Support setting values via typed data objects. + if ($value instanceof TypedDataInterface) { + $value = $value->getValue(); + } + $this->offsetGet($offset)->setValue($value); + } + else { + throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.'); + } + } + + /** + * Implements \IteratorAggregate::getIterator(). + */ + public function getIterator() { + if (isset($this->list)) { + return new \ArrayIterator($this->list); + } + return new \ArrayIterator(array()); + } + + /** + * Implements \Countable::count(). + */ + public function count() { + return isset($this->list) ? count($this->list) : 0; + } + + /** + * Implements \Drupal\Core\TypedData\ListInterface::isEmpty(). + */ + public function isEmpty() { + if (isset($this->list)) { + foreach ($this->list as $item) { + if ($item instanceof ComplexDataInterface || $item instanceof ListInterface) { + if (!$item->isEmpty()) { + return FALSE; + } + } + // Other items are treated as empty if they have no value only. + elseif ($item->getValue() !== NULL) { + return FALSE; + } + } + } + return TRUE; + } + + /** + * Implements \Drupal\Core\TypedData\ListInterface::onChange(). + */ + public function onChange($delta) { + // Notify the parent of changes. + if (isset($this->parent)) { + $this->parent->onChange($this->name); + } + } + + /** + * Magic method: Implements a deep clone. + */ + public function __clone() { + if (isset($this->list)) { + foreach ($this->list as $delta => $item) { + $this->list[$delta] = clone $item; + $this->list[$delta]->setContext($delta, $this); + } + } + } +} diff --git a/core/lib/Drupal/Core/TypedData/TypedData.php b/core/lib/Drupal/Core/TypedData/TypedData.php index 031828a..6e021e1 100644 --- a/core/lib/Drupal/Core/TypedData/TypedData.php +++ b/core/lib/Drupal/Core/TypedData/TypedData.php @@ -20,7 +20,7 @@ /** * The data definition. * - * @var array + * @var \Drupal\Core\TypedData\DataDefinitionInterface */ protected $definition; @@ -41,7 +41,7 @@ /** * Constructs a TypedData object given its definition and context. * - * @param array $definition + * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition * The data definition. * @param string $name * (optional) The name of the created property, or NULL if it is the root @@ -52,7 +52,7 @@ * * @see \Drupal\Core\TypedData\TypedDataManager::create() */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { $this->definition = $definition; $this->parent = $parent; $this->name = $name; diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php index bbdf4ea..bef5a36 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -18,7 +18,9 @@ * Gets the data definition. * * @return array - * The data definition array. + * The data definition represented as array. + * + * @see \Drupal\Core\TypedData\DataDefinition */ public function getDefinition(); diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index bbc0d7f..107ad2f 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -52,77 +52,48 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac } /** - * Implements \Drupal\Component\Plugin\PluginManagerInterface::createInstance(). + * Instantiates a typed data object. * - * @param string $plugin_id - * The id of a plugin, i.e. the data type. + * @param string $data_type + * The data type, for which a typed object should be instantiated. * @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. + * 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. */ - public function createInstance($plugin_id, array $configuration, $name = NULL, $parent = NULL) { - $type_definition = $this->getDefinition($plugin_id); + public function createInstance($data_type, array $configuration) { + $data_definition = $configuration['data_definition']; + $type_definition = $this->getDefinition($data_type); if (!isset($type_definition)) { - throw new \InvalidArgumentException(format_string('Invalid data type %plugin_id has been given.', array('%plugin_id' => $plugin_id))); + throw new \InvalidArgumentException(format_string('Invalid data type %plugin_id has been given.', array('%plugin_id' => $data_type))); } // 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]; - } + $class = $data_definition->getClass(); + $class = isset($class) ? $class : $type_definition['class']; if (!isset($class)) { - throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id)); + throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type)); } - return new $class($configuration, $name, $parent); + return new $class($data_definition, $configuration['name'], $configuration['parent']); } /** * Creates a new typed data object instance. * - * @param array $definition - * The data definition array with the following array keys and values: - * - type: The data type of the data to wrap. Required. - * - label: A human readable label. - * - description: A human readable description. - * - list: Whether the data is multi-valued, i.e. a list of data items. - * Defaults to FALSE. - * - computed: A boolean specifying whether the data value is computed by - * the object, e.g. depending on some other values. - * - read-only: A boolean specifying whether the data is read-only. Defaults - * to TRUE for computed properties, to FALSE otherwise. - * - 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 - * 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 - * required settings. - * - constraints: An array of validation constraints. See - * \Drupal\Core\TypedData\TypedDataManager::getConstraints() for details. - * - required: A boolean specifying whether a non-NULL value is mandatory. - * Further keys may be supported in certain usages, e.g. for further keys - * supported for entity field definitions see - * \Drupal\Core\Entity\StorageControllerInterface::getPropertyDefinitions(). + * @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. @@ -147,14 +118,20 @@ public function createInstance($plugin_id, array $configuration, $name = NULL, $ * @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->createInstance($definition['type'], $definition, $name, $parent); + public function create($definition, $value = NULL, $name = NULL, $parent = NULL) { + if (is_array($definition)) { + $definition = DataDefinition::createFromOldStyleDefinition($definition); + } + $typed_data = $this->createInstance($definition->getDataType(), array( + 'data_definition' => $definition, + 'name' => $name, + 'parent' => $parent, + )); if (isset($value)) { - $wrapper->setValue($value, FALSE); + $typed_data->setValue($value, FALSE); } - return $wrapper; + return $typed_data; } /** @@ -336,7 +313,7 @@ public function getValidationConstraintManager() { * * @see \Drupal\Core\Validation\ConstraintManager * - * @param array $definition + * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition * A data definition array. * * @return array diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php index ba827e6..647188d 100644 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php +++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php @@ -19,6 +19,9 @@ class ValidReferenceConstraintValidator extends ConstraintValidator { * {@inheritdoc} */ public function validate($value, Constraint $constraint) { + if (!isset($value)) { + return; + } $id = $value->get('target_id')->getValue(); // '0' or NULL are considered valid empty references. if (empty($id)) { diff --git a/core/modules/datetime/lib/Drupal/datetime/DateTimeComputed.php b/core/modules/datetime/lib/Drupal/datetime/DateTimeComputed.php index c0f6123..d6954b9 100644 --- a/core/modules/datetime/lib/Drupal/datetime/DateTimeComputed.php +++ b/core/modules/datetime/lib/Drupal/datetime/DateTimeComputed.php @@ -29,7 +29,7 @@ class DateTimeComputed extends TypedData { /** * {@inheritdoc} */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent); if (!isset($definition['settings']['date source'])) { throw new \InvalidArgumentException("The definition's 'date source' key has to specify the name of the date property to be computed."); diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php index 463f5cb..b09c9bc 100644 --- a/core/modules/field/lib/Drupal/field/Entity/Field.php +++ b/core/modules/field/lib/Drupal/field/Entity/Field.php @@ -649,6 +649,20 @@ public function hasData() { } /** + * {@inheritdoc} + */ + public function isFieldQueryable() { + return TRUE; + } + + /** + * {@inheritdoc} + */ + public function isFieldConfigurable() { + return TRUE; + } + + /** * Implements the magic __sleep() method. * * Using the Serialize interface and serialize() / unserialize() methods @@ -669,11 +683,4 @@ public function __wakeup() { $this->__construct($values); } - /** - * {@inheritdoc} - */ - public function isFieldConfigurable() { - return TRUE; - } - } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php index d038977..def3c42 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php @@ -614,7 +614,14 @@ public function isFieldConfigurable() { return TRUE; } - /* + /** + * {@inheritdoc} + */ + public function isFieldQueryable() { + return TRUE; + } + + /** * Implements the magic __sleep() method. * * Using the Serialize interface and serialize() / unserialize() methods diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php index 32bea80..90555cf 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigFieldItemList.php @@ -7,6 +7,7 @@ namespace Drupal\field\Plugin\Type\FieldType; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\Entity\Field\FieldItemList; use Drupal\field\Field as FieldAPI; @@ -26,7 +27,7 @@ class ConfigFieldItemList extends FieldItemList implements ConfigFieldItemListIn /** * {@inheritdoc} */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent); if (isset($definition['instance'])) { $this->instance = $definition['instance']; @@ -69,13 +70,6 @@ public function getConstraints() { /** * {@inheritdoc} */ - protected function getDefaultValue() { - return $this->getFieldDefinition()->getFieldDefaultValue($this->getEntity()); - } - - /** - * {@inheritdoc} - */ public function defaultValuesForm(array &$form, array &$form_state) { if (empty($this->getFieldDefinition()->default_value_function)) { // Place the input in a separate place in the submitted values tree. diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItemList.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItemList.php index 22cd8a0..5d20b0c 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItemList.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItemList.php @@ -102,8 +102,8 @@ public function deleteRevision() { * The name of the hook, e.g. 'presave', 'validate'. */ protected function legacyCallback($hook, $args = array()) { - $definition = $this->getPluginDefinition(); - $module = $definition['provider']; + $type_definition = \Drupal::typedData()->getDefinition($this->getItemDefinition()->getDataType()); + $module = $type_definition['provider']; $callback = "{$module}_field_{$hook}"; if (function_exists($callback)) { // We need to remove the empty "prototype" item here. diff --git a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php index 5d6b200..4abf5d3 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php @@ -11,6 +11,7 @@ use Drupal\Core\TypedData\ContextAwareInterface; use Drupal\Core\Config\Schema\Element; use Drupal\Core\Config\Schema\ArrayElement; +use Drupal\Core\TypedData\DataDefinitionInterface; /** * Defines the locale configuration wrapper object. @@ -41,7 +42,7 @@ class LocaleTypedConfig extends Element { /** * Constructs a configuration wrapper object. * - * @param array $definition + * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition * The data definition. * @param string $name * The configuration object name. @@ -50,7 +51,7 @@ class LocaleTypedConfig extends Element { * @param \Drupal\locale\LocaleConfigManager $localeConfig; * The locale configuration manager object. */ - public function __construct(array $definition, $name, $langcode, \Drupal\locale\LocaleConfigManager $localeConfig) { + public function __construct($definition, $name, $langcode, \Drupal\locale\LocaleConfigManager $localeConfig) { parent::__construct($definition, $name); $this->langcode = $langcode; $this->localeConfig = $localeConfig; diff --git a/core/modules/serialization/tests/Drupal/serialization/Tests/Normalizer/ListNormalizerTest.php b/core/modules/serialization/tests/Drupal/serialization/Tests/Normalizer/ListNormalizerTest.php index 399d8c1..8704c7f 100644 --- a/core/modules/serialization/tests/Drupal/serialization/Tests/Normalizer/ListNormalizerTest.php +++ b/core/modules/serialization/tests/Drupal/serialization/Tests/Normalizer/ListNormalizerTest.php @@ -9,8 +9,7 @@ use Drupal\Tests\UnitTestCase; use Drupal\serialization\Normalizer\ListNormalizer; -use Drupal\Core\TypedData\ItemList; -use Drupal\Core\TypedData\Plugin\DataType\Integer; +use Drupal\Core\TypedData\Plugin\DataType\ItemList; /** * Tests the ListNormalizer class. diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php index bbf0fd0..eee8cc8 100644 --- a/core/modules/text/lib/Drupal/text/TextProcessed.php +++ b/core/modules/text/lib/Drupal/text/TextProcessed.php @@ -7,6 +7,7 @@ namespace Drupal\text; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedData; use Drupal\Core\TypedData\ReadOnlyException; @@ -29,7 +30,7 @@ class TextProcessed extends TypedData { /** * Overrides TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent); if (!isset($definition['settings']['text source'])) {