From b2b7f4665a14f9fb236cd5646f6576a90c914680 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Wed, 24 Jan 2018 07:31:04 +1000 Subject: [PATCH] Issue #2936725 by gabesullice, Wim Leers, dawehner, Berdir: EntityDataDefinition::create() does not respect derived entity definitions --- .../Entity/TypedData/EntityDataDefinition.php | 43 +++++++++++++------ .../tests/src/Unit/EntityViewsDataTest.php | 6 ++- .../Entity/EntityTypedDataDefinitionTest.php | 14 +++++- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/TypedData/EntityDataDefinition.php b/core/lib/Drupal/Core/Entity/TypedData/EntityDataDefinition.php index be6405af4ab..21c05d1e35d 100644 --- a/core/lib/Drupal/Core/Entity/TypedData/EntityDataDefinition.php +++ b/core/lib/Drupal/Core/Entity/TypedData/EntityDataDefinition.php @@ -18,13 +18,35 @@ class EntityDataDefinition extends ComplexDataDefinitionBase implements EntityDa * * @return static */ - public static function create($entity_type_id = NULL) { - $definition = new static([]); - // Set the passed entity type. + public static function create($entity_type_id = NULL, $bundle = NULL) { + // If the entity type is known, use the derived definition. if (isset($entity_type_id)) { + $data_type = "entity:{$entity_type_id}"; + + // If a bundle was given, use the bundle-specific definition. + if ($bundle) { + $data_type .= ":{$bundle}"; + } + + // It's possible that the given entity type ID or bundle wasn't discovered + // by the TypedData plugin manager and/or weren't created by the + // EntityDeriver. In that case, this is a new definition and we'll just + // create the definition from defaults by using an empty array. + $values = \Drupal::typedDataManager()->getDefinition($data_type, FALSE); + $definition = new static(is_array($values) ? $values : []); + + // Set the EntityType constraint using the given entity type ID. $definition->setEntityTypeId($entity_type_id); + + // If available, set the Bundle constraint. + if ($bundle) { + $definition->setBundles([$bundle]); + } + + return $definition; } - return $definition; + + return new static([]); } /** @@ -35,15 +57,10 @@ class EntityDataDefinition extends ComplexDataDefinitionBase implements EntityDa if ($parts[0] != 'entity') { throw new \InvalidArgumentException('Data type must be in the form of "entity:ENTITY_TYPE:BUNDLE."'); } - $definition = static::create(); - // Set the passed entity type and bundle. - if (isset($parts[1])) { - $definition->setEntityTypeId($parts[1]); - } - if (isset($parts[2])) { - $definition->setBundles([$parts[2]]); - } - return $definition; + return static::create( + isset($parts[1]) ? $parts[1] : NULL, + isset($parts[2]) ? $parts[2] : NULL + ); } /** diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index d8b63ce418d..1bd3970536f 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -93,8 +93,10 @@ class EntityViewsDataTest extends UnitTestCase { $typed_data_manager->expects($this->any()) ->method('getDefinition') - ->with($this->equalTo('field_item:string_long')) - ->willReturn(['class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem']); + ->will($this->returnValueMap([ + 'entity:user' => ['class' => '\Drupal\Core\TypedData\DataDefinitionInterface'], + 'field_item:string_long' => ['class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem'], + ])); $this->baseEntityType = new TestEntityType([ 'base_table' => 'entity_test', diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php index 5e755d95842..67882097057 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php @@ -11,6 +11,7 @@ use Drupal\Core\TypedData\DataReferenceDefinition; use Drupal\Core\TypedData\DataReferenceDefinitionInterface; use Drupal\Core\TypedData\ListDataDefinitionInterface; use Drupal\KernelTests\KernelTestBase; +use Drupal\node\Entity\NodeType; /** * Tests deriving metadata of entity and field data types. @@ -31,10 +32,16 @@ class EntityTypedDataDefinitionTest extends KernelTestBase { * * @var array */ - public static $modules = ['filter', 'text', 'node', 'user']; + public static $modules = ['system', 'filter', 'text', 'node', 'user']; protected function setUp() { parent::setup(); + + NodeType::create([ + 'type' => 'article', + 'name' => 'Article', + ])->save(); + $this->typedDataManager = $this->container->get('typed_data_manager'); } @@ -82,10 +89,15 @@ class EntityTypedDataDefinitionTest extends KernelTestBase { */ public function testEntities() { $entity_definition = EntityDataDefinition::create('node'); + $bundle_definition = EntityDataDefinition::create('node', 'article'); // Entities are complex data. $this->assertFalse($entity_definition instanceof ListDataDefinitionInterface); $this->assertTrue($entity_definition instanceof ComplexDataDefinitionInterface); + // Entity definitions should inherit their labels from the entity type. + $this->assertEquals('Content', $entity_definition->getLabel()); + $this->assertEquals('Article', $bundle_definition->getLabel()); + $field_definitions = $entity_definition->getPropertyDefinitions(); // Comparison should ignore the internal static cache, so compare the // serialized objects instead.