diff --git a/core/lib/Drupal/Core/Field/BundleFieldDefinition.php b/core/lib/Drupal/Core/Field/BundleFieldDefinition.php index 85c88d64c2..ec956d589b 100644 --- a/core/lib/Drupal/Core/Field/BundleFieldDefinition.php +++ b/core/lib/Drupal/Core/Field/BundleFieldDefinition.php @@ -50,14 +50,8 @@ class BundleFieldDefinition extends ListDataDefinition implements FieldDefinitio * @return static */ public static function createFromFieldStorageDefinition(FieldStorageDefinitionInterface $storageDefinition) { - $field_definition = new static([]); - $field_definition->fieldStorageDefinition = $storageDefinition; - $field_definition->itemDefinition = FieldItemDataDefinition::create($field_definition); - // Create a definition for the items, and initialize it with the default - // settings for the field type. - $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); - $default_settings = $field_type_manager->getDefaultFieldSettings($storageDefinition->getType()); - $field_definition->itemDefinition->setSettings($default_settings); + $field_definition = new static(); + $field_definition->setFieldStorageDefinition($storageDefinition); return $field_definition; } @@ -171,7 +165,12 @@ public function getDefaultValueLiteral() { } /** - * {@inheritdoc} + * Set the default value callback for the field. + * + * @param string $callback + * The default value callback. + * + * @return $this */ public function setDefaultValueCallback($callback) { if (isset($callback) && !is_string($callback)) { @@ -239,6 +238,26 @@ public function isTranslatable() { return !empty($this->definition['translatable']); } + /** + * Set the field storage definition. + * + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storageDefinition + * The field storage definition associated with this bundle field. + * + * @return $this + * The object itself for chaining. + */ + public function setFieldStorageDefinition(FieldStorageDefinitionInterface $storageDefinition) { + $this->fieldStorageDefinition = $storageDefinition; + $this->itemDefinition = FieldItemDataDefinition::create($this); + // Create a definition for the items, and initialize it with the default + // settings for the field type. + $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); + $default_settings = $field_type_manager->getDefaultFieldSettings($storageDefinition->getType()); + $this->itemDefinition->setSettings($default_settings); + return $this; + } + /** * {@inheritdoc} */ diff --git a/core/tests/Drupal/Tests/Core/Entity/BundleFieldDefinitionTest.php b/core/tests/Drupal/Tests/Core/Entity/BundleFieldDefinitionTest.php index 1c1985a3c4..1ce4711664 100644 --- a/core/tests/Drupal/Tests/Core/Entity/BundleFieldDefinitionTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/BundleFieldDefinitionTest.php @@ -7,6 +7,7 @@ use Drupal\Core\Field\BundleFieldDefinition; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\Tests\UnitTestCase; /** @@ -72,25 +73,30 @@ protected function setUp() { 'foo' => $storage_definition->reveal(), ]); + $typed_data_manager = $this->prophesize(TypedDataManager::class); + $container = new ContainerBuilder(); $container->set('plugin.manager.field.field_type', $field_type_manager->reveal()); $container->set('entity_field.manager', $entity_field_manager->reveal()); + $container->set('typed_data_manager', $typed_data_manager->reveal()); \Drupal::setContainer($container); } /** * @covers ::getName + * @dataProvider factoryTypeProvider */ - public function testFieldName() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldName($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertEquals($this->storageDefinition->getName(), $definition->getName()); } /** * @covers ::getLabel + * @dataProvider factoryTypeProvider */ - public function testFieldLabel() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldLabel($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $label = $this->randomMachineName(); $definition->setLabel($label); $this->assertEquals($label, $definition->getLabel()); @@ -98,9 +104,10 @@ public function testFieldLabel() { /** * @covers ::getDescription + * @dataProvider factoryTypeProvider */ - public function testFieldDescription() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldDescription($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $description = $this->randomMachineName(); $definition->setDescription($description); $this->assertEquals($description, $definition->getDescription()); @@ -108,9 +115,10 @@ public function testFieldDescription() { /** * @covers ::getType + * @dataProvider factoryTypeProvider */ - public function testFieldType() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldType($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertEquals($this->fieldType, $definition->getType()); } @@ -118,9 +126,10 @@ public function testFieldType() { * @covers ::getSetting * @covers ::setSetting * @covers ::getSettings + * @dataProvider factoryTypeProvider */ - public function testFieldSettings() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldSettings($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $setting = $this->randomMachineName(); $value = $this->randomMachineName(); $definition->setSetting($setting, $value); @@ -133,9 +142,10 @@ public function testFieldSettings() { * @covers ::getSetting * @covers ::setSetting * @covers ::getSettings + * @dataProvider factoryTypeProvider */ - public function testDefaultFieldSettings() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testDefaultFieldSettings($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $expected_settings = $this->fieldTypeDefinition['field_settings'] + $this->fieldTypeDefinition['storage_settings'];; $this->assertEquals($expected_settings, $definition->getSettings()); foreach ($expected_settings as $setting => $value) { @@ -146,9 +156,10 @@ public function testDefaultFieldSettings() { /** * @covers ::getDefaultValue * @covers ::setDefaultValue + * @dataProvider factoryTypeProvider */ - public function testFieldDefaultValue() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldDefaultValue($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertEquals([], $definition->getDefaultValueLiteral()); @@ -195,9 +206,10 @@ public function testFieldDefaultValue() { * * @covers ::isTranslatable * @covers ::setTranslatable + * @dataProvider factoryTypeProvider */ - public function testFieldTranslatable() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldTranslatable($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertFalse($definition->isTranslatable()); $definition->setTranslatable(TRUE); $this->assertTrue($definition->isTranslatable()); @@ -210,9 +222,10 @@ public function testFieldTranslatable() { * * @covers ::isRequired * @covers ::setRequired + * @dataProvider factoryTypeProvider */ - public function testFieldRequired() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testFieldRequired($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertFalse($definition->isRequired()); $definition->setRequired(TRUE); $this->assertTrue($definition->isRequired()); @@ -224,9 +237,10 @@ public function testFieldRequired() { * Tests default value callbacks. * * @covers ::setDefaultValueCallback + * @dataProvider factoryTypeProvider */ - public function testDefaultValueCallback() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testDefaultValueCallback($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $callback = get_class($this) . '::mockDefaultValueCallback'; // setDefaultValueCallback returns $this. $this->assertSame($definition, $definition->setDefaultValueCallback($callback)); @@ -237,9 +251,10 @@ public function testDefaultValueCallback() { * Tests invalid default value callbacks. * * @covers ::setDefaultValueCallback + * @dataProvider factoryTypeProvider */ - public function testInvalidDefaultValueCallback() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testInvalidDefaultValueCallback($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); // setDefaultValueCallback returns $this. $this->setExpectedException(\InvalidArgumentException::class); $definition->setDefaultValueCallback([get_class($this), 'mockDefaultValueCallback']); @@ -249,9 +264,10 @@ public function testInvalidDefaultValueCallback() { * Tests NULL default value callbacks. * * @covers ::setDefaultValueCallback + * @dataProvider factoryTypeProvider */ - public function testNullDefaultValueCallback() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testNullDefaultValueCallback($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); // setDefaultValueCallback returns $this. $this->assertSame($definition, $definition->setDefaultValueCallback(NULL)); $this->assertSame(NULL, $definition->getDefaultValueCallback()); @@ -262,9 +278,10 @@ public function testNullDefaultValueCallback() { * * @covers ::isDisplayConfigurable * @covers ::getDisplayOptions + * @dataProvider factoryTypeProvider */ - public function testDisplayConfigurationSettings() { - $definition = BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + public function testDisplayConfigurationSettings($factory_name) { + $definition = $this->initializeBundleFieldUsingFactory($factory_name); $this->assertEquals(FALSE, $definition->isDisplayConfigurable('foo')); $this->assertEquals(NULL, $definition->getDisplayOptions('foo')); @@ -291,4 +308,54 @@ public static function mockDefaultValueCallback($entity, $definition) { return 'a default value'; } + /** + * A data provider for all the types of factories that can create definitions. + */ + public function factoryTypeProvider() { + return [ + '::createFromFieldStorageDefinition factory' => [ + 'createFromFieldStorageDefinition', + ], + '::create factory' => [ + 'create', + ], + '::createFromDataType factory' => [ + 'createFromDataType', + ], + '::createFromItemType factory' => [ + 'createFromItemType', + ], + ]; + } + + /** + * Create a bundle field using a specified factory. + * + * @param string $factory_name + * The factory name to use. + * + * @return \Drupal\Core\Field\BundleFieldDefinition + */ + protected function initializeBundleFieldUsingFactory($factory_name) { + switch ($factory_name) { + case 'createFromFieldStorageDefinition': + return BundleFieldDefinition::createFromFieldStorageDefinition($this->storageDefinition); + + case 'create': + $definition = BundleFieldDefinition::create($this->fieldType); + $definition->setFieldStorageDefinition($this->storageDefinition); + return $definition; + + case 'createFromDataType': + $definition = BundleFieldDefinition::createFromDataType($this->fieldType); + $definition->setFieldStorageDefinition($this->storageDefinition); + return $definition; + + case 'createFromItemType': + $definition = BundleFieldDefinition::createFromItemType($this->fieldType); + $definition->setFieldStorageDefinition($this->storageDefinition); + return $definition; + } + } + }