diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php index db194b5485..8577f25c98 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; @@ -78,9 +79,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->getConfigTypedData()->get($property_name); } // This will throw an exception for unknown fields. return $this->entity->get($property_name); @@ -93,13 +92,14 @@ public function set($property_name, $value, $notify = TRUE) { if (!isset($this->entity)) { 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."); + if ($this->entity instanceof ConfigEntityInterface) { + $this->entity->set($property_name, $value, $notify); } - // This will throw an exception for unknown fields. - $this->entity->set($property_name, $value, $notify); + else { + // This will throw an exception for unknown fields. + $this->entity->set($property_name, $value, $notify); + } + return $this; } @@ -111,9 +111,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->getConfigTypedData()->getProperties($include_computed); } return $this->entity->getFields($include_computed); } @@ -167,7 +165,57 @@ public function applyDefaultValue($notify = TRUE) { * {@inheritdoc} */ public function getIterator() { - return isset($this->entity) ? $this->entity->getIterator() : new \ArrayIterator([]); + if (isset($this->entity)) { + if ($this->entity instanceof ConfigEntityInterface) { + return $this->getConfigTypedData()->getIterator(); + } + else { + return $this->entity->getIterator(); + } + } + return 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; } + /** + * Get typed data for config entity. + * + * @return \Drupal\Core\TypedData\TraversableTypedDataInterface + * The typed data. + */ + protected function getConfigTypedData() { + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $type_config_manager */ + $type_config_manager = \Drupal::service('config.typed'); + return $type_config_manager->createFromNameAndData($this->entity->getConfigDependencyName(), $this->entity->toArray()); + } + + /** + * {@inheritdoc} + */ + public function validate() { + if ($this->entity instanceof ConfigEntityInterface) { + return $this->getConfigTypedData()->validate(); + } + return parent::validate(); + } + + } 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..5da54c513b --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityAdapterTest.php @@ -0,0 +1,98 @@ +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', + // Set weight to be a string which should not validate. + 'weight' => "very heavy", + ]); + $adapter = EntityAdapter::createFromEntity($this->entity); + $violations = $adapter->validate(); + $this->assertCount(1, $violations); + $violation = $violations->get(0); + $this->assertEquals('This value should be of the correct primitive type.', $violation->getMessage()); + $this->assertEquals('weight', $violation->getPropertyPath()); + } + + 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); + } + +}