diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index b3b51c2..76f2c3c 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -208,21 +208,7 @@ public function save() { // Validate the configuration object name before saving. static::validateName($this->name); - // If there is a schema for this configuration object, cast all values to - // conform to the schema. - if ($this->typedConfigManager->hasConfigSchema($this->name)) { - // Ensure that the schema wrapper has the latest data. - $this->schemaWrapper = NULL; - foreach ($this->data as $key => $value) { - $this->data[$key] = $this->castValue($key, $value); - } - } - else { - foreach ($this->data as $key => $value) { - $this->validateValue($key, $value); - } - } - + $this->castData(); $this->storage->write($this->name, $this->data); $this->isNew = FALSE; $this->eventDispatcher->dispatch(ConfigEvents::SAVE, new ConfigCrudEvent($this)); diff --git a/core/lib/Drupal/Core/Config/ConfigCaster.php b/core/lib/Drupal/Core/Config/ConfigCaster.php new file mode 100644 index 0000000..75f52ed --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigCaster.php @@ -0,0 +1,48 @@ +name = $name; + $this->typedConfigManager = $typed_config; + $this->setData($data); + } + + /** + * Saves the configuration object. + * + * @return \Drupal\Core\Config\Config + * The configuration object. + */ + public function save() { + throw new ConfigException('The ConfigCaster has no storage so can not save configuration.'); + } + + /** + * Deletes the configuration object. + * + * @return \Drupal\Core\Config\Config + * The configuration object. + */ + public function delete() { + throw new ConfigException('The ConfigCaster has no storage so can not delete configuration.'); + } + +} diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index a82d184..437ac54 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -124,6 +124,13 @@ public function getConfigFactory() { /** * {@inheritdoc} */ + public function getTypedConfigManager() { + return $this->typedConfigManager; + } + + /** + * {@inheritdoc} + */ public function diff(StorageInterface $source_storage, StorageInterface $target_storage, $source_name, $target_name = NULL, $collection = StorageInterface::DEFAULT_COLLECTION) { if ($collection != StorageInterface::DEFAULT_COLLECTION) { $source_storage = $source_storage->createCollection($collection); diff --git a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php index c0ea6cf..413ed81 100644 --- a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php @@ -40,6 +40,14 @@ public function getEntityManager(); public function getConfigFactory(); /** + * Gets the typed config manager. + * + * @return \Drupal\Core\Config\TypedConfigManagerInterface + * The typed config manager. + */ + public function getTypedConfigManager(); + + /** * Return a formatted diff of a named config between two storages. * * @param \Drupal\Core\Config\StorageInterface $source_storage diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php index 5c6e8b3..ee9b5d2 100644 --- a/core/lib/Drupal/Core/Config/StorableConfigBase.php +++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php @@ -217,4 +217,25 @@ protected function castValue($key, $value) { return $value; } + /** + * Casts the configuration data casted according to the schema. + */ + public function castData() { + // If there is a schema for this configuration object, cast all values to + // conform to the schema. + if ($this->typedConfigManager->hasConfigSchema($this->name)) { + // Ensure that the schema wrapper has the latest data. + $this->schemaWrapper = NULL; + foreach ($this->data as $key => $value) { + $this->data[$key] = $this->castValue($key, $value); + } + } + else { + foreach ($this->data as $key => $value) { + $this->validateValue($key, $value); + } + } + return $this; + } + } diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php index b720abb..caf43b2 100644 --- a/core/lib/Drupal/Core/Config/StorageComparer.php +++ b/core/lib/Drupal/Core/Config/StorageComparer.php @@ -266,7 +266,12 @@ protected function addChangelistUpdate($collection) { $recreates[] = $name; } else { - $this->addChangeList($collection, 'update', array($name)); + // Use the config schema to ensure to compare configuration after + // casting. This allows floats that are integer values to be compared. + $config_casted = new ConfigCaster($name, $this->configManager->getTypedConfigManager(), $this->sourceData[$collection][$name]); + if ($config_casted->castData()->get() !== $this->targetData[$collection][$name]) { + $this->addChangeList($collection, 'update', array($name)); + } } } } diff --git a/core/modules/config/src/Tests/ConfigCRUDTest.php b/core/modules/config/src/Tests/ConfigCRUDTest.php index c38d3f6..39f790e 100644 --- a/core/modules/config/src/Tests/ConfigCRUDTest.php +++ b/core/modules/config/src/Tests/ConfigCRUDTest.php @@ -226,6 +226,7 @@ public function testDataTypes() { 'boolean' => TRUE, 'exp' => 1.2e+34, 'float' => 3.14159, + 'float_as_integer' => (float) 1, 'hex' => 0xC, 'int' => 99, 'octal' => 0775, diff --git a/core/modules/options/src/Tests/OptionsFloatFieldImportTest.php b/core/modules/options/src/Tests/OptionsFloatFieldImportTest.php index 1bd8a16..0f8414f 100644 --- a/core/modules/options/src/Tests/OptionsFloatFieldImportTest.php +++ b/core/modules/options/src/Tests/OptionsFloatFieldImportTest.php @@ -7,7 +7,7 @@ namespace Drupal\options\Tests; -use Drupal\field\Entity\FieldInstanceConfig; +use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Tests\FieldTestBase; @@ -52,7 +52,7 @@ public function testImport() { $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); // Set the active to not use dots in the allowed values key names. - $edit = array('field[settings][allowed_values]' => "0|Zero\n1|One"); + $edit = array('field_storage[settings][allowed_values]' => "0|Zero\n1|One"); $this->drupalPostForm($admin_path, $edit, t('Save field settings')); $field_storage = FieldStorageConfig::loadByName('node', $field_name); $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '1' => 'One')); @@ -64,10 +64,9 @@ public function testImport() { $field_storage = FieldStorageConfig::loadByName('node', $field_name); $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '0.5' => 'Point five')); - // Delete field to test creation. Deleting the instance will also delete - // the storage. This tests + // Delete field to test creation. This tests // \Drupal\Core\Config\Entity\ConfigEntityStorage::importCreate(). - FieldInstanceConfig::loadByName('node', $type, $field_name)->delete(); + FieldConfig::loadByName('node', $type, $field_name)->delete(); $this->drupalGet('admin/config/development/configuration'); $this->drupalPostForm(NULL, array(), t('Import all')); diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml index fa50c85..3b96a57 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml @@ -2,7 +2,7 @@ langcode: en status: true dependencies: entity: - - field.instance.node.options_install_test.body + - field.field.node.options_install_test.body - node.type.options_install_test module: - entity_reference diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml index 6f70ecb..506ee9d 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml @@ -2,7 +2,7 @@ langcode: en status: true dependencies: entity: - - field.instance.node.options_install_test.body + - field.field.node.options_install_test.body - node.type.options_install_test module: - text diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml index ce39a8f..356a6a2 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml @@ -3,7 +3,7 @@ status: true dependencies: entity: - core.entity_view_mode.node.teaser - - field.instance.node.options_install_test.body + - field.field.node.options_install_test.body - node.type.options_install_test module: - text diff --git a/core/modules/options/tests/options_config_install_test/config/install/field.instance.node.options_install_test.body.yml b/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml similarity index 100% rename from core/modules/options/tests/options_config_install_test/config/install/field.instance.node.options_install_test.body.yml rename to core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml diff --git a/core/modules/options/tests/options_config_install_test/config/install/field.instance.node.options_install_test.field_options_float.yml b/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.field_options_float.yml similarity index 100% rename from core/modules/options/tests/options_config_install_test/config/install/field.instance.node.options_install_test.field_options_float.yml rename to core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.field_options_float.yml diff --git a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php index 2263126..d938638 100644 --- a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php +++ b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php @@ -50,6 +50,10 @@ protected function setUp() { $this->sourceStorage = $this->getMock('Drupal\Core\Config\StorageInterface'); $this->targetStorage = $this->getMock('Drupal\Core\Config\StorageInterface'); $this->configManager = $this->getMock('Drupal\Core\Config\ConfigManagerInterface'); + $this->typedConfigManager = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface'); + $this->configManager->expects($this->any()) + ->method('getTypedConfigManager') + ->willReturn($this->typedConfigManager); $this->storageComparer = new StorageComparer($this->sourceStorage, $this->targetStorage, $this->configManager); }