diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index 5c7aeeb..6ccf8fd 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -107,9 +107,13 @@ public function buildDataDefinition(array $definition, $value, $name = NULL, $pa // Remove the type from the definition so that it is replaced with the // concrete type from schema definitions. unset($definition['type']); + + $definition += $this->getDefinition($type, TRUE, $replace); + } + else { + // Add default values from type definition. + $definition += $this->getDefinition($type); } - // Add default values from type definition. - $definition += $this->getDefinition($type); $data_definition = $this->createDataDefinition($definition['type']); @@ -125,7 +129,7 @@ public function buildDataDefinition(array $definition, $value, $name = NULL, $pa /** * {@inheritdoc} */ - public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) { + public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE, $value = NULL) { $definitions = $this->getDefinitions(); if (isset($definitions[$base_plugin_id])) { $type = $base_plugin_id; @@ -145,6 +149,14 @@ public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) { // Preserve integer keys on merge, so sequence item types can override // parent settings as opposed to adding unused second, third, etc. items. $definition = NestedArray::mergeDeepArray(array($merge, $definition), TRUE); + + // If the sub type has a bracket then lets look that up as well. + if (isset($value) && strpos($definition['type'], ']')) { + $sub_type = $this->replaceName($definition['type'], $value); + $merge = $definitions[$sub_type]; + $definition = NestedArray::mergeDeepArray(array($merge, $definition), TRUE); + } + // Unset type so we try the merge only once per type. unset($definition['type']); $this->definitions[$type] = $definition; diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index a94e26a..ee58b0d 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -498,4 +498,37 @@ public function testConfigSchemaInfoAlter() { $this->assertEqual($definitions['config_schema_test.hook']['additional_metadata'], 'new schema info'); } + /** + * Tests saving config when the type is wrapped by a dynamic type. + */ + public function testConfigSaveWithWrappingSchema() { + $untyped_values = [ + 'tests' => [ + [ + 'wrapper_value' => 'foo', + 'plugin_id' => 'wrapper', + 'internal_value' => 100, + ], + ], + ]; + $untyped_to_typed = $untyped_values; + + $typed_values = array( + 'tests' => [ + [ + 'wrapper_value' => 'foo', + 'plugin_id' => 'wrapper', + 'internal_value' => '100', + ], + ], + ); + + // Save config which has a schema that enforces types. + \Drupal::configFactory()->getEditable('wrapping.config_schema_test.plugin_types') + ->setData($untyped_to_typed) + ->save(); + $this->assertIdentical(\Drupal::config('wrapping.config_schema_test.plugin_types') + ->get(), $typed_values); + } + } diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml index 004ae2b..c716537 100644 --- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml +++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml @@ -213,3 +213,23 @@ config_test.dynamic.*.third_party.config_schema_test: type: integer string: type: string + +wrapping.config_schema_test.plugin_types: + type: config_object + mapping: + tests: + type: sequence + sequence: + - type: wrapping.test.plugin_types.[plugin_id] + +wrapping.test.plugin_types.*: + type: test.plugin_types.[plugin_id] + mapping: + wrapper_value: + type: string + +test.plugin_types.wrapper: + type: test.plugin_types + mapping: + internal_value: + type: string