diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaDiscovery.php b/core/lib/Drupal/Core/Config/Schema/SchemaDiscovery.php index 41b88cac63e4..51e684af42e2 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaDiscovery.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaDiscovery.php @@ -48,7 +48,7 @@ class SchemaDiscovery implements DiscoveryInterface { if (isset($this->definitions[$base_plugin_id])) { $type = $base_plugin_id; } - elseif (strpos($base_plugin_id, '.') && ($name = $this->getFallbackName($base_plugin_id)) && isset($this->definitions[$name])) { + elseif (strpos($base_plugin_id, '.') && $name = $this->getFallbackName($base_plugin_id)) { // Found a generic name, replacing the last element by '*'. $type = $name; } @@ -95,13 +95,28 @@ class SchemaDiscovery implements DiscoveryInterface { * @param string $name * Configuration name or key. * - * @return string - * Same name with the last part replaced by the filesystem marker. + * @return null|string + * Same name with the last part(s) replaced by the filesystem marker. + * for example, breakpoint.breakpoint.module.toolbar.narrow check for + * definition in below order: + * breakpoint.breakpoint.module.toolbar.* + * breakpoint.breakpoint.module.*.* + * breakpoint.breakpoint.*.*.* + * breakpoint.*.*.*.* + * Returns null, if no matching element. */ - protected static function getFallbackName($name) { - $replaced = preg_replace('/\.[^.]+$/', '.' . '*', $name); - if ($replaced != $name) { - return $replaced; + protected function getFallbackName($name) { + // Check for definition of $name with filesystem marker. + $replaced = preg_replace('/(\.[^\.]+)([\.\*]*)$/', '.*\2', $name); + if ($replaced != $name ) { + if (isset($this->definitions[$replaced])) { + return $replaced; + } + else { + // No definition for this level(for example, breakpoint.breakpoint.*), + // check for next level (which is, breakpoint.*.*). + return self::getFallbackName($replaced); + } } } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php index b72a54c11271..a204a320aa95 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php @@ -129,6 +129,24 @@ class ConfigSchemaTest extends DrupalUnitTestBase { $expected['type'] = 'image.effect.image_scale'; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium'); + + // More complex, multiple filesystem marker test. + $definition = config_typed()->getDefinition('config_test.someschema.somemodule.section_one.subsection'); + // This should be the schema of config_test.someschema.somemodule.*.*. + $expected = array(); + $expected['label'] = 'Schema multiple filesytem marker test'; + $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['mapping']['id']['type'] = 'string'; + $expected['mapping']['id']['label'] = 'ID'; + $expected['mapping']['description']['type'] = 'text'; + $expected['mapping']['description']['label'] = 'Description'; + + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.someschema.somemodule.section_one.subsection'); + + $definition = config_typed()->getDefinition('config_test.someschema.somemodule.section_two.subsection'); + // The other file should have the same schema. + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.someschema.somemodule.section_two.subsection'); + } /** diff --git a/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_one.subsection.yml b/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_one.subsection.yml new file mode 100644 index 000000000000..521ffd854517 --- /dev/null +++ b/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_one.subsection.yml @@ -0,0 +1,2 @@ +testid: 'Test id' +testdescription: 'Test description' diff --git a/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_two.subsection.yml b/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_two.subsection.yml new file mode 100644 index 000000000000..521ffd854517 --- /dev/null +++ b/core/modules/config/tests/config_test/config/config_test.someschema.somemodule.section_two.subsection.yml @@ -0,0 +1,2 @@ +testid: 'Test id' +testdescription: 'Test description' 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 82028db23811..d0791ee4d31a 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 @@ -6,3 +6,14 @@ config_test.someschema: label: "Test item" "testlist": label: "Test list" + +config_test.someschema.somemodule.*.*: + type: mapping + label: 'Schema multiple filesytem marker test' + mapping: + id: + type: string + label: 'ID' + description: + type: text + label: 'Description'