diff --git a/core/lib/Drupal/Core/Config/Schema/ConfigSchemaAlterException.php b/core/lib/Drupal/Core/Config/Schema/ConfigSchemaAlterException.php new file mode 100644 index 0000000..fa87e06 --- /dev/null +++ b/core/lib/Drupal/Core/Config/Schema/ConfigSchemaAlterException.php @@ -0,0 +1,14 @@ + &$definition) { $this->processDefinition($definition, $plugin_id); } - if ($this->alterHook) { - $this->moduleHandler->alter($this->alterHook, $definitions); - } + $this->alterDefintions($definitions); // If this plugin was provided by a module that does not exist, remove the // plugin definition. foreach ($definitions as $plugin_id => $plugin_definition) { @@ -242,4 +240,16 @@ protected function findDefinitions() { return $definitions; } + /** + * Invokes the hook to alter the definitions if the alter hook is set. + * + * @param $definitions + * The discovered plugin defintions. + */ + protected function alterDefintions(&$definitions) { + if ($this->alterHook) { + $this->moduleHandler->alter($this->alterHook, $definitions); + } + } + } diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index c7a6f55..77166a7 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\InstallStorage; +use Drupal\Core\Config\Schema\ConfigSchemaAlterException; use Drupal\Core\TypedData\Type\IntegerInterface; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\simpletest\KernelTestBase; @@ -436,4 +437,31 @@ function testColonsInSchemaTypeDetermination() { $this->assertEqual($definition['type'], 'test_with_parents.plugin_types.*'); } + /** + * Tests hook_config_schema_info_alter(). + */ + public function testConfigSchemaInfoAlter() { + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */ + $typed_config = \Drupal::service('config.typed'); + $typed_config->clearCachedDefinitions(); + + // Ensure that keys can not be added or removed by + // hook_config_schema_info_alter(). + \Drupal::state()->set('config_schema_test_exception', TRUE); + $message = 'Expected ConfigSchemaAlterException thrown.'; + try { + $typed_config->getDefinitions(); + $this->fail($message); + } + catch (ConfigSchemaAlterException $e) { + $this->pass($message); + } + + // Tests that hook_config_schema_info_alter() can add additional metadata to + // existing configuration schema. + \Drupal::state()->set('config_schema_test_exception', FALSE); + $definitions = $typed_config->getDefinitions(); + $this->assertEqual($definitions['config_schema_test.hook']['additional_metadata'], 'new schema info'); + } + } 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 cbc3c61..719865a 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 @@ -207,3 +207,5 @@ test_with_parents.plugin_types.*: value: type: string +config_schema_test.hook: + type: string diff --git a/core/modules/config/tests/config_schema_test/config_schema_test.module b/core/modules/config/tests/config_schema_test/config_schema_test.module new file mode 100644 index 0000000..e697f9c --- /dev/null +++ b/core/modules/config/tests/config_schema_test/config_schema_test.module @@ -0,0 +1,18 @@ +get('config_schema_test_exception')) { + unset($definitions['config_schema_test.hook']); + } + else { + $definitions['config_schema_test.hook']['additional_metadata'] = 'new schema info'; + } +} diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index cfdf5e2..eb4eb9b 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -580,8 +580,8 @@ function hook_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\Config * configuration schema type to change default labels or form element renderers * used for configuration translation. * - * It is strongly advised not to use this hook to add new data types or to - * change the structure of existing ones. Keep in mind that there are tools + * If implementations of this hook add or remove configuration schema a + * ConfigSchemaAlterException will be thrown. Keep in mind that there are tools * that may use the configuration schema for static analysis of configuration * files, like the string extractor for the localization system. Such systems * won't work with dynamically defined configuration schemas. @@ -591,6 +591,9 @@ function hook_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\Config * @param $definitions * Associative array of configuration type definitions keyed by schema type * names. The elements are themselves array with information about the type. + * + * @see \Drupal\Core\Config\TypedConfigManager + * @see \Drupal\Core\Config\Schema\ConfigSchemaAlterException */ function hook_config_schema_info_alter(&$definitions) { // Enhance the text and date type definitions with classes to generate proper