diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index 2bb06b3..cfd7e65 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -70,9 +70,17 @@ public function __construct(ConfigFactoryInterface $config_factory, StorageInter } /** - * {@inheritdoc} + * Gather default configuration to install. + * + * @param string $type + * Type of extension to install. + * @param string $name + * Name of extension to install. + * + * @return + * Array with list of configuration keys to install. */ - public function installDefaultConfig($type, $name) { + protected function gatherDefaultConfig($type, $name) { // Get all default configuration owned by this extension. $source_storage = new ExtensionInstallStorage($this->activeStorage); $config_to_install = $source_storage->listAll($name . '.'); @@ -103,22 +111,25 @@ public function installDefaultConfig($type, $name) { $config_to_install = array_merge($config_to_install, $other_module_config); } + return $config_to_install; + } + + /** + * {@inheritdoc} + */ + public function installDefaultConfig($type, $name) { + $config_to_install = $this->gatherDefaultConfig($type, $name); if (!empty($config_to_install)) { $old_state = $this->configFactory->getOverrideState(); $this->configFactory->setOverrideState(FALSE); - foreach ($config_to_install as $name) { - // Only import new config. - if ($this->activeStorage->exists($name)) { - continue; - } - - $new_config = new Config($name, $this->activeStorage, $this->eventDispatcher, $this->typedConfig); - $data = $source_storage->read($name); + foreach ($config_to_install as $config_name) { + $new_config = new Config($config_name, $this->activeStorage, $this->eventDispatcher, $this->typedConfig); + $data = $source_storage->read($config_name); if ($data !== FALSE) { $new_config->setData($data); } - if ($entity_type = $this->configManager->getEntityTypeIdByName($name)) { + if ($entity_type = $this->configManager->getEntityTypeIdByName($config_name)) { $this->configManager ->getEntityManager() ->getStorageController($entity_type) @@ -133,4 +144,28 @@ public function installDefaultConfig($type, $name) { } } + /** + * Validate default configuration before installation. + * + * @param string $type + * Type of extension to install. + * @param string $name + * Name of extension to install. + * + * @return bool + * Whether all the default configuration of this module can be installed. + * If any of the default configuration already exists in the system, returns + * FALSE. + */ + public function validatePreInstall($type, $name) { + $config_to_install = $this->gatherDefaultConfig($type, $name); + foreach ($config_to_install as $config_name) { + if ($this->activeStorage->exists($config_name)) { + drupal_set_message(t('Active configuration with the name %config_name already exists therefore can not install the default configuration from with the same name from %extension.', array('%config_name' => $config_name, '%extension' => $name)), 'warning'); + return FALSE; + } + } + return TRUE; + } + } diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 001e278..412a54c 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -563,6 +563,13 @@ public function install(array $module_list, $enable_dependencies = TRUE) { ))); } + // Validate default configuration of this module. Bail if unable to + // install. Should not continue installing more modules because those + // may depend on this one. + if (!\Drupal::service('config.installer')->validatePreInstall('module', $module)) { + break; + } + $module_config ->set("enabled.$module", 0) ->set('enabled', module_config_sort($module_config->get('enabled'))) diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php index 0fd3f5e..8f94f92 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php @@ -94,6 +94,13 @@ function testIntegrationModuleReinstallation() { $config_entity = \Drupal::config($default_configuration_entity); $this->assertIdentical($config_entity->isNew(), FALSE); $this->assertIdentical($config_entity->get('label'), 'Customized integration config label'); + + // Verify that installing a module with default configuration that already + // exists in active configuration produces a warning. + \Drupal::moduleHandler()->install(array('config_install_fail')); + $messages = drupal_get_messages('warning'); + $expected_message = t('Active configuration with the name %config_name already exists therefore can not install the default configuration with the same name from %extension_name.', array('%config_name' => 'config_test.dynamic.dotted.default', '%extension_name' => 'config_install_fail')); + $this->assertTrue(in_array($expected_message, $messages['warning']), 'Warning message about existing configuration exists.'); } } diff --git a/core/modules/config/tests/config_install_fail/config/config_test.dynamic.dotted.default.yml b/core/modules/config/tests/config_install_fail/config/config_test.dynamic.dotted.default.yml new file mode 100644 index 0000000..6e2af21 --- /dev/null +++ b/core/modules/config/tests/config_install_fail/config/config_test.dynamic.dotted.default.yml @@ -0,0 +1,6 @@ +id: dotted.default +label: 'Config install fail' +weight: 0 +protected_property: Default +# Intentionally commented out to verify default status behavior. +# status: 1 diff --git a/core/modules/config/tests/config_install_fail/config_install_fail.info.yml b/core/modules/config/tests/config_install_fail/config_install_fail.info.yml new file mode 100644 index 0000000..ebe72ad --- /dev/null +++ b/core/modules/config/tests/config_install_fail/config_install_fail.info.yml @@ -0,0 +1,8 @@ +name: 'Configuration test install fial' +type: module +package: Testing +version: VERSION +core: 8.x +hidden: true +dependencies: + - config_test diff --git a/core/modules/config/tests/config_install_fail/config_install_fail.module b/core/modules/config/tests/config_install_fail/config_install_fail.module new file mode 100644 index 0000000..e77c7ce --- /dev/null +++ b/core/modules/config/tests/config_install_fail/config_install_fail.module @@ -0,0 +1,6 @@ +