From a44ec5dbbd41c063b46c45a92a838fcf93f3ea4b Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Sat, 3 Dec 2011 02:52:06 +0800 Subject: [PATCH 1/5] Rename system_find_base_themes() to drupal_find_base_themes() --- core/includes/theme.inc | 41 +++++++++++++++++++++++++++++++++++ core/modules/system/system.module | 43 +------------------------------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 40c4f35..edde6ba 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -790,6 +790,47 @@ function list_themes($refresh = FALSE) { } /** + * Find all the base themes for the specified theme. + * + * Themes can inherit templates and function implementations from earlier themes. + * + * @param $themes + * An array of available themes. + * @param $key + * The name of the theme whose base we are looking for. + * @param $used_keys + * A recursion parameter preventing endless loops. + * @return + * Returns an array of all of the theme's ancestors; the first element's value + * will be NULL if an error occurred. + */ +function drupal_find_base_themes($themes, $key, $used_keys = array()) { + $base_key = $themes[$key]->info['base theme']; + // Does the base theme exist? + if (!isset($themes[$base_key])) { + return array($base_key => NULL); + } + + $current_base_theme = array($base_key => $themes[$base_key]->info['name']); + + // Is the base theme itself a child of another theme? + if (isset($themes[$base_key]->info['base theme'])) { + // Do we already know the base themes of this theme? + if (isset($themes[$base_key]->base_themes)) { + return $themes[$base_key]->base_themes + $current_base_theme; + } + // Prevent loops. + if (!empty($used_keys[$base_key])) { + return array($base_key => NULL); + } + $used_keys[$base_key] = TRUE; + return drupal_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme; + } + // If we get here, then this is our parent theme. + return $current_base_theme; +} + +/** * Generates themed output. * * All requests for themed output must go through this function. It examines diff --git a/core/modules/system/system.module b/core/modules/system/system.module index a5bfd10..f2421fb 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2581,7 +2581,7 @@ function _system_rebuild_theme_data() { // Now that we've established all our master themes, go back and fill in data // for subthemes. foreach ($sub_themes as $key) { - $themes[$key]->base_themes = system_find_base_themes($themes, $key); + $themes[$key]->base_themes = drupal_find_base_themes($themes, $key); // Don't proceed if there was a problem with the root base theme. if (!current($themes[$key]->base_themes)) { continue; @@ -2674,47 +2674,6 @@ function _system_default_theme_features() { } /** - * Find all the base themes for the specified theme. - * - * Themes can inherit templates and function implementations from earlier themes. - * - * @param $themes - * An array of available themes. - * @param $key - * The name of the theme whose base we are looking for. - * @param $used_keys - * A recursion parameter preventing endless loops. - * @return - * Returns an array of all of the theme's ancestors; the first element's value - * will be NULL if an error occurred. - */ -function system_find_base_themes($themes, $key, $used_keys = array()) { - $base_key = $themes[$key]->info['base theme']; - // Does the base theme exist? - if (!isset($themes[$base_key])) { - return array($base_key => NULL); - } - - $current_base_theme = array($base_key => $themes[$base_key]->info['name']); - - // Is the base theme itself a child of another theme? - if (isset($themes[$base_key]->info['base theme'])) { - // Do we already know the base themes of this theme? - if (isset($themes[$base_key]->base_themes)) { - return $themes[$base_key]->base_themes + $current_base_theme; - } - // Prevent loops. - if (!empty($used_keys[$base_key])) { - return array($base_key => NULL); - } - $used_keys[$base_key] = TRUE; - return system_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme; - } - // If we get here, then this is our parent theme. - return $current_base_theme; -} - -/** * Get a list of available regions from a specified theme. * * @param $theme_key -- 1.7.8.3 From a9e2e2f45829218a4952b29a9148a8302b6a27a9 Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Sat, 3 Dec 2011 02:52:50 +0800 Subject: [PATCH 2/5] Make system_list() cache base_themes and sub_themes arrays for themes --- core/includes/module.inc | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diff --git a/core/includes/module.inc b/core/includes/module.inc index 1a52a80..d61aba9 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -178,6 +178,30 @@ function system_list($type) { $lists['filepaths'][] = array('type' => $record->type, 'name' => $record->name, 'filepath' => $record->filename); } } + foreach ($lists['theme'] as $key => $theme) { + if (!empty($theme->info['base theme'])) { + // Make a list of the theme's base themes. + $lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key); + // Don't proceed if there was a problem with the root base theme. + if (!current($lists['theme'][$key]->base_themes)) { + continue; + } + // Determine the root base theme. + $base_key = key($lists['theme'][$key]->base_themes); + // Add to the list of sub-themes for each of the theme's base themes. + foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) { + $lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name']; + } + // Add the base theme's theme engine info. + $lists['theme'][$key]->info['engine'] = $lists['theme'][$base_key]->info['engine']; + } + else { + // A plain theme is its own base theme. + $base_key = $key; + } + // Set the theme engine prefix. + $lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine']; + } cache('bootstrap')->set('system_list', $lists); } // To avoid a separate database lookup for the filepath, prime the -- 1.7.8.3 From ea50675546fba991b63e2213ec8b7ceff76bc31f Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Sat, 3 Dec 2011 02:53:08 +0800 Subject: [PATCH 3/5] Add tests --- core/modules/simpletest/tests/theme.test | 31 ++++++++++++++++++++ core/modules/simpletest/tests/theme_test.module | 2 + .../themes/test_basetheme/test_basetheme.info | 7 ++++ .../tests/themes/test_subtheme/test_subtheme.info | 7 ++++ .../tests/themes/test_theme/test_theme.info | 2 + 5 files changed, 49 insertions(+), 0 deletions(-) create mode 100644 core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info create mode 100644 core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info diff --git a/core/modules/simpletest/tests/theme.test b/core/modules/simpletest/tests/theme.test index 9870545..4ca470a 100644 --- a/core/modules/simpletest/tests/theme.test +++ b/core/modules/simpletest/tests/theme.test @@ -113,6 +113,37 @@ class ThemeUnitTest extends DrupalWebTestCase { $this->drupalGet('theme-test/template-test'); $this->assertText('Success: Template overridden.', t('Template overridden by defined \'template\' filename.')); } + + /** + * Test the list_themes() function. + */ + function testListThemes() { + $themes = list_themes(); + // Check if drupal_theme_access() retrieves enabled themes properly from list_themes(). + $this->assertTrue(drupal_theme_access('test_theme'), t('Enabled theme detected')); + // Check if list_themes() returns disabled themes. + $this->assertTrue(array_key_exists('test_basetheme', $themes), t('Disabled theme detected')); + // Check for base theme and subtheme lists. + $base_theme_list = array('test_basetheme' => 'Theme test base theme'); + $sub_theme_list = array('test_subtheme' => 'Theme test subtheme'); + $this->assertIdentical($themes['test_basetheme']->sub_themes, $sub_theme_list, t('Base theme\'s object includes list of subthemes.')); + $this->assertIdentical($themes['test_subtheme']->base_themes, $base_theme_list, t('Subtheme\'s object includes list of base themes.')); + // Check for theme engine in subtheme. + $this->assertIdentical($themes['test_subtheme']->engine, 'phptemplate', t('Subtheme\'s object includes the theme engine.')); + // Check for theme engine prefix. + $this->assertIdentical($themes['test_basetheme']->prefix, 'phptemplate', t('Base theme\'s object includes the theme engine prefix.')); + $this->assertIdentical($themes['test_subtheme']->prefix, 'phptemplate', t('Subtheme\'s object includes the theme engine prefix.')); + } + + /** + * Test the theme_get_setting() function. + */ + function testThemeGetSetting() { + $GLOBALS['theme_key'] = 'test_theme'; + $this->assertIdentical(theme_get_setting('theme_test_setting'), 'default value', t('theme_get_setting() uses the default theme automatically.')); + $this->assertNotEqual(theme_get_setting('subtheme_override', 'test_basetheme'), theme_get_setting('subtheme_override', 'test_subtheme'), t('Base theme\'s default settings values can be overridden by subtheme.')); + $this->assertIdentical(theme_get_setting('basetheme_only', 'test_subtheme'), 'base theme value', t('Base theme\'s default settings values are inherited by subtheme.')); + } } /** diff --git a/core/modules/simpletest/tests/theme_test.module b/core/modules/simpletest/tests/theme_test.module index 570b72c..365fd87 100644 --- a/core/modules/simpletest/tests/theme_test.module +++ b/core/modules/simpletest/tests/theme_test.module @@ -19,6 +19,8 @@ function theme_test_theme($existing, $type, $theme, $path) { */ function theme_test_system_theme_info() { $themes['test_theme'] = drupal_get_path('module', 'theme_test') . '/themes/test_theme/test_theme.info'; + $themes['test_basetheme'] = drupal_get_path('module', 'theme_test') . '/themes/test_basetheme/test_basetheme.info'; + $themes['test_subtheme'] = drupal_get_path('module', 'theme_test') . '/themes/test_subtheme/test_subtheme.info'; return $themes; } diff --git a/core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info b/core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info new file mode 100644 index 0000000..2b5f66e --- /dev/null +++ b/core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info @@ -0,0 +1,7 @@ +name = Theme test base theme +description = Test theme which acts as a base theme for other test subthemes. +core = 8.x +hidden = TRUE + +settings[basetheme_only] = base theme value +settings[subtheme_override] = base theme value diff --git a/core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info b/core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info new file mode 100644 index 0000000..974e00f --- /dev/null +++ b/core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info @@ -0,0 +1,7 @@ +name = Theme test subtheme +description = Test theme which uses test_basetheme as the base theme. +core = 8.x +base theme = test_basetheme +hidden = TRUE + +settings[subtheme_override] = subtheme value diff --git a/core/modules/simpletest/tests/themes/test_theme/test_theme.info b/core/modules/simpletest/tests/themes/test_theme/test_theme.info index c32fe57..b5d1bfc 100644 --- a/core/modules/simpletest/tests/themes/test_theme/test_theme.info +++ b/core/modules/simpletest/tests/themes/test_theme/test_theme.info @@ -14,3 +14,5 @@ hidden = TRUE ; version from being loaded, and that errors aren't caused by the lack of this ; file within the theme folder. stylesheets[all][] = system.base.css + +settings[theme_test_setting] = default value -- 1.7.8.3 From 7611416459c24d0bf76e3ad9cc219b828937c60a Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Fri, 27 Jan 2012 23:03:38 +0800 Subject: [PATCH 4/5] Theme settings forms do not need to rebuild the theme .info cache. --- core/modules/system/system.admin.inc | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 4e8e936..00c4c41 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -369,7 +369,7 @@ function system_theme_settings($form, &$form_state, $key = '') { // Default settings are defined in theme_get_setting() in includes/theme.inc if ($key) { $var = 'theme_' . $key . '_settings'; - $themes = system_rebuild_theme_data(); + $themes = list_themes(); $features = $themes[$key]->info['features']; } else { -- 1.7.8.3 From c3d066b1f0522633a3498923f3b76813383feb5e Mon Sep 17 00:00:00 2001 From: JohnAlbin Date: Fri, 27 Jan 2012 23:54:14 +0800 Subject: [PATCH 5/5] Fixed documentation for list_themes(). --- core/includes/theme.inc | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index edde6ba..ee4ddb5 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -723,7 +723,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { * names of the themes and the values are objects having the following * properties: * - 'filename': The name of the .info file. - * - 'name': The name of the theme. + * - 'name': The machine name of the theme. * - 'status': 1 for enabled, 0 for disabled themes. * - 'info': The contents of the .info file. * - 'stylesheets': A two dimensional array, using the first key for the @@ -733,7 +733,10 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { * - 'scripts': An associative array of JavaScripts, using the filename as key * and the complete filepath as value. * - 'engine': The name of the theme engine. - * - 'base theme': The name of the base theme. + * - 'base_theme': The name of the base theme. + * - 'base_themes': An ordered array of all the base themes. If the first item + * is NULL, a base theme is missing for this theme. + * - 'sub_themes': An unordered array of sub-themes of this theme. */ function list_themes($refresh = FALSE) { $list = &drupal_static(__FUNCTION__, array()); -- 1.7.8.3