diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 3615197d16d..c695934f6db 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -364,9 +364,9 @@ field_config_base: label: 'Translatable' default_value: type: field.[%parent.field_type].value - default_value_function: + default_value_callback: type: string - label: 'Default value function' + label: 'Default value callback' settings: type: field.[%parent.field_type].field_settings third_party_settings: diff --git a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php index 7eb0d8ae6c9..613f88ffc12 100644 --- a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php +++ b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php @@ -397,7 +397,7 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI * * If set, the callback overrides any set default value. * - * @param callable|null $callback + * @param string|null $callback * The callback to invoke for getting the default value (pass NULL to unset * a previously set callback). The callback will be invoked with the * following arguments: @@ -411,6 +411,9 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI * @return $this */ public function setDefaultValueCallback($callback) { + if (isset($callback) && !is_string($callback)) { + throw new \InvalidArgumentException('Default value callback must be a string, like "function_name" or "ClassName::methodName"'); + } $this->definition['default_value_callback'] = $callback; return $this; } diff --git a/core/lib/Drupal/Core/Field/FieldConfigBase.php b/core/lib/Drupal/Core/Field/FieldConfigBase.php index 69473f44673..e0764cdf5ac 100644 --- a/core/lib/Drupal/Core/Field/FieldConfigBase.php +++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php @@ -135,7 +135,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn * hook_field_schema(). If the number of items exceeds the cardinality of the * field, extraneous items will be ignored. * - * This property is overlooked if the $default_value_function is non-empty. + * This property is overlooked if the $default_value_callback is non-empty. * * Example for a integer field: * @code @@ -165,7 +165,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn * * @var string */ - public $default_value_function = ''; + public $default_value_callback = ''; /** * The field storage object. @@ -334,8 +334,8 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn */ public function getDefaultValue(ContentEntityInterface $entity) { // Allow custom default values function. - if ($function = $this->default_value_function) { - $value = call_user_func($function, $entity, $this); + if ($callback = $this->default_value_callback) { + $value = call_user_func($callback, $entity, $this); } else { $value = $this->default_value; diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php index f6ae7d58ceb..393b827d2c2 100644 --- a/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -318,7 +318,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface { * {@inheritdoc} */ public function defaultValuesForm(array &$form, FormStateInterface $form_state) { - if (empty($this->getFieldDefinition()->default_value_function)) { + if (empty($this->getFieldDefinition()->default_value_callback)) { // Place the input in a separate place in the submitted values tree. $widget = $this->defaultValueWidget($form_state); diff --git a/core/modules/book/config/install/core.base_field_override.node.book.promote.yml b/core/modules/book/config/install/core.base_field_override.node.book.promote.yml index 96ce2f6d5d5..609d39144df 100644 --- a/core/modules/book/config/install/core.base_field_override.node.book.promote.yml +++ b/core/modules/book/config/install/core.base_field_override.node.book.promote.yml @@ -15,6 +15,6 @@ translatable: true default_value: - value: 0 -default_value_function: '' +default_value_callback: '' settings: { } field_type: boolean diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php index aa038825118..b2f2c113a51 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php @@ -32,7 +32,7 @@ class DateTimeFieldItemList extends FieldItemList { * {@inheritdoc} */ public function defaultValuesForm(array &$form, FormStateInterface $form_state) { - if (empty($this->getFieldDefinition()->default_value_function)) { + if (empty($this->getFieldDefinition()->default_value_callback)) { $default_value = $this->getFieldDefinition()->default_value; $element = array( diff --git a/core/modules/field/src/Tests/FieldAttachStorageTest.php b/core/modules/field/src/Tests/FieldAttachStorageTest.php index 205dd207c1e..e6c578fcf25 100644 --- a/core/modules/field/src/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/src/Tests/FieldAttachStorageTest.php @@ -194,7 +194,7 @@ class FieldAttachStorageTest extends FieldUnitTestBase { $this->createFieldWithStorage('', $entity_type); // Add a default value function. - $this->fieldTestData->field->default_value_function = 'field_test_default_value'; + $this->fieldTestData->field->default_value_callback = 'field_test_default_value'; $this->fieldTestData->field->save(); // Verify that fields are populated with default values. diff --git a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import.yml index a9ef175c11d..b205693efb5 100644 --- a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import.yml +++ b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import.yml @@ -7,7 +7,7 @@ label: 'Test import field' description: '' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import_2.yml b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import_2.yml index 6c359e2bbb0..ce266635865 100644 --- a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import_2.yml +++ b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.entity_test.field_test_import_2.yml @@ -7,7 +7,7 @@ label: 'Test import field 2 on entity_test bundle' description: '' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.test_bundle.field_test_import_2.yml b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.test_bundle.field_test_import_2.yml index 7d63acb32d7..37adededf57 100644 --- a/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.test_bundle.field_test_import_2.yml +++ b/core/modules/field/tests/modules/field_test_config/config/install/field.field.entity_test.test_bundle.field_test_import_2.yml @@ -7,7 +7,7 @@ label: 'Test import field 2 on test bundle' description: '' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.entity_test.field_test_import_staging.yml b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.entity_test.field_test_import_staging.yml index 9a088dd789f..fe28921e4ab 100644 --- a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.entity_test.field_test_import_staging.yml +++ b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.entity_test.field_test_import_staging.yml @@ -8,7 +8,7 @@ label: 'Import from staging' description: '' required: '0' default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle.field_test_import_staging_2.yml b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle.field_test_import_staging_2.yml index cc8ccd4530a..d1db2b2e95c 100644 --- a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle.field_test_import_staging_2.yml +++ b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle.field_test_import_staging_2.yml @@ -8,7 +8,7 @@ label: 'Test import field 2 on test bundle' description: '' required: '0' default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle_2.field_test_import_staging_2.yml b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle_2.field_test_import_staging_2.yml index f58572a6a66..07953c9b82c 100644 --- a/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle_2.field_test_import_staging_2.yml +++ b/core/modules/field/tests/modules/field_test_config/staging/field.field.entity_test.test_bundle_2.field_test_import_staging_2.yml @@ -8,7 +8,7 @@ label: 'Test import field 2 on test bundle 2' description: '' required: '0' default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: text dependencies: diff --git a/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php b/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php index 15e3d65704b..eb516d7302d 100644 --- a/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php +++ b/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php @@ -159,7 +159,7 @@ class FieldConfigEntityUnitTest extends UnitTestCase { 'description' => '', 'required' => FALSE, 'default_value' => array(), - 'default_value_function' => '', + 'default_value_callback' => '', 'settings' => array(), 'dependencies' => array(), 'field_type' => 'test_field', diff --git a/core/modules/forum/config/install/core.base_field_override.node.forum.promote.yml b/core/modules/forum/config/install/core.base_field_override.node.forum.promote.yml index 42c7cce01a3..3f20b64210d 100644 --- a/core/modules/forum/config/install/core.base_field_override.node.forum.promote.yml +++ b/core/modules/forum/config/install/core.base_field_override.node.forum.promote.yml @@ -15,6 +15,6 @@ translatable: true default_value: - value: 0 -default_value_function: '' +default_value_callback: '' settings: { } field_type: boolean diff --git a/core/modules/forum/config/install/core.base_field_override.node.forum.title.yml b/core/modules/forum/config/install/core.base_field_override.node.forum.title.yml index cd1f9d3c580..c956f344c73 100644 --- a/core/modules/forum/config/install/core.base_field_override.node.forum.title.yml +++ b/core/modules/forum/config/install/core.base_field_override.node.forum.title.yml @@ -13,6 +13,6 @@ description: 'The title of this node, always treated as non-markup plain text.' required: true translatable: true default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } field_type: string diff --git a/core/modules/forum/config/install/field.field.taxonomy_term.forums.forum_container.yml b/core/modules/forum/config/install/field.field.taxonomy_term.forums.forum_container.yml index b1c47ea20d1..80569150fcb 100644 --- a/core/modules/forum/config/install/field.field.taxonomy_term.forums.forum_container.yml +++ b/core/modules/forum/config/install/field.field.taxonomy_term.forums.forum_container.yml @@ -10,7 +10,7 @@ required: true default_value: - value: 0 -default_value_function: '' +default_value_callback: '' settings: { } field_type: boolean dependencies: diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_field_instance.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_field_instance.yml index 1ef6a307fbf..978fb2c609b 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_field_instance.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_field_instance.yml @@ -36,7 +36,7 @@ process: - widget_settings - global_settings - default_value_function: '' + default_value_callback: '' default_value: plugin: d6_field_instance_defaults source: diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index b01ae1e159b..b5bb8f83e0b 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -376,7 +376,7 @@ class Node extends ContentEntityBase implements NodeInterface { ->setRevisionable(TRUE) ->setSetting('target_type', 'user') ->setSetting('handler', 'default') - ->setDefaultValueCallback(array('Drupal\node\Entity\Node', 'getCurrentUserId')) + ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId') ->setTranslatable(TRUE) ->setDisplayOptions('view', array( 'label' => 'hidden', diff --git a/core/modules/node/src/Tests/NodeFieldOverridesTest.php b/core/modules/node/src/Tests/NodeFieldOverridesTest.php new file mode 100644 index 00000000000..b5d13b44435 --- /dev/null +++ b/core/modules/node/src/Tests/NodeFieldOverridesTest.php @@ -0,0 +1,69 @@ +installEntitySchema('node'); + $this->installConfig(array('user')); + $this->user = $this->createUser(); + \Drupal::service('current_user')->setAccount($this->user); + } + + /** + * Tests that field overrides work as expected. + */ + public function testFieldOverrides() { + if (!NodeType::load('ponies')) { + NodeType::create(['name' => 'Ponies', 'type' => 'ponies'])->save(); + } + $override = BaseFieldOverride::loadByName('node', 'ponies', 'uid'); + if ($override) { + $override->delete(); + } + $uid_field = \Drupal::entityManager()->getBaseFieldDefinitions('node')['uid']; + $config = $uid_field->getConfig('ponies'); + $config->save(); + $this->assertEqual($config->get('default_value_callback'), 'Drupal\node\Entity\Node::getCurrentUserId'); + /** @var \Drupal\node\NodeInterface $node */ + $node = Node::create(['type' => 'ponies']); + $owner = $node->getOwner(); + $this->assertTrue($owner instanceof \Drupal\user\UserInterface); + $this->assertEqual($owner->id(), $this->user->id()); + } + +} diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php index e6b67d51c00..efb96c76ced 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php @@ -438,7 +438,7 @@ class EntityTranslationTest extends EntityLanguageTestBase { $entity = $this->reloadEntity($entity); $field_id = implode('.', array($entity->getEntityTypeId(), $entity->bundle(), $this->field_name)); $field = $this->entityManager->getStorage('field_config')->load($field_id); - $field->default_value_function = 'entity_test_field_default_value'; + $field->default_value_callback = 'entity_test_field_default_value'; $field->save(); $translation = $entity->addTranslation($langcode2); $field_storage = $translation->get($this->field_name); diff --git a/core/profiles/standard/config/install/core.base_field_override.node.page.promote.yml b/core/profiles/standard/config/install/core.base_field_override.node.page.promote.yml index 31de54b8731..1555eed84f2 100644 --- a/core/profiles/standard/config/install/core.base_field_override.node.page.promote.yml +++ b/core/profiles/standard/config/install/core.base_field_override.node.page.promote.yml @@ -15,6 +15,6 @@ translatable: true default_value: - value: 0 -default_value_function: '' +default_value_callback: '' settings: { } field_type: boolean diff --git a/core/profiles/standard/config/install/field.field.node.article.field_image.yml b/core/profiles/standard/config/install/field.field.node.article.field_image.yml index 31ba6386b31..b4b91688817 100644 --- a/core/profiles/standard/config/install/field.field.node.article.field_image.yml +++ b/core/profiles/standard/config/install/field.field.node.article.field_image.yml @@ -6,7 +6,7 @@ label: Image description: '' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: file_directory: field/image file_extensions: 'png gif jpg jpeg' diff --git a/core/profiles/standard/config/install/field.field.node.article.field_tags.yml b/core/profiles/standard/config/install/field.field.node.article.field_tags.yml index 0960d3f4d7c..53acce3c288 100644 --- a/core/profiles/standard/config/install/field.field.node.article.field_tags.yml +++ b/core/profiles/standard/config/install/field.field.node.article.field_tags.yml @@ -7,7 +7,7 @@ label: Tags description: 'Enter a comma-separated list. For example: Amsterdam, Mexico City, "Cleveland, Ohio"' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: { } status: true langcode: und diff --git a/core/profiles/standard/config/install/field.field.user.user.user_picture.yml b/core/profiles/standard/config/install/field.field.user.user.user_picture.yml index a7a2ef72cc4..d6b31c23ad9 100644 --- a/core/profiles/standard/config/install/field.field.user.user.user_picture.yml +++ b/core/profiles/standard/config/install/field.field.user.user.user_picture.yml @@ -8,7 +8,7 @@ label: Picture description: 'Your virtual face or picture.' required: false default_value: { } -default_value_function: '' +default_value_callback: '' settings: file_extensions: 'png gif jpg jpeg' file_directory: pictures diff --git a/core/tests/Drupal/Tests/Core/Entity/BaseFieldDefinitionTest.php b/core/tests/Drupal/Tests/Core/Entity/BaseFieldDefinitionTest.php index ab0ad760718..17cb5182bc9 100644 --- a/core/tests/Drupal/Tests/Core/Entity/BaseFieldDefinitionTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/BaseFieldDefinitionTest.php @@ -16,6 +16,7 @@ use Drupal\Tests\UnitTestCase; * Unit test for BaseFieldDefinition. * * @group Entity + * @coversDefaultClass \Drupal\Core\Field\BaseFieldDefinition */ class BaseFieldDefinitionTest extends UnitTestCase { @@ -75,6 +76,8 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field name methods. + * + * @covers ::getName() */ public function testFieldName() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -85,6 +88,8 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field label methods. + * + * @covers ::getLabel() */ public function testFieldLabel() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -95,6 +100,8 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field description methods. + * + * @covers ::getDescription() */ public function testFieldDescription() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -105,6 +112,8 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field type methods. + * + * @covers ::getType() */ public function testFieldType() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -113,6 +122,10 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field settings methods. + * + * @covers ::getSetting() + * @covers ::setSetting() + * @covers ::getSettings() */ public function testFieldSettings() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -126,6 +139,10 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests the initialization of default field settings. + * + * @covers ::getSetting() + * @covers ::setSetting() + * @covers ::getSettings() */ public function testDefaultFieldSettings() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -138,6 +155,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field default value. + * + * @covers ::getDefaultValue() + * @covers ::setDefaultValue() */ public function testFieldDefaultValue() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -154,6 +174,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field translatable methods. + * + * @covers ::isTranslatable() + * @covers ::setTranslatable() */ public function testFieldTranslatable() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -166,6 +189,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field revisionable methods. + * + * @covers ::isRevisionable() + * @covers ::setRevisionable() */ public function testFieldRevisionable() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -178,6 +204,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests field cardinality. + * + * @covers ::getCardinality() + * @covers ::setCardinality() */ public function testFieldCardinality() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -190,6 +219,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests required. + * + * @covers ::isRequired() + * @covers ::setRequired() */ public function testFieldRequired() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -202,6 +234,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests provider. + * + * @covers ::getProvider() + * @covers ::setProvider() */ public function testFieldProvider() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -212,6 +247,9 @@ class BaseFieldDefinitionTest extends UnitTestCase { /** * Tests custom storage. + * + * @covers ::hasCustomStorage() + * @covers ::setCustomStorage() */ public function testCustomStorage() { $definition = BaseFieldDefinition::create($this->fieldType); @@ -222,4 +260,51 @@ class BaseFieldDefinitionTest extends UnitTestCase { $this->assertFalse($definition->hasCustomStorage()); } + /** + * Tests default value callbacks. + * + * @covers ::setDefaultValueCallback() + */ + public function testDefaultValueCallback() { + $definition = BaseFieldDefinition::create($this->fieldType); + $callback = get_class($this) . '::mockDefaultValueCallback'; + $definition->setDefaultValueCallback($callback); + } + + /** + * Tests invalid default value callbacks. + * + * @covers ::setDefaultValueCallback() + * @expectedException \InvalidArgumentException + */ + public function testInvalidDefaultValueCallback() { + $definition = BaseFieldDefinition::create($this->fieldType); + $definition->setDefaultValueCallback([get_class($this), 'mockDefaultValueCallback']); + } + + /** + * Tests NULL default value callbacks. + * + * @covers ::setDefaultValueCallback + */ + public function testNullDefaultValueCallback() { + $definition = BaseFieldDefinition::create($this->fieldType); + $definition->setDefaultValueCallback(NULL); + } + + /** + * Provides a Mock base field default value callback. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * Entity interface. + * @param \Drupal\Core\Field\FieldDefinitionInterface $definition + * Field definition. + * + * @return string + * Default value. + */ + public static function mockDefaultValueCallback($entity, $definition) { + return 'a default value'; + } + }