From 7f00c591b0433b6ef40856427aa60a8d02b3fca6 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 9 Apr 2014 04:49:22 -0400
Subject: [PATCH] Issue #2218655 by sun, effulgentsia, jessebeach: Core expects
 $theme.settings default config file to exist.

---
 core/config/schema/core.data_types.schema.yml | 65 ++++++++++++++++-
 core/includes/theme.inc                       | 13 +++-
 .../system/config/schema/system.schema.yml    | 63 +---------------
 .../system/Tests/Theme/ThemeSettingsTest.php  | 73 +++++++++++++++++++
 .../config/schema/test_basetheme.schema.yml   |  7 ++
 .../config/test_basetheme.settings.yml        |  3 +
 core/themes/bartik/bartik.info.yml            |  4 +-
 core/themes/bartik/config/bartik.settings.yml |  3 +
 .../bartik/config/schema/bartik.schema.yml    |  8 +-
 .../seven/config/schema/seven.schema.yml      |  2 +-
 core/themes/seven/config/seven.settings.yml   |  1 -
 core/themes/seven/seven.info.yml              |  6 +-
 .../stark/config/schema/stark.schema.yml      |  2 +-
 core/themes/stark/config/stark.settings.yml   |  1 -
 14 files changed, 172 insertions(+), 79 deletions(-)
 create mode 100644 core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSettingsTest.php
 create mode 100644 core/modules/system/tests/themes/test_basetheme/config/schema/test_basetheme.schema.yml
 create mode 100644 core/modules/system/tests/themes/test_basetheme/config/test_basetheme.settings.yml
 delete mode 100644 core/themes/seven/config/seven.settings.yml
 delete mode 100644 core/themes/stark/config/stark.settings.yml

diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index ee8c1471a684..fc534dff9b58 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -101,12 +101,69 @@ action_configuration_default:
   sequence:
     - type: string
 
-theme_settings_default:
+theme_settings:
   type: mapping
   mapping:
-    shortcut_module_link:
-      type: boolean
-      label: 'Shortcut module link'
+    favicon:
+      type: mapping
+      label: 'Shortcut icon settings'
+      mapping:
+        mimetype:
+          type: string
+          label: 'MIME type'
+        path:
+          type: string
+          label: 'Path'
+        url:
+          type: string
+          label: 'URL'
+        use_default:
+          type: boolean
+          label: 'Use the default shortcut icon supplied by the theme'
+    features:
+      type: mapping
+      label: 'Shortcut icon settings'
+      mapping:
+        comment_user_picture:
+          type: boolean
+          label: 'User pictures in comments'
+        comment_user_verification:
+          type: boolean
+          label: 'User verification status in comments'
+        favicon:
+          type: boolean
+          label: 'Shortcut icon'
+        logo:
+          type: boolean
+          label: 'Logo'
+        name:
+          type: boolean
+          label: 'Site name'
+        node_user_picture:
+          type: boolean
+          label: 'User pictures in posts'
+        main_menu:
+          type: boolean
+          label: 'Main menu'
+        secondary_menu:
+          type: boolean
+          label: 'Secondary menu'
+        slogan:
+          type: boolean
+          label: 'Site slogan'
+    logo:
+      type: mapping
+      label: 'Shortcut icon settings'
+      mapping:
+        path:
+          type: string
+          label: 'Logo path'
+        url:
+          type: uri
+          label: 'URL'
+        use_default:
+          type: boolean
+          label: 'Use default'
 
 theme_breakpoints_default:
   type: sequence
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index dec14f48ab1d..52ce3160165d 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -12,6 +12,7 @@
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Config\Config;
+use Drupal\Core\Config\StorageException;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Extension\Extension;
 use Drupal\Core\Extension\ExtensionNameLengthException;
@@ -862,6 +863,7 @@ function theme_get_setting($setting_name, $theme = NULL) {
       else {
         $theme_keys = array($theme);
       }
+      // Read hard-coded default settings from the theme info files.
       foreach ($theme_keys as $theme_key) {
         if (!empty($themes[$theme_key]->info['settings'])) {
           $cache[$theme]->merge($themes[$theme_key]->info['settings']);
@@ -873,12 +875,17 @@ function theme_get_setting($setting_name, $theme = NULL) {
     $cache[$theme]->merge(\Drupal::config('system.theme.global')->get());
 
     if ($theme) {
-      // Get the saved theme-specific settings from the configuration system.
-      $cache[$theme]->merge(\Drupal::config($theme . '.settings')->get());
+      // Retrieve configured theme-specific settings, if any.
+      try {
+        if ($theme_settings = \Drupal::config($theme . '.settings')->get()) {
+          $cache[$theme]->merge($theme_settings);
+        }
+      }
+      catch (StorageException $e) {
+      }
 
       // If the theme does not support a particular feature, override the global
       // setting and set the value to NULL.
-      //$supports = $cache[$theme]->get('supports');
       if (!empty($theme_object->info['features'])) {
         foreach (_system_default_theme_features() as $feature) {
           if (!in_array($feature, $theme_object->info['features'])) {
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index 5f8b4d47bb59..91f06055590d 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -385,66 +385,5 @@ system.mail:
           label: 'Default'
 
 system.theme.global:
-  type: mapping
+  type: theme_settings
   label: 'Theme global settings'
-  mapping:
-    favicon:
-      type: mapping
-      label: 'Shortcut icon settings'
-      mapping:
-        mimetype:
-          type: string
-          label: 'MIME type'
-        path:
-          type: string
-          label: 'Path'
-        url:
-          type: string
-          label: 'URL'
-        use_default:
-          type: boolean
-          label: 'Use the default shortcut icon supplied by the theme'
-    features:
-      type: mapping
-      label: 'Shortcut icon settings'
-      mapping:
-        comment_user_picture:
-          type: boolean
-          label: 'User pictures in comments'
-        comment_user_verification:
-          type: boolean
-          label: 'User verification status in comments'
-        favicon:
-          type: boolean
-          label: 'Shortcut icon'
-        logo:
-          type: boolean
-          label: 'Logo'
-        name:
-          type: boolean
-          label: 'Site name'
-        node_user_picture:
-          type: boolean
-          label: 'User pictures in posts'
-        main_menu:
-          type: boolean
-          label: 'Main menu'
-        secondary_menu:
-          type: boolean
-          label: 'Secondary menu'
-        slogan:
-          type: boolean
-          label: 'Site slogan'
-    logo:
-      type: mapping
-      label: 'Shortcut icon settings'
-      mapping:
-        path:
-          type: string
-          label: 'Logo path'
-        url:
-          type: uri
-          label: 'URL'
-        use_default:
-          type: boolean
-          label: 'Use default'
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSettingsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSettingsTest.php
new file mode 100644
index 000000000000..8593bae000ae
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSettingsTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Theme\ThemeSettingsTest.
+ */
+
+namespace Drupal\system\Tests\Theme;
+
+use Drupal\Core\Extension\ExtensionDiscovery;
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests theme settings functionality.
+ */
+class ThemeSettingsTest extends DrupalUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('system');
+
+  /**
+   * List of discovered themes.
+   *
+   * @var array
+   */
+  protected $availableThemes;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Theme settings',
+      'description' => 'Tests theme settings functionality.',
+      'group' => 'Theme',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    // Theme settings rely on System module's system.theme.global configuration.
+    $this->installConfig(array('system'));
+
+    if (!isset($this->availableThemes)) {
+      $discovery = new ExtensionDiscovery();
+      $this->availableThemes = $discovery->scan('theme');
+    }
+  }
+
+  /**
+   * Tests that $theme.settings are imported and used as default theme settings.
+   */
+  function testDefaultConfig() {
+    $name = 'test_basetheme';
+    $path = $this->availableThemes[$name]->getPath();
+    $this->assertTrue(file_exists("$path/config/$name.settings.yml"));
+    $this->container->get('theme_handler')->enable(array($name));
+    $this->assertIdentical(theme_get_setting('base', $name), 'only');
+  }
+
+  /**
+   * Tests that the $theme.settings default config file is optional.
+   */
+  function testNoDefaultConfig() {
+    $name = 'stark';
+    $path = $this->availableThemes[$name]->getPath();
+    $this->assertFalse(file_exists("$path/config/$name.settings.yml"));
+    $this->container->get('theme_handler')->enable(array($name));
+    $this->assertNotNull(theme_get_setting('features.favicon', $name));
+  }
+
+}
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 000000000000..8a4bd452a974
--- /dev/null
+++ b/core/modules/system/tests/themes/test_basetheme/config/schema/test_basetheme.schema.yml
@@ -0,0 +1,7 @@
+test_basetheme.settings:
+  type: theme_settings
+  label: 'Test base theme settings'
+  mapping:
+    base:
+      type: string
+      label: 'Base theme setting'
diff --git a/core/modules/system/tests/themes/test_basetheme/config/test_basetheme.settings.yml b/core/modules/system/tests/themes/test_basetheme/config/test_basetheme.settings.yml
new file mode 100644
index 000000000000..2d5de349ceda
--- /dev/null
+++ b/core/modules/system/tests/themes/test_basetheme/config/test_basetheme.settings.yml
@@ -0,0 +1,3 @@
+features:
+  favicon: false
+base: only
diff --git a/core/themes/bartik/bartik.info.yml b/core/themes/bartik/bartik.info.yml
index 3e49ffdaec74..bd0bf898e61e 100644
--- a/core/themes/bartik/bartik.info.yml
+++ b/core/themes/bartik/bartik.info.yml
@@ -35,6 +35,6 @@ regions:
   footer_thirdcolumn: 'Footer third column'
   footer_fourthcolumn: 'Footer fourth column'
   footer: Footer
-# @todo D8: Remove once themes have to be installed.
+
 settings:
-  shortcut_module_link: '0'
+  shortcut_module_link: false
diff --git a/core/themes/bartik/config/bartik.settings.yml b/core/themes/bartik/config/bartik.settings.yml
index 3bb124eb8571..48877a3811a5 100644
--- a/core/themes/bartik/config/bartik.settings.yml
+++ b/core/themes/bartik/config/bartik.settings.yml
@@ -1 +1,4 @@
+# @todo There is no UI yet for configuring this, but the setting is included
+#   here, because ConfigImportUITest requires a non-empty bartik.settings.yml
+#   file: https://drupal.org/node/2235901.
 shortcut_module_link: false
diff --git a/core/themes/bartik/config/schema/bartik.schema.yml b/core/themes/bartik/config/schema/bartik.schema.yml
index 7788d4f1537e..bebcfc17a9ba 100644
--- a/core/themes/bartik/config/schema/bartik.schema.yml
+++ b/core/themes/bartik/config/schema/bartik.schema.yml
@@ -1,5 +1,11 @@
 # Schema for the configuration files of the Bartik theme.
 
 bartik.settings:
-  type: theme_settings_default
+  type: theme_settings
   label: 'Bartik settings'
+  mapping:
+    # @todo Module-specific settings should be defined by the module:
+    #   https://drupal.org/node/2235901.
+    shortcut_module_link:
+      type: boolean
+      label: 'Shortcut module link'
diff --git a/core/themes/seven/config/schema/seven.schema.yml b/core/themes/seven/config/schema/seven.schema.yml
index 13f1384063e7..6d4c86e24163 100644
--- a/core/themes/seven/config/schema/seven.schema.yml
+++ b/core/themes/seven/config/schema/seven.schema.yml
@@ -1,7 +1,7 @@
 # Schema for the configuration files of the Seven theme.
 
 seven.settings:
-  type: theme_settings_default
+  type: theme_settings
   label: 'Seven settings'
 
 seven.breakpoints:
diff --git a/core/themes/seven/config/seven.settings.yml b/core/themes/seven/config/seven.settings.yml
deleted file mode 100644
index f84652cc2e5e..000000000000
--- a/core/themes/seven/config/seven.settings.yml
+++ /dev/null
@@ -1 +0,0 @@
-shortcut_module_link: true
diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml
index 582b498d1905..2140bd9637dd 100644
--- a/core/themes/seven/seven.info.yml
+++ b/core/themes/seven/seven.info.yml
@@ -15,9 +15,6 @@ stylesheets-override:
   - jquery.ui.theme.css
 edit_stylesheets:
   - edit.css
-settings:
-  # @todo D8: Remove once themes have to be installed.
-  shortcut_module_link: '1'
 regions:
   content: Content
   help: Help
@@ -26,3 +23,6 @@ regions:
   sidebar_first: 'First sidebar'
 regions_hidden:
   - sidebar_first
+
+settings:
+  shortcut_module_link: true
diff --git a/core/themes/stark/config/schema/stark.schema.yml b/core/themes/stark/config/schema/stark.schema.yml
index 6e0293eacfcf..03311706e194 100644
--- a/core/themes/stark/config/schema/stark.schema.yml
+++ b/core/themes/stark/config/schema/stark.schema.yml
@@ -1,7 +1,7 @@
 # Schema for the configuration files of the Stark theme.
 
 stark.settings:
-  type: theme_settings_default
+  type: theme_settings
   label: 'Stark settings'
 
 stark.breakpoints:
diff --git a/core/themes/stark/config/stark.settings.yml b/core/themes/stark/config/stark.settings.yml
deleted file mode 100644
index 3bb124eb8571..000000000000
--- a/core/themes/stark/config/stark.settings.yml
+++ /dev/null
@@ -1 +0,0 @@
-shortcut_module_link: false
-- 
GitLab