diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index e3b2b9e..349835d 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -235,15 +235,9 @@ config_dependencies: config_entity: type: mapping mapping: - id: - type: string - label: 'ID' uuid: type: string label: 'UUID' - label: - type: label - label: 'Label' langcode: type: string label: 'Default language' diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 15eba92..7439b85 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -10,6 +10,7 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface; use Drupal\Component\Utility\String; use Drupal\Core\Cache\Cache; +use Drupal\Core\Config\Schema\SchemaIncompleteException; use Drupal\Core\Entity\Entity; use Drupal\Core\Config\ConfigDuplicateUUIDException; use Drupal\Core\Entity\EntityStorageInterface; @@ -240,20 +241,36 @@ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) * {@inheritdoc} */ public function toArray() { - // Configuration objects do not have a schema. Extract all key names from - // class properties. - $class_info = new \ReflectionClass($this); $properties = array(); - foreach ($class_info->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { - $name = $property->getName(); - $properties[$name] = $this->get($name); + $config_name = $this->getEntityType()->getConfigPrefix() . '.' . $this->id(); + $definition = $this->getTypedConfig()->getDefinition($config_name); + if (!isset($definition['mapping'])) { + throw new SchemaIncompleteException(String::format('Incomplete or missing schema for @config_name', array('@config_name' => $config_name))); + } + $id_key = $this->getEntityType()->getKey('id'); + foreach (array_keys($definition['mapping']) as $name) { + // Special handling for IDs so that computed compound IDs work. + // @see \Drupal\entity\EntityDisplayBase::id() + if ($name == $id_key) { + $properties[$name] = $this->id(); + } + else { + $properties[$name] = $this->get($name); + } } - // Add protected dependencies property. - $properties['dependencies'] = $this->dependencies; return $properties; } /** + * Gets the typed config manager. + * + * @return \Drupal\Core\Config\TypedConfigManagerInterface + */ + protected function getTypedConfig() { + return \Drupal::service('config.typed'); + } + + /** * {@inheritdoc} */ public function preSave(EntityStorageInterface $storage) { diff --git a/core/modules/block/config/schema/block.schema.yml b/core/modules/block/config/schema/block.schema.yml index 9e4508b..fdf50f5 100644 --- a/core/modules/block/config/schema/block.schema.yml +++ b/core/modules/block/config/schema/block.schema.yml @@ -4,6 +4,9 @@ block.block.*: type: config_entity label: 'Block' mapping: + id: + type: string + label: 'ID' theme: type: string label: 'Theme' diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php index de6c971..3f0903b 100644 --- a/core/modules/block/src/Entity/Block.php +++ b/core/modules/block/src/Entity/Block.php @@ -33,8 +33,7 @@ * admin_permission = "administer blocks", * fieldable = FALSE, * entity_keys = { - * "id" = "id", - * "label" = "label" + * "id" = "id" * }, * links = { * "delete-form" = "block.admin_block_delete", @@ -135,25 +134,6 @@ public function label() { } /** - * {@inheritdoc} - */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'theme', - 'region', - 'weight', - 'plugin', - 'settings', - 'visibility', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** * Sorts active blocks by weight; sorts inactive blocks by name. */ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) { diff --git a/core/modules/block/src/Tests/BlockStorageUnitTest.php b/core/modules/block/src/Tests/BlockStorageUnitTest.php index 65d67f6..ab5496c 100644 --- a/core/modules/block/src/Tests/BlockStorageUnitTest.php +++ b/core/modules/block/src/Tests/BlockStorageUnitTest.php @@ -90,13 +90,15 @@ protected function createTests() { // Ensure that default values are filled in. $expected_properties = array( - 'id' => 'test_block', - 'weight' => NULL, - 'status' => TRUE, 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->id, + 'status' => TRUE, 'dependencies' => array('module' => array('block_test'), 'theme' => array('stark')), + 'id' => 'test_block', 'theme' => 'stark', 'region' => '-1', + 'weight' => NULL, + 'provider' => NULL, + 'visibility' => NULL, 'plugin' => 'test_html', 'settings' => array( 'id' => 'test_html', @@ -108,8 +110,8 @@ protected function createTests() { 'contexts' => array(), ), ), - 'visibility' => NULL, ); + $this->assertIdentical($actual_properties, $expected_properties); $this->assertTrue($entity->getPlugin() instanceof TestHtmlBlock, 'The entity has an instance of the correct block plugin.'); diff --git a/core/modules/block_content/config/schema/block_content.schema.yml b/core/modules/block_content/config/schema/block_content.schema.yml index d241494..2e7c338 100644 --- a/core/modules/block_content/config/schema/block_content.schema.yml +++ b/core/modules/block_content/config/schema/block_content.schema.yml @@ -4,6 +4,12 @@ block_content.type.*: type: config_entity label: 'Custom block type settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' revision: type: integer label: 'Create new revision' diff --git a/core/modules/breakpoint/config/schema/breakpoint.schema.yml b/core/modules/breakpoint/config/schema/breakpoint.schema.yml index 4a66914..c44ef4c 100644 --- a/core/modules/breakpoint/config/schema/breakpoint.schema.yml +++ b/core/modules/breakpoint/config/schema/breakpoint.schema.yml @@ -3,6 +3,12 @@ breakpoint.breakpoint.*.*.*: type: config_entity label: 'Defines the Breakpoint entity' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' name: type: string label: 'Machine name' @@ -29,6 +35,12 @@ breakpoint.breakpoint_group.*.*.*: type: config_entity label: 'Breakpoint group settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' name: type: string label: 'Machine name' diff --git a/core/modules/breakpoint/src/Entity/BreakpointGroup.php b/core/modules/breakpoint/src/Entity/BreakpointGroup.php index 02d6e29..0b585e2 100644 --- a/core/modules/breakpoint/src/Entity/BreakpointGroup.php +++ b/core/modules/breakpoint/src/Entity/BreakpointGroup.php @@ -214,29 +214,6 @@ public function getBreakpointById($id) { /** * {@inheritdoc} */ - public function toArray() { - $names = array( - 'id', - 'uuid', - 'name', - 'label', - 'breakpoint_ids', - 'source', - 'sourceType', - 'status', - 'langcode', - 'dependencies', - ); - $properties = array(); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { parent::calculateDependencies(); diff --git a/core/modules/config/src/Tests/ConfigDiffTest.php b/core/modules/config/src/Tests/ConfigDiffTest.php index 03902e4..fc9dc40 100644 --- a/core/modules/config/src/Tests/ConfigDiffTest.php +++ b/core/modules/config/src/Tests/ConfigDiffTest.php @@ -111,11 +111,12 @@ function testDiff() { $diff = \Drupal::service('config.manager')->diff($active, $staging, 'config_test.dynamic.' . $new_test_entity_id, $config_name); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'change', 'The second item in the diff is a copy.'); - $this->assertEqual($edits[0]->orig, array('id: ' . $new_test_entity_id)); - $this->assertEqual($edits[0]->closing, array('id: ' . $test_entity_id)); - $this->assertEqual($edits[1]->type, 'copy', 'The second item in the diff is a copy.'); - $this->assertEqual(count($edits), 2, 'There are two items in the diff.'); + $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.'); + $this->assertEqual($edits[1]->type, 'change', 'The second item in the diff is a change.'); + $this->assertEqual($edits[1]->orig, array('id: ' . $new_test_entity_id)); + $this->assertEqual($edits[1]->closing, array('id: ' . $test_entity_id)); + $this->assertEqual($edits[2]->type, 'copy', 'The third item in the diff is a copy.'); + $this->assertEqual(count($edits), 3, 'There are three items in the diff.'); } /** diff --git a/core/modules/config/src/Tests/ConfigEntityTest.php b/core/modules/config/src/Tests/ConfigEntityTest.php index fc079f4..4a1bd1b 100644 --- a/core/modules/config/src/Tests/ConfigEntityTest.php +++ b/core/modules/config/src/Tests/ConfigEntityTest.php @@ -46,7 +46,6 @@ function testCRUD() { $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->id; // Verify default properties on a newly created empty entity. $empty = entity_create('config_test'); - $this->assertIdentical($empty->id, NULL); $this->assertTrue($empty->uuid); $this->assertIdentical($empty->label, NULL); $this->assertIdentical($empty->style, NULL); @@ -105,7 +104,6 @@ function testCRUD() { 'label' => $this->randomString(), 'style' => $this->randomName(), )); - $this->assertIdentical($config_test->id, $expected['id']); $this->assertTrue($config_test->uuid); $this->assertNotEqual($config_test->uuid, $empty->uuid); $this->assertIdentical($config_test->label, $expected['label']); @@ -159,7 +157,7 @@ function testCRUD() { try { $id_length_config_test->save(); $this->pass(String::format("config_test entity with ID length @length was saved.", array( - '@length' => strlen($id_length_config_test->id)) + '@length' => strlen($id_length_config_test->id())) )); } catch (ConfigEntityIdLengthException $e) { @@ -173,7 +171,7 @@ function testCRUD() { try { $id_length_config_test->save(); $this->pass(String::format("config_test entity with ID length @length was saved.", array( - '@length' => strlen($id_length_config_test->id), + '@length' => strlen($id_length_config_test->id()), ))); } catch (ConfigEntityIdLengthException $e) { @@ -187,13 +185,13 @@ function testCRUD() { try { $status = $id_length_config_test->save(); $this->fail(String::format("config_test entity with ID length @length exceeding the maximum allowed length of @max saved successfully", array( - '@length' => strlen($id_length_config_test->id), + '@length' => strlen($id_length_config_test->id()), '@max' => static::MAX_ID_LENGTH, ))); } catch (ConfigEntityIdLengthException $e) { $this->pass(String::format("config_test entity with ID length @length exceeding the maximum allowed length of @max failed to save", array( - '@length' => strlen($id_length_config_test->id), + '@length' => strlen($id_length_config_test->id()), '@max' => static::MAX_ID_LENGTH, ))); } @@ -221,7 +219,7 @@ function testCRUD() { $this->assertIdentical($config_test->getOriginalId(), $old_id); // Rename. - $config_test->id = $new_id; + $config_test->set('id', $new_id); $this->assertIdentical($config_test->id(), $new_id); $status = $config_test->save(); $this->assertIdentical($status, SAVED_UPDATED); diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/src/Tests/ConfigImportUITest.php index b95a666..6f3bb2c 100644 --- a/core/modules/config/src/Tests/ConfigImportUITest.php +++ b/core/modules/config/src/Tests/ConfigImportUITest.php @@ -56,15 +56,15 @@ function testImport() { // Create new config entity. $original_dynamic_data = array( + 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', + 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->id, + 'status' => TRUE, + 'dependencies' => array(), 'id' => 'new', 'label' => 'New', 'weight' => 0, 'style' => '', 'test_dependencies' => array(), - 'status' => TRUE, - 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', - 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->id, - 'dependencies' => array(), 'protected_property' => '', ); $staging->write($dynamic_name, $original_dynamic_data); @@ -349,31 +349,31 @@ function testImportErrorLog() { $uuid = $this->container->get('uuid'); $values_primary = array( + 'uuid' => $uuid->generate(), + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => array(), 'id' => 'primary', 'label' => 'Primary', 'weight' => 0, 'style' => NULL, 'test_dependencies' => array(), - 'status' => TRUE, - 'uuid' => $uuid->generate(), - 'langcode' => 'en', - 'dependencies' => array(), 'protected_property' => null, ); $staging->write($name_primary, $values_primary); $values_secondary = array( - 'id' => 'secondary', - 'label' => 'Secondary Sync', - 'weight' => 0, - 'style' => NULL, - 'test_dependencies' => array(), - 'status' => TRUE, 'uuid' => $uuid->generate(), 'langcode' => 'en', + 'status' => TRUE, // Add a dependency on primary, to ensure that is synced first. 'dependencies' => array( 'entity' => array($name_primary), ), + 'id' => 'secondary', + 'label' => 'Secondary Sync', + 'weight' => 0, + 'style' => NULL, + 'test_dependencies' => array(), 'protected_property' => null, ); $staging->write($name_secondary, $values_secondary); diff --git a/core/modules/config/src/Tests/ConfigImporterTest.php b/core/modules/config/src/Tests/ConfigImporterTest.php index 21ce402..ca4d704 100644 --- a/core/modules/config/src/Tests/ConfigImporterTest.php +++ b/core/modules/config/src/Tests/ConfigImporterTest.php @@ -170,15 +170,15 @@ function testNew() { // Create new config entity. $original_dynamic_data = array( + 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', + 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->id, + 'status' => TRUE, + 'dependencies' => array(), 'id' => 'new', 'label' => 'New', 'weight' => 0, 'style' => '', 'test_dependencies' => array(), - 'status' => TRUE, - 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', - 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->id, - 'dependencies' => array(), 'protected_property' => '', ); $staging->write($dynamic_name, $original_dynamic_data); diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index 14161bb..ca5eaba 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -135,12 +135,8 @@ function testSchemaMapping() { $expected['label'] = 'Image style'; $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; $expected['mapping']['name']['type'] = 'string'; - $expected['mapping']['id']['label'] = 'ID'; - $expected['mapping']['id']['type'] = 'string'; $expected['mapping']['uuid']['type'] = 'string'; $expected['mapping']['uuid']['label'] = 'UUID'; - $expected['mapping']['label']['type'] = 'label'; - $expected['mapping']['label']['label'] = 'Label'; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Default language'; $expected['mapping']['status']['type'] = 'boolean'; @@ -148,6 +144,8 @@ function testSchemaMapping() { $expected['mapping']['dependencies']['type'] = 'config_dependencies'; $expected['mapping']['dependencies']['label'] = 'Dependencies'; $expected['mapping']['name']['type'] = 'string'; + $expected['mapping']['label']['type'] = 'label'; + $expected['mapping']['label']['label'] = 'Label'; $expected['mapping']['effects']['type'] = 'sequence'; $expected['mapping']['effects']['sequence'][0]['type'] = 'mapping'; $expected['mapping']['effects']['sequence'][0]['mapping']['id']['type'] = 'string'; diff --git a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml index 6a585d3..904fb69 100644 --- a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml +++ b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml @@ -1,12 +1,11 @@ # Schema for the configuration files of the Configuration Test module. -config_test.dynamic.*: - type: mapping - label: 'Config test entity' +config_test_dynamic: + type: config_entity mapping: id: type: string - label: 'Machine name' + label: 'ID' label: type: label label: 'Label' @@ -15,20 +14,10 @@ config_test.dynamic.*: label: 'Weight' style: type: string - label: 'Image style' - protected_property: - type: string - label: 'Protected property' - -config_test_dynamic: - type: config_entity - mapping: - weight: - type: integer - label: 'Weight' - style: - type: string label: 'style' + test_dependencies: + type: config_dependencies + label: 'Configuration dependencies' protected_property: type: string label: 'Protected property' @@ -41,6 +30,24 @@ config_test.dynamic.*.*: type: config_test_dynamic label: 'Config test dynamic settings' +config_test.query.*: + type: config_entity + mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' + array: + type: sequence + label: 'Array' + sequence: + - type: string + number: + type: integer + label: 'number' + config_test.types: type: mapping label: 'Configuration type' diff --git a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php index 07ec50a..b5f2dea 100644 --- a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php +++ b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php @@ -48,7 +48,7 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface { * * @var string */ - public $id; + protected $id; /** * The human-readable name of the configuration entity. @@ -86,20 +86,6 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface { protected $protected_property; /** - * {@inheritdoc} - */ - public function toArray() { - $properties = parent::toArray(); - $protected_names = array( - 'protected_property', - ); - foreach ($protected_names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::sort(). */ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) { diff --git a/core/modules/contact/config/schema/contact.schema.yml b/core/modules/contact/config/schema/contact.schema.yml index 5443bf3..0ef4c2e 100644 --- a/core/modules/contact/config/schema/contact.schema.yml +++ b/core/modules/contact/config/schema/contact.schema.yml @@ -4,6 +4,12 @@ contact.category.*: type: config_entity label: 'Contact category' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' recipients: type: sequence label: 'Recipients' diff --git a/core/modules/editor/src/Entity/Editor.php b/core/modules/editor/src/Entity/Editor.php index d555db7..29f7350 100644 --- a/core/modules/editor/src/Entity/Editor.php +++ b/core/modules/editor/src/Entity/Editor.php @@ -176,21 +176,4 @@ public function setImageUploadSettings(array $image_upload_settings) { return $this; } - /** - * {@inheritdoc} - */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'format', - 'editor', - 'settings', - 'image_upload', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - } diff --git a/core/modules/entity/config/schema/entity.schema.yml b/core/modules/entity/config/schema/entity.schema.yml index 4583093..074d82a 100644 --- a/core/modules/entity/config/schema/entity.schema.yml +++ b/core/modules/entity/config/schema/entity.schema.yml @@ -33,6 +33,12 @@ entity.form_mode.*.*: type: config_entity label: 'Entity form mode settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' targetEntityType: type: string label: 'Target entity type' @@ -45,6 +51,12 @@ entity.view_display.*.*.*: type: config_entity label: 'Entity display' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' targetEntityType: type: string label: 'Target entity type' @@ -71,6 +83,9 @@ entity.form_display.*.*.*: type: config_entity label: 'Entity form display' mapping: + id: + type: string + label: 'ID' targetEntityType: type: string label: 'Target entity type' @@ -80,9 +95,12 @@ entity.form_display.*.*.*: mode: type: string label: 'View or form mode machine name' + status: + type: boolean + label: 'Enabled' content: type: sequence - label: 'Field form display formatters' + label: 'Field display formatters' sequence: - type: entity_form_display.field.[type] hidden: @@ -91,6 +109,9 @@ entity.form_display.*.*.*: sequence: - type: boolean label: 'Component' + dependencies: + type: config_dependencies + label: 'Dependencies' # Default schema for entity display field with undefined type. entity_view_display.field.*: diff --git a/core/modules/entity/src/EntityDisplayBase.php b/core/modules/entity/src/EntityDisplayBase.php index 34dc815..a9b99d2 100644 --- a/core/modules/entity/src/EntityDisplayBase.php +++ b/core/modules/entity/src/EntityDisplayBase.php @@ -200,23 +200,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { * {@inheritdoc} */ public function toArray() { - $names = array( - 'uuid', - 'targetEntityType', - 'bundle', - 'mode', - 'content', - 'hidden', - 'status', - 'dependencies' - ); - $properties = array( - 'id' => $this->id(), - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - + $properties = parent::toArray(); // Do not store options for fields whose display is not set to be // configurable. foreach ($this->getFieldDefinitions() as $field_name => $definition) { diff --git a/core/modules/field/config/schema/field.schema.yml b/core/modules/field/config/schema/field.schema.yml index ff871bf..a00c89e 100644 --- a/core/modules/field/config/schema/field.schema.yml +++ b/core/modules/field/config/schema/field.schema.yml @@ -12,6 +12,9 @@ field.field.*.*: type: config_entity label: 'Field' mapping: + id: + type: string + label: 'ID' name: type: string label: 'Name' @@ -49,6 +52,12 @@ field.instance.*.*.*: type: config_entity label: 'Field instance' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' field_uuid: type: string label: 'Field UUID' diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php index f25af7b..846fe70 100644 --- a/core/modules/field/src/Entity/FieldConfig.php +++ b/core/modules/field/src/Entity/FieldConfig.php @@ -227,34 +227,6 @@ public function id() { } /** - * {@inheritdoc} - */ - public function toArray() { - $names = array( - 'uuid', - 'status', - 'langcode', - 'name', - 'entity_type', - 'type', - 'settings', - 'module', - 'locked', - 'cardinality', - 'translatable', - 'indexes', - 'dependencies', - ); - $properties = array( - 'id' => $this->id(), - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** * Overrides \Drupal\Core\Entity\Entity::preSave(). * * @throws \Drupal\field\FieldException @@ -730,7 +702,10 @@ public function entityCount($as_bool = FALSE) { */ public function __sleep() { // Only serialize properties from self::toArray(). - return array_keys(array_intersect_key($this->toArray(), get_object_vars($this))); + $properties = array_keys(array_intersect_key($this->toArray(), get_object_vars($this))); + // Serialize $entityTypeId property so that toArray() works when waking up. + $properties[] = 'entityTypeId'; + return $properties; } /** diff --git a/core/modules/field/src/Entity/FieldInstanceConfig.php b/core/modules/field/src/Entity/FieldInstanceConfig.php index bf8e354..f5730c0 100644 --- a/core/modules/field/src/Entity/FieldInstanceConfig.php +++ b/core/modules/field/src/Entity/FieldInstanceConfig.php @@ -274,29 +274,7 @@ public function id() { * {@inheritdoc} */ public function toArray() { - $names = array( - 'uuid', - 'status', - 'langcode', - 'field_uuid', - 'field_name', - 'entity_type', - 'bundle', - 'label', - 'description', - 'required', - 'default_value', - 'default_value_function', - 'settings', - 'dependencies', - ); - $properties = array( - 'id' => $this->id(), - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - + $properties = parent::toArray(); // Additionally, include the field type, that is needed to be able to // generate the field-type-dependant parts of the config schema. $properties['field_type'] = $this->getType(); @@ -674,7 +652,10 @@ public function targetBundle() { */ public function __sleep() { // Only serialize properties from self::toArray(). - return array_keys(array_intersect_key($this->toArray(), get_object_vars($this))); + $properties = array_keys(array_intersect_key($this->toArray(), get_object_vars($this))); + // Serialize $entityTypeId property so that toArray() works when waking up. + $properties[] = 'entityTypeId'; + return $properties; } /** diff --git a/core/modules/field/tests/src/FieldInstanceConfigEntityUnitTest.php b/core/modules/field/tests/src/FieldInstanceConfigEntityUnitTest.php index ca06aab..450b20f 100644 --- a/core/modules/field/tests/src/FieldInstanceConfigEntityUnitTest.php +++ b/core/modules/field/tests/src/FieldInstanceConfigEntityUnitTest.php @@ -64,14 +64,18 @@ public static function getInfo() { */ public function setUp() { $this->entityTypeId = $this->randomName(); + $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface'); $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface'); + $this->typedConfigManager = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface'); + $container = new ContainerBuilder(); $container->set('entity.manager', $this->entityManager); $container->set('uuid', $this->uuid); + $container->set('config.typed', $this->typedConfigManager); \Drupal::setContainer($container); // Create a mock FieldConfig object. @@ -139,12 +143,12 @@ public function testCalculateDependencies() { */ public function testToArray() { $values = array('field_name' => $this->field->getName(), 'entity_type' => 'test_entity_type', 'bundle' => 'test_bundle'); - $instance = new FieldInstanceConfig($values); - $export = $instance->toArray(); + $instance = new FieldInstanceConfig($values, $this->entityTypeId); + $expected = array( 'id' => 'test_entity_type.test_bundle.field_test', 'uuid' => NULL, - 'status' => 1, + 'status' => TRUE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'field_uuid' => NULL, 'field_name' => 'field_test', @@ -159,6 +163,19 @@ public function testToArray() { 'dependencies' => array(), 'field_type' => 'test_field', ); + $this->entityManager->expects($this->any()) + ->method('getDefinition') + ->with($this->entityTypeId) + ->will($this->returnValue($this->entityType)); + $this->entityType->expects($this->once()) + ->method('getKey') + ->with('id') + ->will($this->returnValue('id')); + $this->typedConfigManager->expects($this->once()) + ->method('getDefinition') + ->will($this->returnValue(array('mapping' => array_fill_keys(array_keys($expected), '')))); + + $export = $instance->toArray(); $this->assertEquals($expected, $export); } } diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php index 9598f77..944d5c7 100644 --- a/core/modules/filter/src/Entity/FilterFormat.php +++ b/core/modules/filter/src/Entity/FilterFormat.php @@ -162,13 +162,9 @@ public function setFilterConfig($instance_id, array $configuration) { */ public function toArray() { $properties = parent::toArray(); - // @todo Make self::$weight and self::$cache protected and add them here. - $names = array( - 'filters', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } + // The 'roles' property is only used during install and should never + // actually be saved. + unset($properties['roles']); return $properties; } diff --git a/core/modules/image/config/schema/image.schema.yml b/core/modules/image/config/schema/image.schema.yml index 8248696..2985696 100644 --- a/core/modules/image/config/schema/image.schema.yml +++ b/core/modules/image/config/schema/image.schema.yml @@ -6,6 +6,9 @@ image.style.*: mapping: name: type: string + label: + type: label + label: 'Label' effects: type: sequence sequence: diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php index 0338767..ad415a9 100644 --- a/core/modules/image/src/Entity/ImageStyle.php +++ b/core/modules/image/src/Entity/ImageStyle.php @@ -357,20 +357,6 @@ public function addImageEffect(array $configuration) { /** * {@inheritdoc} */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'effects', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function getReplacementID() { return $this->get('replacementID'); } diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml index 584a715..210a1e6 100644 --- a/core/modules/language/config/schema/language.schema.yml +++ b/core/modules/language/config/schema/language.schema.yml @@ -85,6 +85,12 @@ language.entity.*: type: config_entity label: 'Language' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' direction: type: integer label: 'Direction' diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php index 5adea09..c892ccb 100644 --- a/core/modules/migrate/src/Entity/Migration.php +++ b/core/modules/migrate/src/Entity/Migration.php @@ -339,4 +339,18 @@ public function checkRequirements() { return TRUE; } + /** + * {@inheritdoc} + */ + public function toArray() { + // @todo Remove once migration config entities have schema + // https://drupal.org/node/2183957. + $class_info = new \ReflectionClass($this); + foreach ($class_info->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { + $name = $property->getName(); + $properties[$name] = $this->get($name); + } + return $properties; + } + } diff --git a/core/modules/rdf/config/schema/rdf.schema.yml b/core/modules/rdf/config/schema/rdf.schema.yml index 75b83ed..ac452a3 100644 --- a/core/modules/rdf/config/schema/rdf.schema.yml +++ b/core/modules/rdf/config/schema/rdf.schema.yml @@ -4,6 +4,9 @@ rdf.mapping.*.*: type: config_entity label: 'RDF mapping' mapping: + id: + type: string + label: 'ID' targetEntityType: type: string label: 'Target entity type' diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php index e5783b7..76607ec 100644 --- a/core/modules/rdf/src/Entity/RdfMapping.php +++ b/core/modules/rdf/src/Entity/RdfMapping.php @@ -136,30 +136,6 @@ public function id() { /** * {@inheritdoc} */ - public function toArray() { - $names = array( - 'uuid', - 'targetEntityType', - 'bundle', - 'types', - 'fieldMappings', - ); - $properties = array( - 'id' => $this->id(), - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - if (!empty($this->dependencies)) { - // Add protected dependencies property if set. - $properties['dependencies'] = $this->dependencies; - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { parent::calculateDependencies(); $entity_type = \Drupal::entityManager()->getDefinition($this->targetEntityType); diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php index d94d376..4a9a369 100644 --- a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php +++ b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php @@ -189,24 +189,6 @@ public function hasMappings() { /** * {@inheritdoc} */ - public function toArray() { - $names = array( - 'id', - 'uuid', - 'label', - 'mappings', - 'breakpointGroup', - ); - $properties = array(); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function setMappings(array $mappings) { $this->set('mappings', $mappings); return $this; diff --git a/core/modules/search/config/schema/search.schema.yml b/core/modules/search/config/schema/search.schema.yml index d4114e2..3be192c 100644 --- a/core/modules/search/config/schema/search.schema.yml +++ b/core/modules/search/config/schema/search.schema.yml @@ -68,6 +68,12 @@ search.page.*: type: config_entity label: 'Search page' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' path: type: string label: 'Search page path' diff --git a/core/modules/search/src/Entity/SearchPage.php b/core/modules/search/src/Entity/SearchPage.php index f1b92cd..7341221 100644 --- a/core/modules/search/src/Entity/SearchPage.php +++ b/core/modules/search/src/Entity/SearchPage.php @@ -169,23 +169,6 @@ public function getWeight() { /** * {@inheritdoc} */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'path', - 'weight', - 'plugin', - 'configuration', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function postCreate(EntityStorageInterface $storage) { parent::postCreate($storage); diff --git a/core/modules/shortcut/config/schema/shortcut.schema.yml b/core/modules/shortcut/config/schema/shortcut.schema.yml index 0162d80..daef434 100644 --- a/core/modules/shortcut/config/schema/shortcut.schema.yml +++ b/core/modules/shortcut/config/schema/shortcut.schema.yml @@ -4,6 +4,12 @@ shortcut.set.*: type: config_entity label: 'Shortcut settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' links: type: sequence label: 'Shortcuts' diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index c3e3bc3..5375524 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -118,6 +118,12 @@ system.date_format.*: type: config_entity label: 'Date format' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' locked: type: boolean label: 'Locked' @@ -278,6 +284,12 @@ system.menu.*: type: config_entity label: 'Menu' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' description: type: label label: 'Menu description' @@ -289,6 +301,12 @@ system.action.*: type: config_entity label: 'System action' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' type: type: string label: 'Type' diff --git a/core/modules/system/src/Entity/Action.php b/core/modules/system/src/Entity/Action.php index 642933a..e48f335 100644 --- a/core/modules/system/src/Entity/Action.php +++ b/core/modules/system/src/Entity/Action.php @@ -148,20 +148,4 @@ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) return parent::sort($a, $b); } - /** - * {@inheritdoc} - */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'type', - 'plugin', - 'configuration', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - } diff --git a/core/modules/system/src/Entity/DateFormat.php b/core/modules/system/src/Entity/DateFormat.php index 1016fbc..a7d689d 100644 --- a/core/modules/system/src/Entity/DateFormat.php +++ b/core/modules/system/src/Entity/DateFormat.php @@ -71,21 +71,6 @@ class DateFormat extends ConfigEntityBase implements DateFormatInterface { /** * {@inheritdoc} */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'locked', - 'pattern', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function getPattern() { return $this->pattern; } diff --git a/core/modules/system/src/Entity/Menu.php b/core/modules/system/src/Entity/Menu.php index 2ea8dd1..756728f 100644 --- a/core/modules/system/src/Entity/Menu.php +++ b/core/modules/system/src/Entity/Menu.php @@ -60,22 +60,6 @@ class Menu extends ConfigEntityBase implements MenuInterface { /** * {@inheritdoc} */ - public function toArray() { - $properties = parent::toArray(); - // @todo Make $description protected and include it here, see - // https://drupal.org/node/2030645. - $names = array( - 'locked', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function isLocked() { return (bool) $this->locked; } diff --git a/core/modules/tour/config/schema/tour.schema.yml b/core/modules/tour/config/schema/tour.schema.yml index d277cfe..5d0d85e 100644 --- a/core/modules/tour/config/schema/tour.schema.yml +++ b/core/modules/tour/config/schema/tour.schema.yml @@ -4,6 +4,12 @@ tour.tour.*: type: config_entity label: 'Tour settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' module: type: string label: 'Providing module' diff --git a/core/modules/tour/src/Entity/Tour.php b/core/modules/tour/src/Entity/Tour.php index 1361942..d8271ac 100644 --- a/core/modules/tour/src/Entity/Tour.php +++ b/core/modules/tour/src/Entity/Tour.php @@ -123,21 +123,6 @@ public function getTips() { /** * {@inheritdoc} */ - public function toArray() { - $properties = parent::toArray(); - $names = array( - 'routes', - 'tips', - ); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function hasMatchingRoute($route_name, $route_params) { if (!isset($this->keyedRoutes)) { $this->keyedRoutes = array(); diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml index 44762ed..69600fd 100644 --- a/core/modules/user/config/schema/user.schema.yml +++ b/core/modules/user/config/schema/user.schema.yml @@ -119,6 +119,12 @@ user.role.*: type: config_entity label: 'User role settings' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' weight: type: integer label: 'User role weight' diff --git a/core/modules/views/config/schema/views.schema.yml b/core/modules/views/config/schema/views.schema.yml index fba3ce4..8b837c2 100644 --- a/core/modules/views/config/schema/views.schema.yml +++ b/core/modules/views/config/schema/views.schema.yml @@ -72,6 +72,12 @@ views.view.*: type: config_entity label: 'View' mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' module: type: string label: 'Module' diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index db5ba76..00098b88 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -243,32 +243,6 @@ public function &getDisplay($display_id) { /** * {@inheritdoc} */ - public function toArray() { - $names = array( - 'base_field', - 'base_table', - 'core', - 'description', - 'status', - 'display', - 'label', - 'module', - 'id', - 'tag', - 'uuid', - 'langcode', - 'dependencies', - ); - $properties = array(); - foreach ($names as $name) { - $properties[$name] = $this->get($name); - } - return $properties; - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { parent::calculateDependencies(); diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php index 4f718fc..a824b3a 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php @@ -86,6 +86,13 @@ class ConfigEntityBaseUnitTest extends UnitTestCase { protected $cacheBackend; /** + * The mocked typed config manager. + * + * @var \Drupal\Core\Config\TypedConfigManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $typedConfigManager; + + /** * {@inheritdoc} */ public static function getInfo() { @@ -129,11 +136,14 @@ public function setUp() { $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); + $this->typedConfigManager = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface'); + $container = new ContainerBuilder(); $container->set('entity.manager', $this->entityManager); $container->set('uuid', $this->uuid); $container->set('language_manager', $this->languageManager); $container->set('cache.test', $this->cacheBackend); + $container->set('config.typed', $this->typedConfigManager); $container->setParameter('cache_bins', array('cache.test' => 'test')); \Drupal::setContainer($container); @@ -431,14 +441,21 @@ public function testSort() { * @covers ::toArray */ public function testToArray() { + $this->typedConfigManager->expects($this->once()) + ->method('getDefinition') + ->will($this->returnValue(array('mapping' => array('id' => '', 'dependencies' => '')))); $properties = $this->entity->toArray(); $this->assertInternalType('array', $properties); - $class_info = new \ReflectionClass($this->entity); - foreach ($class_info->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { - $name = $property->getName(); - $this->assertArrayHasKey($name, $properties); - $this->assertSame($this->entity->get($name), $properties[$name]); - } + $this->assertEquals(array('id' => $this->entity->id(), 'dependencies' => array()), $properties); + } + + /** + * @covers ::toArray + * + * @expectedException \Drupal\Core\Config\Schema\SchemaIncompleteException + */ + public function testToArrayFallback() { + $this->entity->toArray(); } } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php index 37019f5..12c4823 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php @@ -98,6 +98,13 @@ class ConfigEntityStorageTest extends UnitTestCase { protected $cacheBackend; /** + * The mocked typed config manager. + * + * @var \Drupal\Core\Config\TypedConfigManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $typedConfigManager; + + /** * {@inheritdoc} */ public static function getInfo() { @@ -167,8 +174,13 @@ protected function setUp() { $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); + $this->typedConfigManager = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface'); + $this->typedConfigManager->expects($this->any()) + ->method('getDefinition') + ->will($this->returnValue(array('mapping' => array('id' => '', 'uuid' => '', 'dependencies' => '')))); $container = new ContainerBuilder(); $container->set('entity.manager', $this->entityManager); + $container->set('config.typed', $this->typedConfigManager); $container->set('cache.test', $this->cacheBackend); $container->setParameter('cache_bins', array('cache.test' => 'test')); \Drupal::setContainer($container); @@ -242,7 +254,7 @@ public function testSaveInsert(EntityInterface $entity) { $config_object->expects($this->atLeastOnce()) ->method('isNew') ->will($this->returnValue(TRUE)); - $config_object->expects($this->exactly(4)) + $config_object->expects($this->exactly(3)) ->method('set'); $config_object->expects($this->once()) ->method('save'); @@ -301,7 +313,7 @@ public function testSaveUpdate(EntityInterface $entity) { $config_object->expects($this->atLeastOnce()) ->method('isNew') ->will($this->returnValue(FALSE)); - $config_object->expects($this->exactly(4)) + $config_object->expects($this->exactly(3)) ->method('set'); $config_object->expects($this->once()) ->method('save'); @@ -361,7 +373,7 @@ public function testSaveRename(ConfigEntityInterface $entity) { $config_object->expects($this->atLeastOnce()) ->method('isNew') ->will($this->returnValue(FALSE)); - $config_object->expects($this->exactly(4)) + $config_object->expects($this->exactly(3)) ->method('set'); $config_object->expects($this->once()) ->method('save');