diff -u b/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php --- b/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -295,32 +295,30 @@ return $module_data[$module]->sort; }, $module_list); - // Work out what to install and uninstall. - $current_modules = $this->storageComparer->getTargetStorage()->read('system.module'); - $new_modules = $this->storageComparer->getSourceStorage()->read('system.module'); - $install = array(); - $uninstall = array(); - if (isset($current_modules['enabled'], $new_modules['enabled']) && is_array($current_modules['enabled']) && is_array($new_modules['enabled'])) { - $uninstall = array_diff(array_keys($current_modules['enabled']), array_keys($new_modules['enabled'])); - $install = array_diff(array_keys($new_modules['enabled']), array_keys($current_modules['enabled'])); - // Sort the module list by their weights. So that dependencies - // are uninstalled last. - asort($module_list); - $uninstall = array_intersect(array_keys($module_list), $uninstall); - // Sort the module list by their weights (reverse). So that dependencies - // are installed first. - arsort($module_list); - $install = array_intersect(array_keys($module_list), $install); - } - - $current_themes = $this->storageComparer->getTargetStorage()->read('system.theme'); - $new_themes = $this->storageComparer->getSourceStorage()->read('system.theme'); - $enable = array(); - $disable = array(); - if (isset($current_themes['enabled'], $new_themes['enabled']) && is_array($current_themes['enabled']) && is_array($new_themes['enabled'])) { - $enable = array_diff(array_keys($new_themes['enabled']), array_keys($current_themes['enabled'])); - $disable = array_diff(array_keys($current_themes['enabled']), array_keys($new_themes['enabled'])); - } + // Read the extensions information to determine changes. + $current_extensions = $this->storageComparer->getTargetStorage()->read('core.extension'); + $new_extensions = $this->storageComparer->getSourceStorage()->read('core.extension'); + + // Probably an empty staging directory. + if (!$new_extensions) { + return; + } + + // Work out what modules to install and uninstall. + $uninstall = array_diff(array_keys($current_extensions['module']), array_keys($new_extensions['module'])); + $install = array_diff(array_keys($new_extensions['module']), array_keys($current_extensions['module'])); + // Sort the module list by their weights. So that dependencies + // are uninstalled last. + asort($module_list); + $uninstall = array_intersect(array_keys($module_list), $uninstall); + // Sort the module list by their weights (reverse). So that dependencies + // are installed first. + arsort($module_list); + $install = array_intersect(array_keys($module_list), $install); + + // Work out what themes to enable and to disable. + $enable = array_diff(array_keys($new_extensions['theme']), array_keys($current_extensions['theme'])); + $disable = array_diff(array_keys($current_extensions['theme']), array_keys($new_extensions['theme'])); $this->extensionChangelist = array( 'module' => array( diff -u b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRecreateTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRecreateTest.php --- b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRecreateTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRecreateTest.php @@ -45,14 +45,6 @@ $this->installSchema('system', 'config_snapshot'); $this->installSchema('node', 'node'); - $theme_data = $this->container->get('config.storage')->read('system.theme'); - if (empty($theme_data['enabled'])) { - $this->container->get('config.storage')->write('system.theme', array('admin' => '', 'default' => 'start', 'enabled' => array('stark'))); - } - $module_data = $this->container->get('config.storage')->read('system.module'); - if (empty($module_data['enabled'])) { - $this->container->get('config.storage')->write('system.module', array('enabled' => array('system'))); - } $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); // Set up the ConfigImporter object for testing. diff -u b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php --- b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php @@ -75,19 +75,19 @@ // during the install. Options and Text are there in ensure modules are // installed with the correct dependencies. Options depends on Text so Text // should be installed first. - $system_module = \Drupal::config('system.module')->get(); - $system_module['enabled']['action'] = 0; - $system_module['enabled']['ban'] = 0; - $system_module['enabled'] = module_config_sort($system_module['enabled']); - $staging->write('system.module', $system_module); + $core_extension = \Drupal::config('core.extension')->get(); + $core_extension['module']['action'] = 0; + $core_extension['module']['ban'] = 0; + $core_extension['module'] = module_config_sort($core_extension['module']); + $core_extension['theme']['bartik'] = 0; + $staging->write('core.extension', $core_extension); // Use the install storage so that we can read configuration from modules // and themes that are not installed. $install_storage = new InstallStorage(); - // Enable the bartik theme and set it as default. + // Set the Bartik theme as default. $system_theme = \Drupal::config('system.theme')->get(); - $system_theme['enabled']['bartik'] = 0; $system_theme['default'] = 'bartik'; $staging->write('system.theme', $system_theme); $staging->write('bartik.settings', $install_storage->read('bartik.settings')); @@ -96,15 +96,19 @@ $action_settings = $install_storage->read('action.settings'); $action_settings['recursion_limit'] = 50; $staging->write('action.settings', $action_settings); - // Disable the Options and Text modules to ensure that dependencies are handled // correctly. \Drupal::moduleHandler()->uninstall(array('text', 'options')); + + // Set the state system to record installations and uninstallations. + \Drupal::state()->set('ConfigImportUITest.core.extension.modules_installed', array()); + \Drupal::state()->set('ConfigImportUITest.core.extension.modules_uninstalled', array()); + // Verify that both appear as ready to import. $this->drupalGet('admin/config/development/configuration'); $this->assertText($name); $this->assertText($dynamic_name); - $this->assertText('system.module'); + $this->assertText('core.extension'); $this->assertText('system.theme'); $this->assertText('action.settings'); $this->assertText('bartik.settings'); @@ -114,7 +118,7 @@ $this->drupalPostForm(NULL, array(), t('Import all')); $this->assertNoText($name); $this->assertNoText($dynamic_name); - $this->assertNoText('system.module'); + $this->assertNoText('core.extension'); $this->assertNoText('system.theme'); $this->assertNoText('action.settings'); $this->assertNoText('bartik.settings'); @@ -143,10 +147,12 @@ $theme_info = \Drupal::service('theme_handler')->listInfo(); $this->assertTrue($theme_info['bartik']->status, 'Bartik theme enabled during import.'); - // The configuration object system.theme will be saved twice during config - // import. Once during enabling the system and once during importing the - // new default setting. - $this->assertEqual(\Drupal::state()->get('ConfigImportUITest.system.theme.save', 0), 2, 'The system.theme configuration saved twice during import.'); + // Ensure installations and uninstallation occur as expected. + $installed = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_installed', array()); + $uninstalled = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_uninstalled', array()); + $expected = array('ban', 'action', 'text', 'options'); + $this->assertIdentical($expected, $installed, 'Ban, Action, Text and Options modules installed in the correct order.'); + $this->assertTrue(empty($uninstalled), 'No modules uninstalled during import'); // Verify that the action.settings configuration object was only written // once during the import process and only with the value set in the staged @@ -156,37 +162,36 @@ $recursion_limit_values = \Drupal::state()->get('ConfigImportUITest.action.settings.recursion_limit', array()); $this->assertIdentical($recursion_limit_values, array(50)); - $system_module = \Drupal::config('system.module')->get(); - unset($system_module['enabled']['action']); - unset($system_module['enabled']['ban']); - unset($system_module['enabled']['options']); - unset($system_module['enabled']['text']); - $staging->write('system.module', $system_module); + $core_extension = \Drupal::config('core.extension')->get(); + unset($core_extension['module']['action']); + unset($core_extension['module']['ban']); + unset($core_extension['module']['options']); + unset($core_extension['module']['text']); + unset($core_extension['theme']['bartik']); + $core_extension['disabled']['theme']['bartik'] = 0; + $staging->write('core.extension', $core_extension); $staging->delete('action.settings'); $staging->delete('text.settings'); $system_theme = \Drupal::config('system.theme')->get(); - unset($system_theme['enabled']['bartik']); $system_theme['default'] = 'stark'; $system_theme['admin'] = 'stark'; $staging->write('system.theme', $system_theme); - $staging->write('system.theme.disabled', array('bartik' => 0)); - // Reset counter. - \Drupal::state()->set('ConfigImportUITest.system.theme.save', 0); + // Set the state system to record installations and uninstallations. + \Drupal::state()->set('ConfigImportUITest.core.extension.modules_installed', array()); + \Drupal::state()->set('ConfigImportUITest.core.extension.modules_uninstalled', array()); // Verify that both appear as ready to import. $this->drupalGet('admin/config/development/configuration'); - $this->assertText('system.module'); + $this->assertText('core.extension'); $this->assertText('system.theme'); - $this->assertText('system.theme.disabled'); $this->assertText('action.settings'); // Import and verify that both do not appear anymore. $this->drupalPostForm(NULL, array(), t('Import all')); - $this->assertNoText('system.module'); + $this->assertNoText('core.extension'); $this->assertNoText('system.theme'); - $this->assertNoText('system.theme.disabled'); $this->assertNoText('action.settings'); $this->rebuildContainer(); @@ -195,9 +200,13 @@ $this->assertFalse(\Drupal::moduleHandler()->moduleExists('action'), 'Action module uninstalled during import.'); $this->assertFalse(\Drupal::moduleHandler()->moduleExists('options'), 'Options module uninstalled during import.'); $this->assertFalse(\Drupal::moduleHandler()->moduleExists('text'), 'Text module uninstalled during import.'); - // This is because it will be updated to change the default and admin theme, - // and then remove Bartik. - $this->assertEqual(\Drupal::state()->get('ConfigImportUITest.system.theme.save', 0), 2, 'The system.theme configuration saved twice during import.'); + + // Ensure installations and uninstallation occur as expected. + $installed = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_installed', array()); + $uninstalled = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_uninstalled', array()); + $expected = array('options', 'text', 'ban', 'action'); + $this->assertIdentical($expected, $uninstalled, 'Options, Text, Action and Ban modules uninstalled in the correct order.'); + $this->assertTrue(empty($installed), 'No modules installed during import'); $theme_info = \Drupal::service('theme_handler')->listInfo(); $this->assertTrue(isset($theme_info['bartik']) && !$theme_info['bartik']->status, 'Bartik theme disabled during import.'); diff -u b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php --- b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php @@ -50,14 +50,6 @@ // so it has to be cleared out manually. unset($GLOBALS['hook_config_test']); - $theme_data = $this->container->get('config.storage')->read('system.theme'); - if (empty($theme_data['enabled'])) { - $this->container->get('config.storage')->write('system.theme', array('admin' => '', 'default' => 'stark', 'enabled' => array('stark'))); - } - $module_data = $this->container->get('config.storage')->read('system.module'); - if (empty($module_data['enabled'])) { - $this->container->get('config.storage')->write('system.module', array('enabled' => array('system'))); - } $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); // Set up the ConfigImporter object for testing. diff -u b/core/modules/config/tests/config_import_test/lib/Drupal/config_import_test/EventSubscriber.php b/core/modules/config/tests/config_import_test/lib/Drupal/config_import_test/EventSubscriber.php --- b/core/modules/config/tests/config_import_test/lib/Drupal/config_import_test/EventSubscriber.php +++ b/core/modules/config/tests/config_import_test/lib/Drupal/config_import_test/EventSubscriber.php @@ -56,9 +56,23 @@ $values[] = $config->get('recursion_limit'); $this->state->set('ConfigImportUITest.action.settings.recursion_limit', $values); } - if ($config->getName() == 'system.theme') { - $value = $this->state->get('ConfigImportUITest.system.theme.save', 0); - $this->state->set('ConfigImportUITest.system.theme.save', $value + 1); + + if ($config->getName() == 'core.extension') { + $installed = $this->state->get('ConfigImportUITest.core.extension.modules_installed', array()); + $uninstalled = $this->state->get('ConfigImportUITest.core.extension.modules_uninstalled', array()); + $original = $config->getOriginal('module'); + $data = $config->get('module'); + $install = array_diff_key($data, $original); + if (!empty($install)) { + $installed[] = key($install); + } + $uninstall = array_diff_key($original, $data); + if (!empty($uninstall)) { + $uninstalled[] = key($uninstall); + } + + $this->state->set('ConfigImportUITest.core.extension.modules_installed', $installed); + $this->state->set('ConfigImportUITest.core.extension.modules_uninstalled', $uninstalled); } } diff -u b/core/modules/forum/forum.install b/core/modules/forum/forum.install --- b/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -34,7 +34,7 @@ ), ), ))->save(); - + // Create a default forum so forum posts can be created. $term = entity_create('taxonomy_term', array( 'name' => t('General discussion'), @@ -44,7 +44,7 @@ 'forum_container' => 0, )); $term->save(); - + // Create the instance on the bundle. entity_create('field_instance_config', array( 'field_name' => 'taxonomy_forums', @@ -53,14 +53,14 @@ 'bundle' => 'forum', 'required' => TRUE, ))->save(); - - // Assign form display settings for the 'default' form mode. - entity_get_form_display('node', 'forum', 'default') - ->setComponent('taxonomy_forums', array( - 'type' => 'options_select', - )) - ->save(); - + + // Assign form display settings for the 'default' form mode. + entity_get_form_display('node', 'forum', 'default') + ->setComponent('taxonomy_forums', array( + 'type' => 'options_select', + )) + ->save(); + // Assign display settings for the 'default' and 'teaser' view modes. entity_get_display('node', 'forum', 'default') ->setComponent('taxonomy_forums', array( @@ -68,6 +68,7 @@ 'weight' => 10, )) ->save(); + entity_get_display('node', 'forum', 'teaser') ->setComponent('taxonomy_forums', array( 'type' => 'taxonomy_term_reference_link', reverted: --- b/core/modules/system/config/schema/system.schema.yml +++ a/core/modules/system/config/schema/system.schema.yml @@ -466,8 +466,6 @@ type: boolean label: 'Use default' -# The weight for disabled themes is ignored but the same format for -# system.theme:enabled is used for consistency. system.theme.disabled: type: sequence label: 'Disabled themes' reverted: --- b/core/modules/system/config/system.theme.disabled.yml +++ /dev/null @@ -1,3 +0,0 @@ -# An empty array representing no disabled themes. This file needs to exist since -# all simple configuration must exist. -{ } \ No newline at end of file only in patch2: unchanged: --- a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php @@ -32,6 +32,7 @@ public static function getInfo() { public function setUp() { parent::setUp(); $this->installSchema('system', 'config_snapshot'); + $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); } /** only in patch2: unchanged: --- a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php @@ -36,6 +36,7 @@ public function setUp() { // Update the config snapshot. This allows the parent::setUp() to write // configuration files. \Drupal::service('config.manager')->createSnapshot(\Drupal::service('config.storage'), \Drupal::service('config.storage.snapshot')); + $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); } /** only in patch2: unchanged: --- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php @@ -148,7 +148,7 @@ protected function setUp() { // \Drupal\Core\Config\ConfigInstaller::installDefaultConfig() to work. // Write directly to active storage to avoid early instantiation of // the event dispatcher which can prevent modules from registering events. - \Drupal::service('config.storage')->write('core.extension', array('module' => array())); + \Drupal::service('config.storage')->write('core.extension', array('module' => array(), 'theme' => array())); // Collect and set a fixed module list. $class = get_class($this);