diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 95d6658..4ab0fd7 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -87,12 +87,22 @@ color_hex: # Complex extended data types: # Root of a configuration object. + +_core_config_info: + type: mapping + mapping: + default_config_hash: + type: string + label: 'Default configuration hash' + config_object: type: mapping mapping: langcode: type: string label: 'Language code' + _core: + type: _core_config_info # Mail text with subject and body parts. mail: @@ -281,9 +291,8 @@ config_entity: label: 'Third party settings' sequence: type: '[%parent.%parent.%type].third_party.[%key]' - default_config_hash: - type: string - label: 'Default configuration hash' + _core: + type: _core_config_info block_settings: type: mapping diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index b34dc80..04f517d 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -280,6 +280,9 @@ protected function createConfiguration($collection, array $config_to_create) { } if ($config_to_create[$name] !== FALSE) { $new_config->setData($config_to_create[$name]); + if (!$this->isSyncing()) { + $new_config->set('_core.default_config_hash', Crypt::hashBase64(serialize($config_to_create[$name]))); + } } if ($collection == StorageInterface::DEFAULT_COLLECTION && $entity_type = $this->configManager->getEntityTypeIdByName($name)) { // If we are syncing do not create configuration entities. Pluggable @@ -306,10 +309,7 @@ protected function createConfiguration($collection, array $config_to_create) { $entity = $entity_storage->createFromStorageRecord($new_config->get()); } if ($entity->isInstallable()) { - $entity - ->set('default_config_hash', Crypt::hashBase64(serialize($new_config->get()))) - ->trustData() - ->save(); + $entity->trustData()->save(); } } else { diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 70144d2..8c0c376 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -104,9 +104,15 @@ protected $third_party_settings = array(); /** - * @var string + * Information maintained by Drupal core about configuration. + * + * Keys: + * - default_config_hash: A hash calculated by the config.installer service + * and added during installation. + * + * @var array */ - protected $default_config_hash = ''; + protected $_core = []; /** * Trust supplied data and not use configuration schema on save. @@ -301,8 +307,8 @@ public function toArray() { if (empty($this->third_party_settings)) { unset($properties['third_party_settings']); } - if (empty($this->default_config_hash)) { - unset($properties['default_config_hash']); + if (empty($this->_core)) { + unset($properties['_core']); } return $properties; } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php index b29f803..785b314 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php @@ -157,7 +157,7 @@ public function getPropertiesToExport() { 'status' => 'status', 'dependencies' => 'dependencies', 'third_party_settings' => 'third_party_settings', - 'default_config_hash' => 'default_config_hash', + '_core' => '_core', ]; foreach ($this->config_export as $property => $name) { if (is_numeric($property)) { diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index 3c7980c..8735db1 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -63,6 +63,7 @@ function testSchemaMapping() { $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['mapping']['testitem'] = array('label' => 'Test item'); $expected['mapping']['testlist'] = array('label' => 'Test list'); $expected['type'] = 'config_schema_test.someschema'; @@ -106,6 +107,7 @@ function testSchemaMapping() { 'label' => 'Language code', 'type' => 'string', ); + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['type'] = 'system.maintenance'; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance'); @@ -120,6 +122,7 @@ function testSchemaMapping() { 'type' => 'string', 'label' => 'Language code', ); + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['mapping']['label'] = array( 'label' => 'Label', 'type' => 'label', @@ -179,8 +182,7 @@ function testSchemaMapping() { $expected['mapping']['third_party_settings']['type'] = 'sequence'; $expected['mapping']['third_party_settings']['label'] = 'Third party settings'; $expected['mapping']['third_party_settings']['sequence']['type'] = '[%parent.%parent.%type].third_party.[%key]'; - $expected['mapping']['default_config_hash']['type'] = 'string'; - $expected['mapping']['default_config_hash']['label'] = 'Default configuration hash'; + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['type'] = 'image.style.*'; $this->assertEqual($definition, $expected); @@ -233,6 +235,7 @@ function testSchemaMapping() { $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['mapping']['testid']['type'] = 'string'; $expected['mapping']['testid']['label'] = 'ID'; $expected['mapping']['testdescription']['type'] = 'text'; @@ -388,7 +391,9 @@ public function testConfigSaveWithSchema() { $extension_path = drupal_get_path('module', 'config_schema_test'); $install_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY); $original_data = $install_storage->read('config_schema_test.ignore'); - $this->assertIdentical($this->config('config_schema_test.ignore')->get(), $original_data); + $installed_data = $this->config('config_schema_test.ignore')->get(); + unset($installed_data['_core']); + $this->assertIdentical($installed_data, $original_data); } /** @@ -403,6 +408,7 @@ function testSchemaFallback() { $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; + $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['mapping']['testid']['type'] = 'string'; $expected['mapping']['testid']['label'] = 'ID'; $expected['mapping']['testdescription']['type'] = 'text'; diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php index de09fc3..d37c73b 100644 --- a/core/modules/locale/src/LocaleConfigManager.php +++ b/core/modules/locale/src/LocaleConfigManager.php @@ -493,7 +493,7 @@ public function getDefaultConfigLangcode($name) { // language list. $config_entity_type = $this->configManager->getEntityTypeIdByName($name); if (!$config_entity_type || $config_entity_type === 'configurable_language' - || !empty($this->configFactory->get($name)->get('default_config_hash')) + || !empty($this->configFactory->get($name)->get('_core.default_config_hash')) ) { $shipped = $this->defaultConfigStorage->read($name); if (!empty($shipped)) { diff --git a/core/modules/locale/src/Tests/LocaleConfigManagerTest.php b/core/modules/locale/src/Tests/LocaleConfigManagerTest.php index 3e3e697..193f4fa 100644 --- a/core/modules/locale/src/Tests/LocaleConfigManagerTest.php +++ b/core/modules/locale/src/Tests/LocaleConfigManagerTest.php @@ -26,6 +26,13 @@ class LocaleConfigManagerTest extends KernelTestBase { public static $modules = array('system', 'language', 'locale', 'locale_test', 'block'); /** + * This test creates simple config on the fly breaking schema checking. + * + * @var bool + */ + protected $strictConfigSchema = FALSE; + + /** * Tests hasTranslation(). */ public function testHasTranslation() { @@ -74,6 +81,10 @@ public function testGetDefaultConfigLangcode() { \Drupal::service('module_installer')->install(['locale_test_translate']); $this->assertEqual('en', \Drupal::service('locale.config_manager')->getDefaultConfigLangcode('locale_test_translate.settings'), 'After installing a module the locale config manager can get the shipped configuration langcode.'); + $simple_config = \Drupal::configFactory()->getEditable('locale_test_translate.simple_config_extra'); + $simple_config->set('foo', 'bar')->save(); + $this->assertNull(\Drupal::service('locale.config_manager')->getDefaultConfigLangcode($simple_config->getName()), 'Simple config created through the API is not treated as shipped configuration.'); + $block = Block::create(array( 'id' => 'test_default_config', 'theme' => 'classy', @@ -98,7 +109,7 @@ public function testGetDefaultConfigLangcode() { // The test_default_config block provided by the locale_test module will not // be installed because a block with the same ID already exists. $this->installConfig(['locale_test']); - $this->assertEqual(NULL, \Drupal::service('locale.config_manager')->getDefaultConfigLangcode('block.block.test_default_config'), 'The block.block.test_default_config is not shipped configuration.'); + $this->assertNull(\Drupal::service('locale.config_manager')->getDefaultConfigLangcode('block.block.test_default_config'), 'The block.block.test_default_config is not shipped configuration.'); // Delete the block so we can install the one provided by the locale_test // module. $block->delete(); @@ -111,7 +122,7 @@ public function testGetDefaultConfigLangcode() { $this->assertEqual('en', \Drupal::service('locale.config_manager')->getDefaultConfigLangcode('language.entity.fr'), 'The language.entity.fr is treated as shipped configuration because it is a configurable_language config entity and in the standard language list.'); $custom_language = ConfigurableLanguage::createFromLangcode('custom'); $custom_language->save(); - $this->assertEqual(NULL, \Drupal::service('locale.config_manager')->getDefaultConfigLangcode('language.entity.custom'), 'The language.entity.custom is not shipped configuration because it is not in the standard language list.'); + $this->assertNull(\Drupal::service('locale.config_manager')->getDefaultConfigLangcode('language.entity.custom'), 'The language.entity.custom is not shipped configuration because it is not in the standard language list.'); } } diff --git a/core/tests/Drupal/KernelTests/AssertConfigTrait.php b/core/tests/Drupal/KernelTests/AssertConfigTrait.php index 8489ae7..203e85f 100644 --- a/core/tests/Drupal/KernelTests/AssertConfigTrait.php +++ b/core/tests/Drupal/KernelTests/AssertConfigTrait.php @@ -74,15 +74,15 @@ protected function assertConfigDiff(Diff $result, $config_name, array $skipped_c } break; case 'Drupal\Component\Diff\Engine\DiffOpAdd': + // The _core property does not exist in the default config. + if ($op->closing[0] === '_core:') { + continue; + } foreach ($op->closing as $closing) { // The UUIDs don't exist in the default config. if (strpos($closing, 'uuid: ') === 0) { continue; } - // The UUIDs don't exist in the default config. - if (strpos($closing, 'default_config_hash: ') === 0) { - continue; - } throw new \Exception($config_name . ': ' . var_export($op, TRUE)); } break; diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php index 44eae9a..8104efc 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php @@ -163,7 +163,7 @@ public function providerGetPropertiesToExport() { 'status' => 'status', 'dependencies' => 'dependencies', 'third_party_settings' => 'third_party_settings', - 'default_config_hash' => 'default_config_hash', + '_core' => '_core', 'id' => 'id', 'custom_property' => 'customProperty', ],