diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php index 1f366aa..b47fea1 100644 --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -196,6 +196,10 @@ public function enable(array $theme_list, $enable_dependencies = TRUE) { arsort($theme_list); $theme_list = array_keys($theme_list); } + else { + $installed_themes = $extension_config->get('theme') ?: array(); + $installed_themes += $extension_config->get('disabled.theme') ?: array(); + } $themes_enabled = array(); foreach ($theme_list as $key) { @@ -219,31 +223,38 @@ public function enable(array $theme_list, $enable_dependencies = TRUE) { ->clear("disabled.theme.$key") ->save(); - // Update the current theme data accordingly. + // Add the theme to the current list. // @todo Remove all code that relies on $status property. $theme_data[$key]->status = 1; + $this->addTheme($theme_data[$key]); + + // Update the current theme data accordingly. $current_theme_data = $this->state->get('system.theme.data', array()); $current_theme_data[$key] = $theme_data[$key]; $this->state->set('system.theme.data', $current_theme_data); + // Reset theme settings. $theme_settings = &drupal_static('theme_get_setting'); unset($theme_settings[$key]); - // Refresh the theme list as installation of default configuration needs - // an updated list to work. - $this->reset(); - - // The default config installation storage only knows about the currently - // enabled list of themes, so it has to be reset in order to pick up the - // default config of the newly installed theme. However, do not reset the - // source storage when synchronizing configuration, since that would - // needlessly trigger a reload of the whole configuration to be imported. - if (!$this->configInstaller->isSyncing()) { - $this->configInstaller->resetSourceStorage(); - } + // @todo Remove system_list(). + $this->systemListReset(); + + // Only install default configuration if this theme has not been installed + // already. + if (!isset($installed_themes[$key])) { + // The default config installation storage only knows about the currently + // enabled list of themes, so it has to be reset in order to pick up the + // default config of the newly installed theme. However, do not reset the + // source storage when synchronizing configuration, since that would + // needlessly trigger a reload of the whole configuration to be imported. + if (!$this->configInstaller->isSyncing()) { + $this->configInstaller->resetSourceStorage(); + } - // Install default configuration of the theme. - $this->configInstaller->installDefaultConfig('theme', $key); + // Install default configuration of the theme. + $this->configInstaller->installDefaultConfig('theme', $key); + } $themes_enabled[] = $key; @@ -251,8 +262,8 @@ public function enable(array $theme_list, $enable_dependencies = TRUE) { watchdog('system', '%theme theme enabled.', array('%theme' => $key), WATCHDOG_INFO); } - $this->resetSystem(); $this->clearCssCache(); + $this->resetSystem(); // Invoke hook_themes_enabled() after the themes have been enabled. $this->moduleHandler->invokeAll('themes_enabled', array($themes_enabled)); @@ -284,15 +295,22 @@ public function disable(array $theme_list) { ->clear("theme.$key") ->set("disabled.theme.$key", 0); + // Remove the theme from the current list. + unset($this->list[$key]); + + // Update the current theme data accordingly. unset($current_theme_data[$key]); + // Reset theme settings. $theme_settings = &drupal_static('theme_get_setting'); unset($theme_settings[$key]); + + // @todo Remove system_list(). + $this->systemListReset(); } $extension_config->save(); $this->state->set('system.theme.data', $current_theme_data); - $this->reset(); $this->resetSystem(); // Invoke hook_themes_disabled after the themes have been disabled. diff --git a/core/modules/system/lib/Drupal/system/Tests/Extension/ThemeHandlerTest.php b/core/modules/system/lib/Drupal/system/Tests/Extension/ThemeHandlerTest.php index 0268f7d..95fdee9 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Extension/ThemeHandlerTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Extension/ThemeHandlerTest.php @@ -73,7 +73,7 @@ function testEnable() { $this->themeHandler()->enable(array($name)); $this->assertIdentical($this->extensionConfig()->get("theme.$name"), 0); - $this->assertFalse($this->extensionConfig()->get("disabled.theme.$name")); + $this->assertNull($this->extensionConfig()->get("disabled.theme.$name")); $themes = $this->themeHandler()->listInfo(); $this->assertTrue(isset($themes[$name])); @@ -141,14 +141,40 @@ function testDisable() { /** * Tests disabling and enabling a theme. + * + * Verifies that + * - themes can be re-enabled + * - default configuration is not re-imported upon re-enabling an already + * installed theme. */ function testDisableEnable() { $name = 'test_basetheme'; - $this->testDisable(); - $this->config("$name.settings")->set('keep', 'me')->save(); - $this->testEnable(); - $this->assertIdentical($this->config("$name.settings")->get('keep'), 'me'); + $this->themeHandler()->enable(array($name)); + $this->themeHandler()->disable(array($name)); + + $this->assertIdentical($this->config("$name.settings")->get('base'), 'only'); + $this->assertIdentical($this->config('system.date_format.fancy')->get('label'), 'Fancy date'); + + // Default configuration never overwrites custom configuration, so just + // changing values in existing configuration will cause ConfigInstaller to + // simply skip those files. To ensure that no default configuration is + // re-imported, the custom configuration has to be deleted. + $this->configStorage()->delete("$name.settings"); + $this->configStorage()->delete('system.date_format.fancy'); + // Reflect direct storage operations in ConfigFactory. + $this->container->get('config.factory')->reset(); + + $this->themeHandler()->enable(array($name)); + + $themes = $this->themeHandler()->listInfo(); + $this->assertTrue(isset($themes[$name])); + $this->assertEqual($themes[$name]->getName(), $name); + + $this->assertEqual(array_keys(system_list('theme')), array_keys($themes)); + + $this->assertFalse($this->config("$name.settings")->get()); + $this->assertNull($this->config('system.date_format.fancy')->get('label')); } /** @@ -289,10 +315,22 @@ protected function extensionConfig() { /** * Returns a given config object. * + * @param string $name + * The name of the config object to load. + * * @return \Drupal\Core\Config\Config */ protected function config($name) { return $this->container->get('config.factory')->get($name); } + /** + * Returns the active configuration storage. + * + * @return \Drupal\Core\Config\ConfigStorageInterface + */ + protected function configStorage() { + return $this->container->get('config.storage'); + } + } diff --git a/core/modules/system/tests/themes/test_basetheme/config/schema/test_basetheme.schema.yml b/core/modules/system/tests/themes/test_basetheme/config/schema/test_basetheme.schema.yml new file mode 100644 index 0000000..9cfe9ec --- /dev/null +++ b/core/modules/system/tests/themes/test_basetheme/config/schema/test_basetheme.schema.yml @@ -0,0 +1,10 @@ +test_basetheme.settings: + type: system.theme.global + label: 'Test base theme settings' + mapping: + base: + type: string + label: 'Base theme setting' + override: + type: string + label: 'Whether the setting has been overridden' diff --git a/core/modules/system/tests/themes/test_basetheme/config/system.date_format.fancy.yml b/core/modules/system/tests/themes/test_basetheme/config/system.date_format.fancy.yml new file mode 100644 index 0000000..12ae886 --- /dev/null +++ b/core/modules/system/tests/themes/test_basetheme/config/system.date_format.fancy.yml @@ -0,0 +1,11 @@ +# Themes are not supposed to provide/install this kind of config normally. +# This exists for testing purposes only. +# @see \Drupal\system\Tests\Extension\ThemeHandlerTest +id: fancy +label: 'Fancy date' +status: true +langcode: en +locked: false +pattern: + php: 'U' + intl: 'EEEE, LLLL d, yyyy - kk:mm' diff --git a/core/modules/system/tests/themes/test_subtheme/config/schema/test_subtheme.schema.yml b/core/modules/system/tests/themes/test_subtheme/config/schema/test_subtheme.schema.yml new file mode 100644 index 0000000..034734b --- /dev/null +++ b/core/modules/system/tests/themes/test_subtheme/config/schema/test_subtheme.schema.yml @@ -0,0 +1,7 @@ +test_subtheme.settings: + type: theme_settings_default + label: 'Test sub theme settings' + mapping: + override: + type: string + label: 'Whether the setting has been overridden'