From 4831e2ee7c9185a6f00b418ea4d88f8cf32f80b0 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 16 Jun 2014 00:19:55 +0100 Subject: [PATCH] Issue #2226267 by fago, xjm, Berdir: Improve default value handling of fields to be consistent. --- .../lib/Drupal/Core/Field/FieldDefinition.php | 54 ++++++++++++- .../Core/Field/FieldDefinitionInterface.php | 12 +-- core/lib/Drupal/Core/Field/FieldItemList.php | 20 +++-- .../Core/Field/FieldItemListInterface.php | 27 +++++++ .../Plugin/Field/FieldType/StringItem.php | 2 +- core/modules/aggregator/src/Entity/Feed.php | 4 +- core/modules/comment/src/Entity/Comment.php | 14 ++-- .../Field/FieldType/DateTimeFieldItemList.php | 8 +- ...nfigurableEntityReferenceFieldItemList.php | 8 +- .../field/src/Entity/FieldInstanceConfig.php | 27 +++---- .../src/Tests/FieldAttachStorageTest.php | 2 +- .../modules/field_test/field_test.field.inc | 4 +- core/modules/node/src/Entity/Node.php | 8 +- .../src/Tests/EntitySerializationTest.php | 1 - core/modules/shortcut/src/Entity/Shortcut.php | 2 +- .../Entity/EntityFieldDefaultValueTest.php | 11 +++ .../modules/entity_test/entity_test.module | 27 ++++--- .../src/Entity/EntityTestDefaultValue.php | 43 ++++++++++ core/modules/taxonomy/src/Entity/Term.php | 4 +- .../TaxonomyTermReferenceFieldItemList.php | 81 ++++++++++--------- core/modules/user/src/Entity/User.php | 12 +-- .../Tests/Core/Entity/FieldDefinitionTest.php | 8 +- 22 files changed, 254 insertions(+), 125 deletions(-) create mode 100644 core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php index c6a661e4e452..006ceb008a28 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinition.php +++ b/core/lib/Drupal/Core/Field/FieldDefinition.php @@ -7,7 +7,7 @@ namespace Drupal\Core\Field; -use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\TypedData\FieldItemDataDefinition; use Drupal\Core\TypedData\ListDataDefinition; use Drupal\field\FieldException; @@ -378,8 +378,56 @@ public function isDisplayConfigurable($display_context) { /** * {@inheritdoc} */ - public function getDefaultValue(EntityInterface $entity) { - return $this->getSetting('default_value'); + public function getDefaultValue(ContentEntityInterface $entity) { + // Allow custom default values function. + if (isset($this->definition['default_value_callback'])) { + $value = call_user_func($this->definition['default_value_callback'], $entity, $this); + } + else { + $value = isset($this->definition['default_value']) ? $this->definition['default_value'] : NULL; + } + // Allow the field type to process default values. + $field_item_list_class = $this->getClass(); + return $field_item_list_class::processDefaultValue($value, $entity, $this); + } + + /** + * Sets a custom default value callback. + * + * If set, the callback overrides any set default value. + * + * @param string|array $callback + * The callback to invoke for getting the default value. The callback will + * be invoked with the following arguments: + * - \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity being created. + * - \Drupal\Core\Field\FieldDefinitionInterface $definition + * The field definition. + * It should return the default value as documented by + * \Drupal\Core\Field\FieldDefinitionInterface::getDefaultValue(). + * + * @return $this + */ + public function setDefaultValueCallback($callback) { + $this->definition['default_value_callback'] = $callback; + return $this; + } + + /** + * Sets a default value. + * + * Note that if a default value callback is set, it will take precedence over + * any value set here. + * + * @param mixed $value + * The default value in the format as returned by + * \Drupal\Core\Field\FieldDefinitionInterface::getDefaultValue(). + * + * @return $this + */ + public function setDefaultValue($value) { + $this->definition['default_value'] = $value; + return $this; } /** diff --git a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php index a6c91907ccac..20838192027b 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php +++ b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php @@ -7,7 +7,7 @@ namespace Drupal\Core\Field; -use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\TypedData\ListDataDefinitionInterface; /** @@ -114,19 +114,19 @@ public function isRequired(); /** * Returns the default value for the field in a newly created entity. * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity being created. + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity for which the default value is generated. * * @return mixed * The default value for the field, as accepted by - * Drupal\field\Plugin\Core\Entity\FieldConfig::setValue(). This can be - * either: + * \Drupal\field\Plugin\Core\Entity\FieldItemListInterface::setValue(). This + * can be either: * - a literal, in which case it will be assigned to the first property of * the first item. * - a numerically indexed array of items, each item being a property/value * array. * - NULL or array() for no default value. */ - public function getDefaultValue(EntityInterface $entity); + public function getDefaultValue(ContentEntityInterface $entity); } diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php index 2e0b442b9b18..c715902e1452 100644 --- a/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Field; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; @@ -202,7 +203,7 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N * {@inheritdoc} */ public function applyDefaultValue($notify = TRUE) { - $value = $this->getDefaultValue(); + $value = $this->getFieldDefinition()->getDefaultValue($this->getEntity()); // NULL or array() mean "no default value", but 0, '0' and the empty string // are valid default values. @@ -216,16 +217,6 @@ public function applyDefaultValue($notify = TRUE) { return $this; } - /** - * Returns the default value for the field. - * - * @return array - * The default value for the field. - */ - protected function getDefaultValue() { - return $this->getFieldDefinition()->getDefaultValue($this->getEntity()); - } - /** * {@inheritdoc} */ @@ -347,6 +338,13 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo return $this->getValue(); } + /** + * {@inheritdoc} + */ + public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) { + return $default_value; + } + /** * Returns the widget object used in default value form. * diff --git a/core/lib/Drupal/Core/Field/FieldItemListInterface.php b/core/lib/Drupal/Core/Field/FieldItemListInterface.php index 651f1e472419..0a1583b85aaf 100644 --- a/core/lib/Drupal/Core/Field/FieldItemListInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemListInterface.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Field; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Access\AccessibleInterface; use Drupal\Core\TypedData\ListInterface; @@ -228,4 +229,30 @@ public function defaultValuesFormValidate(array $element, array &$form, array &$ */ public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state); + /** + * Processes the default value before being applied. + * + * Defined or configured default values of a field might need some processing + * in order to be a valid value for the field type; e.g., a date field could + * process the defined value of 'NOW' to a valid date. + * + * @param mixed + * The default value as defined for the field. + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity for which the default value is generated. + * @param \Drupal\Core\Field\FieldDefinitionInterface $definition + * The definition of the field. + * + * @return mixed + * The default value for the field, as accepted by + * \Drupal\field\Plugin\Core\Entity\FieldItemListInterface::setValue(). This + * can be either: + * - a literal, in which case it will be assigned to the first property of + * the first item. + * - a numerically indexed array of items, each item being a property/value + * array. + * - NULL or array() for no default value. + */ + public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition); + } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php index fe7c4f47d104..ba72dc38012e 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Core\Entity\Plugin\Field\FieldType\StringItem. + * Contains \Drupal\Core\Field\Plugin\Field\FieldType\StringItem. */ namespace Drupal\Core\Field\Plugin\Field\FieldType; diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php index 4222152ba2be..8c091c3caade 100644 --- a/core/modules/aggregator/src/Entity/Feed.php +++ b/core/modules/aggregator/src/Entity/Feed.php @@ -176,12 +176,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['checked'] = FieldDefinition::create('timestamp') ->setLabel(t('Checked')) ->setDescription(t('Last time feed was checked for new items, as Unix timestamp.')) - ->setSetting('default_value', 0); + ->setDefaultValue(0); $fields['queued'] = FieldDefinition::create('timestamp') ->setLabel(t('Queued')) ->setDescription(t('Time when this feed was queued for refresh, 0 if not queued.')) - ->setSetting('default_value', 0); + ->setDefaultValue(0); $fields['link'] = FieldDefinition::create('uri') ->setLabel(t('Link')) diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index d7c7d11c4e1a..1164756f0c1f 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -233,18 +233,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['uid'] = FieldDefinition::create('entity_reference') ->setLabel(t('User ID')) ->setDescription(t('The user ID of the comment author.')) - ->setSettings(array( - 'target_type' => 'user', - 'default_value' => 0, - )); + ->setSetting('target_type', 'user') + ->setDefaultValue(0); $fields['name'] = FieldDefinition::create('string') ->setLabel(t('Name')) ->setDescription(t("The comment author's name.")) - ->setSettings(array( - 'default_value' => '', - 'max_length' => 60, - )) + ->setSetting('max_length', 60) + ->setDefaultValue('') ->addConstraint('CommentName', array()); $fields['mail'] = FieldDefinition::create('email') @@ -274,7 +270,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['status'] = FieldDefinition::create('boolean') ->setLabel(t('Publishing status')) ->setDescription(t('A boolean indicating whether the comment is published.')) - ->setSetting('default_value', TRUE); + ->setDefaultValue(TRUE); $fields['thread'] = FieldDefinition::create('string') ->setLabel(t('Thread place')) diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php index 81fa6df7a545..75a59ec4eb96 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php @@ -8,6 +8,8 @@ namespace Drupal\datetime\Plugin\Field\FieldType; use Drupal\Core\Datetime\DrupalDateTime; +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemList; /** @@ -61,14 +63,14 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo /** * {@inheritdoc} */ - public function getDefaultValue() { - $default_value = parent::getDefaultValue(); + public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) { + $default_value = parent::processDefaultValue($default_value, $entity, $definition); if (isset($default_value[0]['default_date']) && $default_value[0]['default_date'] == static::DEFAULT_VALUE_NOW) { // A default value should be in the format and timezone used for date // storage. $date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE); - $storage_format = $this->getFieldDefinition()->getSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT; + $storage_format = $definition->getSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT; $value = $date->format($storage_format); // We only provide a default value for the first item, as do all fields. // Otherwise, there is no way to clear out unwanted values on multiple value diff --git a/core/modules/entity_reference/src/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php b/core/modules/entity_reference/src/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php index bf9e38b424ec..3d4bec31aafb 100644 --- a/core/modules/entity_reference/src/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php +++ b/core/modules/entity_reference/src/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php @@ -8,6 +8,8 @@ namespace Drupal\entity_reference\Plugin\Field\FieldType; use Drupal\Core\Field\EntityReferenceFieldItemList; +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; /** * Represents a configurable entity_reference entity field. @@ -17,8 +19,8 @@ class ConfigurableEntityReferenceFieldItemList extends EntityReferenceFieldItemL /** * {@inheritdoc} */ - protected function getDefaultValue() { - $default_value = parent::getDefaultValue(); + public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) { + $default_value = parent::processDefaultValue($default_value, $entity, $definition); if ($default_value) { // Convert UUIDs to numeric IDs. @@ -33,7 +35,7 @@ protected function getDefaultValue() { } } if ($uuids) { - $target_type = $this->getSetting('target_type'); + $target_type = $definition->getSetting('target_type'); $entity_ids = \Drupal::entityQuery($target_type) ->condition('uuid', $uuids, 'IN') ->execute(); diff --git a/core/modules/field/src/Entity/FieldInstanceConfig.php b/core/modules/field/src/Entity/FieldInstanceConfig.php index 11ab930f7956..77d1cf3d8b63 100644 --- a/core/modules/field/src/Entity/FieldInstanceConfig.php +++ b/core/modules/field/src/Entity/FieldInstanceConfig.php @@ -9,7 +9,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinition; use Drupal\Core\Field\TypedData\FieldItemDataDefinition; @@ -154,14 +154,10 @@ class FieldInstanceConfig extends ConfigEntityBase implements FieldInstanceConfi * The name of a callback function that returns default values. * * The function will be called with the following arguments: - * - \Drupal\Core\Entity\EntityInterface $entity + * - \Drupal\Core\Entity\ContentEntityInterface $entity * The entity being created. - * - \Drupal\field\Entity\FieldConfig $field - * The field object. - * - \Drupal\field\Entity\FieldInstanceConfig $instance - * The field instance object. - * - string $langcode - * The language of the entity being created. + * - \Drupal\Core\Field\FieldDefinitionInterface $definition + * The field definition. * It should return an array of default values, in the same format as the * $default_value property. * @@ -588,14 +584,17 @@ public function isMultiple() { /** * {@inheritdoc} */ - public function getDefaultValue(EntityInterface $entity) { - if (!empty($this->default_value_function)) { - $function = $this->default_value_function; - return $function($entity, $this->getField(), $this, $entity->language()->id); + public function getDefaultValue(ContentEntityInterface $entity) { + // Allow custom default values function. + if ($function = $this->default_value_function) { + $value = call_user_func($function, $entity, $this); } - elseif (!empty($this->default_value)) { - return $this->default_value; + else { + $value = $this->default_value; } + // Allow the field type to process default values. + $field_item_list_class = $this->getClass(); + return $field_item_list_class::processDefaultValue($value, $entity, $this); } /** diff --git a/core/modules/field/src/Tests/FieldAttachStorageTest.php b/core/modules/field/src/Tests/FieldAttachStorageTest.php index 492496c1eb78..9ec1d7cb42b8 100644 --- a/core/modules/field/src/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/src/Tests/FieldAttachStorageTest.php @@ -220,7 +220,7 @@ function testFieldAttachSaveEmptyDataDefaultValue() { // Verify that fields are populated with default values. $entity_init = entity_create($entity_type, array('id' => 1, 'revision_id' => 1)); - $default = field_test_default_value($entity_init, $this->field, $this->instance); + $default = field_test_default_value($entity_init, $this->instance); $this->assertEqual($entity_init->{$this->field_name}->getValue(), $default, 'Default field value correctly populated.'); // Insert: Field is NULL. diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc index 79b57a3c0215..e43a7e79b572 100644 --- a/core/modules/field/tests/modules/field_test/field_test.field.inc +++ b/core/modules/field/tests/modules/field_test/field_test.field.inc @@ -5,7 +5,7 @@ * Defines a field type and its formatters and widgets. */ -use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Session\AccountInterface; @@ -31,7 +31,7 @@ function field_test_field_config_update_forbid(FieldConfigInterface $field, Fiel /** * Sample 'default value' callback. */ -function field_test_default_value(EntityInterface $entity, $field, $instance) { +function field_test_default_value(ContentEntityInterface $entity, FieldDefinitionInterface $definition) { return array(array('value' => 99)); } diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index 0cdac075c865..90ab790d645e 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -357,7 +357,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRequired(TRUE) ->setTranslatable(TRUE) ->setRevisionable(TRUE) - ->setSetting('default_value', '') + ->setDefaultValue('') ->setSetting('max_length', 255) ->setDisplayOptions('view', array( 'label' => 'hidden', @@ -453,11 +453,11 @@ public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $options = $node_type->getModuleSettings('node')['options']; $fields['status'] = clone $base_field_definitions['status']; - $fields['status']->setSetting('default_value', !empty($options['status']) ? NODE_PUBLISHED : NODE_NOT_PUBLISHED); + $fields['status']->setDefaultValue(!empty($options['status']) ? NODE_PUBLISHED : NODE_NOT_PUBLISHED); $fields['promote'] = clone $base_field_definitions['promote']; - $fields['promote']->setSetting('default_value', !empty($options['promote']) ? NODE_PROMOTED : NODE_NOT_PROMOTED); + $fields['promote']->setDefaultValue(!empty($options['promote']) ? NODE_PROMOTED : NODE_NOT_PROMOTED); $fields['sticky'] = clone $base_field_definitions['sticky']; - $fields['sticky']->setSetting('default_value', !empty($options['sticky']) ? NODE_STICKY : NODE_NOT_STICKY); + $fields['sticky']->setDefaultValue(!empty($options['sticky']) ? NODE_STICKY : NODE_NOT_STICKY); return $fields; } diff --git a/core/modules/serialization/src/Tests/EntitySerializationTest.php b/core/modules/serialization/src/Tests/EntitySerializationTest.php index 6266454ba9dd..fc01ced7da91 100644 --- a/core/modules/serialization/src/Tests/EntitySerializationTest.php +++ b/core/modules/serialization/src/Tests/EntitySerializationTest.php @@ -8,7 +8,6 @@ namespace Drupal\serialization\Tests; use Drupal\Core\Language\LanguageInterface; -use Symfony\Component\Serializer\Serializer; use Drupal\Component\Utility\String; /** diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php index 80f0261d6958..ee76e9f0affa 100644 --- a/core/modules/shortcut/src/Entity/Shortcut.php +++ b/core/modules/shortcut/src/Entity/Shortcut.php @@ -174,7 +174,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The name of the shortcut.')) ->setRequired(TRUE) ->setTranslatable(TRUE) - ->setSetting('default_value', '') + ->setDefaultValue('') ->setSetting('max_length', 255) ->setDisplayOptions('form', array( 'type' => 'string', diff --git a/core/modules/system/src/Tests/Entity/EntityFieldDefaultValueTest.php b/core/modules/system/src/Tests/Entity/EntityFieldDefaultValueTest.php index aaa544cb08fd..61b9aae6e340 100644 --- a/core/modules/system/src/Tests/Entity/EntityFieldDefaultValueTest.php +++ b/core/modules/system/src/Tests/Entity/EntityFieldDefaultValueTest.php @@ -59,4 +59,15 @@ protected function assertDefaultValues($entity_type) { $this->assertTrue(Uuid::isValid($entity->uuid->value), String::format('%entity_type: Default UUID', array('%entity_type' => $entity_type))); $this->assertEqual($entity->name->getValue(), array(0 => array('value' => NULL)), 'Field has one empty value by default.'); } + + /** + * Tests custom default value callbacks. + */ + public function testDefaultValueCallback() { + $entity = $this->entityManager->getStorage('entity_test_default_value')->create(); + // The description field has a default value callback for testing, see + // entity_test_field_default_value(). + $this->assertEqual($entity->description->value, 'description_' . $entity->language()->id); + } + } diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index 6c3a078dc695..864e302164db 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -6,13 +6,12 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Session\AccountInterface; use Drupal\entity\Entity\EntityFormDisplay; -use Drupal\field\FieldConfigInterface; -use Drupal\field\FieldInstanceConfigInterface; /** * Filter that limits test entity list to revisable ones. @@ -419,17 +418,19 @@ function entity_test_entity_test_mul_translation_delete(EntityInterface $transla /** * Field default value callback. * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity the field belongs to. - * @param \Drupal\field\FieldConfigInterface $field - * The field for which default values should be provided. - * @param \Drupal\field\FieldInstanceConfigInterface $instance - * The field instance for which default values should be provided. - * @param string $langcode - * The field language code to fill-in with the default value. - */ -function entity_test_field_default_value(EntityInterface $entity, FieldConfigInterface $field, FieldInstanceConfigInterface $instance, $langcode) { - return array(array('value' => $field->getName() . '_' . $langcode)); + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity being created. + * @param \Drupal\Core\Field\FieldDefinitionInterface $definition + * The field definition. + * + * @return array + * An array of default values, in the same format as the $default_value + * property. + * + * @see \Drupal\field\Entity\FieldInstanceConfig::$default_value + */ +function entity_test_field_default_value(ContentEntityInterface $entity, FieldDefinitionInterface $definition) { + return array(array('value' => $definition->getName() . '_' . $entity->language()->id)); } /** diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php new file mode 100644 index 000000000000..89fc15b879e9 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php @@ -0,0 +1,43 @@ +<?php + +/** + * @file + * Contains \Drupal\entity_test\Entity\EntityTestDefaultValue. + */ + +namespace Drupal\entity_test\Entity; + +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\FieldDefinition; + +/** + * Defines a test entity class for testing default values. + * + * @ContentEntityType( + * id = "entity_test_default_value", + * label = @Translation("Test entity for default values"), + * base_table = "entity_test_default_value", + * fieldable = TRUE, + * entity_keys = { + * "id" = "id", + * "uuid" = "uuid", + * "bundle" = "type" + * } + * ) + */ +class EntityTestDefaultValue extends EntityTest { + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields = parent::baseFieldDefinitions($entity_type); + + $fields['description'] = FieldDefinition::create('string') + ->setLabel(t('Some custom description')) + ->setDefaultValueCallback('entity_test_field_default_value'); + + return $fields; + } + +} diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index a31f0808edff..603286154066 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -156,7 +156,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['weight'] = FieldDefinition::create('integer') ->setLabel(t('Weight')) ->setDescription(t('The weight of this term in relation to other terms.')) - ->setSetting('default_value', 0); + ->setDefaultValue(0); // @todo Convert this to an entity_reference field, see // https://drupal.org/node/1915056 @@ -165,7 +165,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The parents of this term.')) ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) // Save new terms with no parents by default. - ->setSetting('default_value', 0) + ->setDefaultValue(0) ->setSetting('unsigned', TRUE) ->addConstraint('TermParent', array()); diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceFieldItemList.php b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceFieldItemList.php index 70ce2c28d3ec..bae89fd64194 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceFieldItemList.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceFieldItemList.php @@ -8,52 +8,14 @@ namespace Drupal\taxonomy\Plugin\Field\FieldType; use Drupal\Core\Field\EntityReferenceFieldItemList; +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; /** * Represents a configurable taxonomy_term_reference entity field item list. */ class TaxonomyTermReferenceFieldItemList extends EntityReferenceFieldItemList { - /** - * {@inheritdoc} - */ - protected function getDefaultValue() { - $default_value = parent::getDefaultValue(); - - if ($default_value) { - // Convert UUIDs to numeric IDs. - $uuids = array(); - foreach ($default_value as $delta => $properties) { - $uuids[$delta] = $properties['target_uuid']; - } - if ($uuids) { - $entity_ids = \Drupal::entityQuery('taxonomy_term') - ->condition('uuid', $uuids, 'IN') - ->execute(); - $entities = \Drupal::entityManager() - ->getStorage('taxonomy_term') - ->loadMultiple($entity_ids); - - foreach ($entities as $id => $entity) { - $entity_ids[$entity->uuid()] = $id; - } - foreach ($uuids as $delta => $uuid) { - if (isset($entity_ids[$uuid])) { - $default_value[$delta]['target_id'] = $entity_ids[$uuid]; - unset($default_value[$delta]['target_uuid']); - } - else { - unset($default_value[$delta]); - } - } - } - - // Ensure we return consecutive deltas, in case we removed unknown UUIDs. - $default_value = array_values($default_value); - } - return $default_value; - } - /** * {@inheritdoc} */ @@ -76,4 +38,43 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo return $default_value; } + /** + * {@inheritdoc} + */ + public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) { + $default_value = parent::processDefaultValue($default_value, $entity, $definition); + + // Convert UUIDs to numeric IDs. + $uuids = array(); + foreach ($default_value as $delta => $properties) { + $uuids[$delta] = $properties['target_uuid']; + } + if ($uuids) { + $entity_ids = \Drupal::entityQuery('taxonomy_term') + ->condition('uuid', $uuids, 'IN') + ->execute(); + $entities = \Drupal::entityManager() + ->getStorage('taxonomy_term') + ->loadMultiple($entity_ids); + + foreach ($entities as $id => $entity) { + $entity_ids[$entity->uuid()] = $id; + } + foreach ($uuids as $delta => $uuid) { + if (isset($entity_ids[$uuid])) { + $default_value[$delta]['target_id'] = $entity_ids[$uuid]; + unset($default_value[$delta]['target_uuid']); + } + else { + unset($default_value[$delta]); + } + } + } + + // Ensure we return consecutive deltas, in case we removed unknown UUIDs. + $default_value = array_values($default_value); + + return $default_value; + } + } diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 3cc77b730fdd..d6cfe967ccb0 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -470,7 +470,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['name'] = FieldDefinition::create('string') ->setLabel(t('Name')) ->setDescription(t('The name of this user.')) - ->setSetting('default_value', '') + ->setDefaultValue('') ->setPropertyConstraints('value', array( // No Length constraint here because the UserName constraint also covers // that. @@ -485,7 +485,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['mail'] = FieldDefinition::create('email') ->setLabel(t('Email')) ->setDescription(t('The email of this user.')) - ->setSetting('default_value', '') + ->setDefaultValue('') ->setPropertyConstraints('value', array('UserMailUnique' => array())); // @todo Convert to a text field in https://drupal.org/node/1548204. @@ -504,7 +504,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['status'] = FieldDefinition::create('boolean') ->setLabel(t('User status')) ->setDescription(t('Whether the user is active or blocked.')) - ->setSetting('default_value', FALSE); + ->setDefaultValue(FALSE); $fields['created'] = FieldDefinition::create('created') ->setLabel(t('Created')) @@ -513,17 +513,17 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['access'] = FieldDefinition::create('timestamp') ->setLabel(t('Last access')) ->setDescription(t('The time that the user last accessed the site.')) - ->setSetting('default_value', 0); + ->setDefaultValue(0); $fields['login'] = FieldDefinition::create('timestamp') ->setLabel(t('Last login')) ->setDescription(t('The time that the user last logged in.')) - ->setSetting('default_value', 0); + ->setDefaultValue(0); $fields['init'] = FieldDefinition::create('email') ->setLabel(t('Initial email')) ->setDescription(t('The email address used for initial account creation.')) - ->setSetting('default_value', ''); + ->setDefaultValue(''); // @todo Convert this to entity_reference_field, see // https://drupal.org/node/2044859. diff --git a/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php b/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php index 9637ccbf372b..d620399953d9 100644 --- a/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php @@ -149,12 +149,14 @@ public function testDefaultFieldSettings() { */ public function testFieldDefaultValue() { $definition = FieldDefinition::create($this->fieldType); - $setting = 'default_value'; $value = $this->randomName(); - $definition->setSetting($setting, $value); - $entity = $this->getMockBuilder('Drupal\Core\Entity\Entity') + $definition->setDefaultValue($value); + $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase') ->disableOriginalConstructor() ->getMock(); + // Set the field item list class to be used to avoid requiring the typed + // data manager to retrieve it. + $definition->setClass('Drupal\Core\Field\FieldItemList'); $this->assertEquals($value, $definition->getDefaultValue($entity)); } -- GitLab