diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 90bb702379..c650e6977d 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -639,4 +639,23 @@ public function save() { return $return; } + /** + * {@inheritdoc} + */ + public function getTypedData() { + if (!isset($this->typedData)) { + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $type_config_manager */ + $type_config_manager = \Drupal::service('config.typed'); + $this->typedData = $type_config_manager->createFromNameAndData($this->getConfigDependencyName(), $this->toArray()); + } + return $this->typedData; + } + + /** + * {@inheritdoc} + */ + public function getIterator() { + return $this->getTypedData()->getIterator(); + } + } diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php index db194b5485..8895440ece 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php @@ -2,6 +2,7 @@ namespace Drupal\Core\Entity\Plugin\DataType; +use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\TypedData\EntityDataDefinition; @@ -45,8 +46,10 @@ class EntityAdapter extends TypedData implements \IteratorAggregate, ComplexData */ public static function createFromEntity(EntityInterface $entity) { $definition = EntityDataDefinition::create() - ->setEntityTypeId($entity->getEntityTypeId()) - ->setBundles([$entity->bundle()]); + ->setEntityTypeId($entity->getEntityTypeId()); + if ($entity instanceof FieldableEntityInterface) { + $definition->setBundles([$entity->bundle()]); + } $instance = new static($definition); $instance->setValue($entity); return $instance; @@ -78,9 +81,7 @@ public function get($property_name) { throw new MissingDataException("Unable to get property $property_name as no entity has been provided."); } if (!$this->entity instanceof FieldableEntityInterface) { - // @todo: Add support for config entities in - // https://www.drupal.org/node/1818574. - throw new \InvalidArgumentException("Unable to get unknown property $property_name."); + return $this->entity->getTypedData()->get($property_name); } // This will throw an exception for unknown fields. return $this->entity->get($property_name); @@ -94,9 +95,7 @@ public function set($property_name, $value, $notify = TRUE) { throw new MissingDataException("Unable to set property $property_name as no entity has been provided."); } if (!$this->entity instanceof FieldableEntityInterface) { - // @todo: Add support for config entities in - // https://www.drupal.org/node/1818574. - throw new \InvalidArgumentException("Unable to set unknown property $property_name."); + $this->entity->getTypedData()->set($property_name, $value, $notify); } // This will throw an exception for unknown fields. $this->entity->set($property_name, $value, $notify); @@ -111,9 +110,7 @@ public function getProperties($include_computed = FALSE) { throw new MissingDataException('Unable to get properties as no entity has been provided.'); } if (!$this->entity instanceof FieldableEntityInterface) { - // @todo: Add support for config entities in - // https://www.drupal.org/node/1818574. - return []; + return $this->entity->getTypedData()->getProperties($include_computed); } return $this->entity->getFields($include_computed); } @@ -170,4 +167,23 @@ public function getIterator() { return isset($this->entity) ? $this->entity->getIterator() : new \ArrayIterator([]); } + /** + * Gets the typed data manager. + * + * @return \Drupal\Core\TypedData\TypedDataManagerInterface + * The typed data manager. + */ + public function getTypedDataManager() { + if (empty($this->typedDataManager)) { + if ($this->entity instanceof ConfigEntityInterface) { + $this->typedDataManager = \Drupal::service('config.typed'); + } + else { + $this->typedDataManager = \Drupal::typedDataManager(); + } + } + + return $this->typedDataManager; + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityAdapterTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityAdapterTest.php new file mode 100644 index 0000000000..fc430c0d7a --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityAdapterTest.php @@ -0,0 +1,94 @@ +installConfig(static::$modules); + + $this->entity = entity_create('config_test', [ + 'id' => 'system', + 'label' => 'foobar', + 'weight' => 1, + ]); + } + + public function testValidate() { + $adapter = EntityAdapter::createFromEntity($this->entity); + $violations = $adapter->validate(); + $this->assertEmpty($violations); + $this->entity = entity_create('config_test', [ + 'id' => 'system', + 'label' => 'foobar', + 'weight' => "very heavy", + ]); + $adapter = EntityAdapter::createFromEntity($this->entity); + $violations = $adapter->validate(); + $this->assertCount(1, $violations); + } + + public function testGetProperties() { + $expected_properties = [ + 'uuid' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'langcode' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'status' => 'Drupal\Core\TypedData\Plugin\DataType\BooleanData', + 'dependencies' => 'Drupal\Core\Config\Schema\Mapping', + 'id' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'label' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'weight' => 'Drupal\Core\TypedData\Plugin\DataType\IntegerData', + 'style' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'size' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'size_value' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + 'protected_property' => 'Drupal\Core\TypedData\Plugin\DataType\StringData', + ]; + $properties = EntityAdapter::createFromEntity($this->entity)->getProperties(); + $keys = []; + foreach ($properties as $key => $property) { + $keys[] = $key; + $this->assertEquals($expected_properties[$key], get_class($property)); + } + $this->assertSame(array_keys($expected_properties), $keys); + } + + public function testGetProperty() { + $adapter = EntityAdapter::createFromEntity($this->entity); + $this->assertEquals($this->entity->weight, $adapter->get('weight')->getValue()); + $this->assertEquals($this->entity->id(), $adapter->get('id')->getValue()); + $this->assertEquals($this->entity->label, $adapter->get('label')->getValue()); + } + + public function testSetProperty() { + $adapter = EntityAdapter::createFromEntity($this->entity); + $adapter->set('weight', 2); + $this->assertEquals(2, $this->entity->weight); + } + +}