Commit e8c263c4 authored by catch's avatar catch

Issue #2112239 by amateescu: Convert base field and property definitions.

parent 31c48739
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
use Drupal\Core\Entity\Plugin\DataType\EntityReference; use Drupal\Core\Entity\Plugin\DataType\EntityReference;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
/** /**
...@@ -227,7 +228,7 @@ public function getDefinition() { ...@@ -227,7 +228,7 @@ public function getDefinition() {
else { else {
$type = 'entity:' . $this->entityType(); $type = 'entity:' . $this->entityType();
} }
return array('type' => $type); return DataDefinition::create($type);
} }
/** /**
......
...@@ -338,15 +338,8 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) { ...@@ -338,15 +338,8 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) {
// See https://drupal.org/node/2114707. // See https://drupal.org/node/2114707.
$class = $this->factory->getPluginClass($entity_type, $this->getDefinition($entity_type)); $class = $this->factory->getPluginClass($entity_type, $this->getDefinition($entity_type));
$base_definitions = $class::baseFieldDefinitions($entity_type);
foreach ($base_definitions as &$base_definition) {
// Support old-style field types to avoid that all base field
// definitions need to be changed.
// @todo: Remove after https://drupal.org/node/2047229.
$base_definition['type'] = preg_replace('/(.+)_field/', 'field_item:$1', $base_definition['type']);
}
$this->entityFieldInfo[$entity_type] = array( $this->entityFieldInfo[$entity_type] = array(
'definitions' => $base_definitions, 'definitions' => $class::baseFieldDefinitions($entity_type),
// Contains definitions of optional (per-bundle) fields. // Contains definitions of optional (per-bundle) fields.
'optional' => array(), 'optional' => array(),
// An array keyed by bundle name containing the optional fields added // An array keyed by bundle name containing the optional fields added
...@@ -360,13 +353,9 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) { ...@@ -360,13 +353,9 @@ public function getFieldDefinitions($entity_type, $bundle = NULL) {
$result = $this->moduleHandler->invokeAll('entity_field_info', array($entity_type)); $result = $this->moduleHandler->invokeAll('entity_field_info', array($entity_type));
$this->entityFieldInfo[$entity_type] = NestedArray::mergeDeep($this->entityFieldInfo[$entity_type], $result); $this->entityFieldInfo[$entity_type] = NestedArray::mergeDeep($this->entityFieldInfo[$entity_type], $result);
// Enforce field definitions to be objects. // Automatically set the field name for non-configurable fields.
foreach (array('definitions', 'optional') as $key) { foreach (array('definitions', 'optional') as $key) {
foreach ($this->entityFieldInfo[$entity_type][$key] as $field_name => &$definition) { foreach ($this->entityFieldInfo[$entity_type][$key] as $field_name => &$definition) {
if (is_array($definition)) {
$definition = FieldDefinition::createFromOldStyleDefinition($definition);
}
// Automatically set the field name for non-configurable fields.
if ($definition instanceof FieldDefinition) { if ($definition instanceof FieldDefinition) {
$definition->setFieldName($field_name); $definition->setFieldName($field_name);
} }
......
...@@ -64,7 +64,7 @@ public function getTarget() { ...@@ -64,7 +64,7 @@ public function getTarget() {
if (!isset($this->target) && isset($this->id)) { if (!isset($this->target) && isset($this->id)) {
// If we have a valid reference, return the entity object which is typed // If we have a valid reference, return the entity object which is typed
// data itself. // data itself.
$this->target = entity_load($this->definition['constraints']['EntityType'], $this->id); $this->target = entity_load($this->definition->getConstraint('EntityType'), $this->id);
} }
return $this->target; return $this->target;
} }
...@@ -101,7 +101,7 @@ public function setValue($value, $notify = TRUE) { ...@@ -101,7 +101,7 @@ public function setValue($value, $notify = TRUE) {
if (!isset($value) || $value instanceof EntityInterface) { if (!isset($value) || $value instanceof EntityInterface) {
$this->target = $value; $this->target = $value;
} }
elseif (!is_scalar($value) || empty($this->definition['constraints']['EntityType'])) { elseif (!is_scalar($value) || (($constraints = $this->definition->getConstraints()) && empty($constraints['EntityType']))) {
throw new \InvalidArgumentException('Value is not a valid entity.'); throw new \InvalidArgumentException('Value is not a valid entity.');
} }
else { else {
......
...@@ -7,9 +7,8 @@ ...@@ -7,9 +7,8 @@
namespace Drupal\Core\Entity\Plugin\DataType; namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\DataReferenceBase; use Drupal\Core\TypedData\DataReferenceBase;
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
/** /**
* Defines the 'language_reference' data type. * Defines the 'language_reference' data type.
...@@ -32,9 +31,7 @@ class LanguageReference extends DataReferenceBase { ...@@ -32,9 +31,7 @@ class LanguageReference extends DataReferenceBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getTargetDefinition() { public function getTargetDefinition() {
return array( return DataDefinition::create('language');
'type' => 'language',
);
} }
/** /**
......
...@@ -29,8 +29,7 @@ public function validate($value, Constraint $constraint) { ...@@ -29,8 +29,7 @@ public function validate($value, Constraint $constraint) {
} }
$referenced_entity = $value->get('entity')->getTarget(); $referenced_entity = $value->get('entity')->getTarget();
if (!$referenced_entity) { if (!$referenced_entity) {
$definition = $value->getDefinition(); $type = $value->getDefinition()->getSetting('target_type');
$type = $definition['settings']['target_type'];
$this->context->addViolation($constraint->message, array('%type' => $type, '%id' => $id)); $this->context->addViolation($constraint->message, array('%type' => $type, '%id' => $id));
} }
} }
......
...@@ -204,7 +204,7 @@ public function addField($field, $type, $langcode) { ...@@ -204,7 +204,7 @@ public function addField($field, $type, $langcode) {
// Check for a valid relationship. // Check for a valid relationship.
if (isset($propertyDefinitions[$relationship_specifier]) && $entity->{$specifier}->get('entity') instanceof EntityReference) { if (isset($propertyDefinitions[$relationship_specifier]) && $entity->{$specifier}->get('entity') instanceof EntityReference) {
// If it is, use the entity type. // If it is, use the entity type.
$entity_type = $propertyDefinitions[$relationship_specifier]['constraints']['EntityType']; $entity_type = $propertyDefinitions[$relationship_specifier]->getConstraint('EntityType');
$entity_info = $entity_manager->getDefinition($entity_type); $entity_info = $entity_manager->getDefinition($entity_type);
// Add the new entity base table using the table and sql column. // Add the new entity base table using the table and sql column.
$join_condition= '%alias.' . $entity_info['entity_keys']['id'] . " = $table.$sql_column"; $join_condition= '%alias.' . $entity_info['entity_keys']['id'] . " = $table.$sql_column";
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field; namespace Drupal\Core\Field;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\field\FieldInstanceInterface; use Drupal\field\FieldInstanceInterface;
use Drupal\field\FieldInterface; use Drupal\field\FieldInterface;
...@@ -35,11 +36,12 @@ class ConfigEntityReferenceItemBase extends EntityReferenceItem implements Confi ...@@ -35,11 +36,12 @@ class ConfigEntityReferenceItemBase extends EntityReferenceItem implements Confi
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getPropertyDefinitions() { public function getPropertyDefinitions() {
$target_type = $this->definition['settings']['target_type']; $settings = $this->definition->getSettings();
$target_type = $settings['target_type'];
// Definitions vary by entity type and bundle, so key them accordingly. // Definitions vary by entity type and bundle, so key them accordingly.
$key = $target_type . ':'; $key = $target_type . ':';
$key .= isset($this->definition['settings']['target_bundle']) ? $this->definition['settings']['target_bundle'] : ''; $key .= isset($settings['target_bundle']) ? $settings['target_bundle'] : '';
if (!isset(static::$propertyDefinitions[$key])) { if (!isset(static::$propertyDefinitions[$key])) {
// Call the parent to define the target_id and entity properties. // Call the parent to define the target_id and entity properties.
...@@ -49,25 +51,18 @@ public function getPropertyDefinitions() { ...@@ -49,25 +51,18 @@ public function getPropertyDefinitions() {
// revisions. // revisions.
$target_type_info = \Drupal::entityManager()->getDefinition($target_type); $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
if (!empty($target_type_info['entity_keys']['revision']) && !empty($target_type_info['revision_table'])) { if (!empty($target_type_info['entity_keys']['revision']) && !empty($target_type_info['revision_table'])) {
static::$propertyDefinitions[$key]['revision_id'] = array( static::$propertyDefinitions[$key]['revision_id'] = DataDefinition::create('integer')
'type' => 'integer', ->setLabel(t('Revision ID'))
'label' => t('Revision ID'), ->setConstraints(array('Range' => array('min' => 0)));
'constraints' => array(
'Range' => array('min' => 0),
),
);
} }
static::$propertyDefinitions[$key]['label'] = array( static::$propertyDefinitions[$key]['label'] = DataDefinition::create('string')
'type' => 'string', ->setLabel(t('Label (auto-create)'))
'label' => t('Label (auto-create)'), ->setComputed(TRUE);
'computed' => TRUE,
); static::$propertyDefinitions[$key]['access'] = DataDefinition::create('boolean')
static::$propertyDefinitions[$key]['access'] = array( ->setLabel(t('Access'))
'type' => 'boolean', ->setComputed(TRUE);
'label' => t('Access'),
'computed' => TRUE,
);
} }
return static::$propertyDefinitions[$key]; return static::$propertyDefinitions[$key];
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
/** /**
* A class for defining entity fields. * A class for defining entity fields.
*/ */
class FieldDefinition extends ListDefinition implements FieldDefinitionInterface, \ArrayAccess { class FieldDefinition extends ListDefinition implements FieldDefinitionInterface {
/** /**
* Creates a new field definition. * Creates a new field definition.
...@@ -22,7 +22,7 @@ class FieldDefinition extends ListDefinition implements FieldDefinitionInterface ...@@ -22,7 +22,7 @@ class FieldDefinition extends ListDefinition implements FieldDefinitionInterface
* @param string $type * @param string $type
* The type of the field. * The type of the field.
* *
* @return \Drupal\Core\Field\FieldDefinition * @return static
* A new field definition object. * A new field definition object.
*/ */
public static function create($type) { public static function create($type) {
...@@ -42,7 +42,7 @@ public function getFieldName() { ...@@ -42,7 +42,7 @@ public function getFieldName() {
* @param string $name * @param string $name
* The field name to set. * The field name to set.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setFieldName($name) { public function setFieldName($name) {
...@@ -73,7 +73,7 @@ public function getFieldSettings() { ...@@ -73,7 +73,7 @@ public function getFieldSettings() {
* @param array $settings * @param array $settings
* The value to set. * The value to set.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setFieldSettings(array $settings) { public function setFieldSettings(array $settings) {
...@@ -85,8 +85,7 @@ public function setFieldSettings(array $settings) { ...@@ -85,8 +85,7 @@ public function setFieldSettings(array $settings) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getFieldSetting($setting_name) { public function getFieldSetting($setting_name) {
$settings = $this->getFieldSettings(); return $this->getItemDefinition()->getSetting($setting_name);
return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
} }
/** /**
...@@ -97,13 +96,12 @@ public function getFieldSetting($setting_name) { ...@@ -97,13 +96,12 @@ public function getFieldSetting($setting_name) {
* @param mixed $value * @param mixed $value
* The value to set. * The value to set.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setFieldSetting($setting_name, $value) { public function setFieldSetting($setting_name, $value) {
$settings = $this->getFieldSettings(); $this->getItemDefinition()->setSetting($setting_name, $value);
$settings[$setting_name] = $value; return $this;
return $this->setFieldSettings($settings);
} }
/** /**
...@@ -126,7 +124,7 @@ public function isFieldTranslatable() { ...@@ -126,7 +124,7 @@ public function isFieldTranslatable() {
* @param bool $translatable * @param bool $translatable
* Whether the field is translatable. * Whether the field is translatable.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setTranslatable($translatable) { public function setTranslatable($translatable) {
...@@ -191,7 +189,7 @@ public function isFieldMultiple() { ...@@ -191,7 +189,7 @@ public function isFieldMultiple() {
* @param bool $required * @param bool $required
* Whether the field is required. * Whether the field is required.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setFieldRequired($required) { public function setFieldRequired($required) {
...@@ -211,7 +209,7 @@ public function isFieldQueryable() { ...@@ -211,7 +209,7 @@ public function isFieldQueryable() {
* @param bool $queryable * @param bool $queryable
* Whether the field is queryable. * Whether the field is queryable.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setFieldQueryable($queryable) { public function setFieldQueryable($queryable) {
...@@ -227,7 +225,7 @@ public function setFieldQueryable($queryable) { ...@@ -227,7 +225,7 @@ public function setFieldQueryable($queryable) {
* @param array $constraints * @param array $constraints
* The constraints to set. * The constraints to set.
* *
* @return self * @return static
* The object itself for chaining. * The object itself for chaining.
*/ */
public function setPropertyConstraints($name, array $constraints) { public function setPropertyConstraints($name, array $constraints) {
...@@ -251,77 +249,4 @@ public function getFieldDefaultValue(EntityInterface $entity) { ...@@ -251,77 +249,4 @@ public function getFieldDefaultValue(EntityInterface $entity) {
return $this->getFieldSetting('default_value'); return $this->getFieldSetting('default_value');
} }
/**
* Allows creating field definition objects from old style definition arrays.
*
* @todo: Remove once https://drupal.org/node/2112239 is in.
*/
public static function createFromOldStyleDefinition(array $definition) {
unset($definition['list']);
// Separate the list item definition from the list definition.
$list_definition = $definition;
unset($list_definition['type']);
// Constraints, class and settings apply to the list item.
unset($list_definition['constraints']);
unset($list_definition['class']);
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']);
}
}
if (isset($definition['translatable'])) {
$field_definition->setTranslatable($definition['translatable']);
unset($definition['translatable']);
}
// Take care of the item definition now.
// Required applies to the field definition only.
unset($definition['required']);
$item_definition = new DataDefinition($definition);
$field_definition->setItemDefinition($item_definition);
return $field_definition;
}
/**
* {@inheritdoc}
*
* This is for BC support only.
* @todo: Remove once https://drupal.org/node/2112239 is in.
*/
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}
*
* This is for BC support only.
* @todo: Remove once https://drupal.org/node/2112239 is in.
*/
public function offsetSet($offset, $value) {
if ($offset == 'type') {
// What previously was "type" is now the type of the list item.
$this->itemDefinition->setDataType($value);
}
else {
$this->definition[$offset] = $value;
}
}
} }
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field; namespace Drupal\Core\Field;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\Plugin\DataType\Map; use Drupal\Core\TypedData\Plugin\DataType\Map;
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\user; use Drupal\user;
...@@ -23,14 +24,14 @@ ...@@ -23,14 +24,14 @@
abstract class FieldItemBase extends Map implements FieldItemInterface { abstract class FieldItemBase extends Map implements FieldItemInterface {
/** /**
* Overrides \Drupal\Core\TypedData\TypedData::__construct(). * {@inheritdoc}
*/ */
public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
parent::__construct($definition, $name, $parent); parent::__construct($definition, $name, $parent);
// Initialize computed properties by default, such that they get cloned // Initialize computed properties by default, such that they get cloned
// with the whole item. // with the whole item.
foreach ($this->getPropertyDefinitions() as $name => $definition) { foreach ($this->getPropertyDefinitions() as $name => $definition) {
if (!empty($definition['computed'])) { if ($definition->isComputed()) {
$this->properties[$name] = \Drupal::typedData()->getPropertyInstance($this, $name); $this->properties[$name] = \Drupal::typedData()->getPropertyInstance($this, $name);
} }
} }
...@@ -185,20 +186,6 @@ public function onChange($property_name) { ...@@ -185,20 +186,6 @@ public function onChange($property_name) {
} }
} }
/**
* {@inheritdoc}
*/
public function getConstraints() {
$constraints = parent::getConstraints();
// If property constraints are present add in a ComplexData constraint for
// applying them.
if (!empty($this->definition['property_constraints'])) {
$constraints[] = \Drupal::typedData()->getValidationConstraintManager()
->create('ComplexData', $this->definition['property_constraints']);
}
return $constraints;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field; namespace Drupal\Core\Field;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\TypedData\Plugin\DataType\ItemList; use Drupal\Core\TypedData\Plugin\DataType\ItemList;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
...@@ -40,7 +41,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface { ...@@ -40,7 +41,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
parent::__construct($definition, $name, $parent); parent::__construct($definition, $name, $parent);
// Always initialize one empty item as most times a value for at least one // Always initialize one empty item as most times a value for at least one
// item will be present. That way prototypes created by // item will be present. That way prototypes created by
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field\Plugin\Field\FieldType; namespace Drupal\Core\Field\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\TypedData\DataDefinition;
/** /**
* Defines the 'boolean' entity field type. * Defines the 'boolean' entity field type.
...@@ -34,13 +35,11 @@ class BooleanItem extends FieldItemBase { ...@@ -34,13 +35,11 @@ class BooleanItem extends FieldItemBase {
* Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions(). * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
*/ */
public function getPropertyDefinitions() { public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) { if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array( static::$propertyDefinitions['value'] = DataDefinition::create('boolean')
'type' => 'boolean', ->setLabel(t('Boolean value'));
'label' => t('Boolean value'),
);
} }
return static::$propertyDefinitions; return static::$propertyDefinitions;
} }
} }
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field\Plugin\Field\FieldType; namespace Drupal\Core\Field\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\TypedData\DataDefinition;
/** /**
* Defines the 'email' entity field type. * Defines the 'email' entity field type.
...@@ -36,10 +37,8 @@ class EmailItem extends FieldItemBase { ...@@ -36,10 +37,8 @@ class EmailItem extends FieldItemBase {
public function getPropertyDefinitions() { public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) { if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array( static::$propertyDefinitions['value'] = DataDefinition::create('email')
'type' => 'email', ->setLabel(t('E-mail value'));
'label' => t('E-mail value'),
);
} }
return static::$propertyDefinitions; return static::$propertyDefinitions;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\Core\Field\Plugin\Field\FieldType; namespace Drupal\Core\Field\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\TypedData\DataDefinition;
/** /**
* Defines the 'entity_reference' entity field type. * Defines the 'entity_reference' entity field type.
...@@ -41,45 +42,41 @@ class EntityReferenceItem extends FieldItemBase { ...@@ -41,45 +42,41 @@ class EntityReferenceItem extends FieldItemBase {
* Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions(). * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
*/ */
public function getPropertyDefinitions() {