diff --git includes/theme.inc includes/theme.inc index baceb73..0c5df7c 100644 --- includes/theme.inc +++ includes/theme.inc @@ -67,14 +67,34 @@ function _drupal_theme_access($theme) { /** * Initialize the theme system by loading the theme. + * Use $force_theme to load a specific theme */ -function drupal_theme_initialize() { - global $theme, $user, $theme_key; +function drupal_theme_initialize($force_theme = '') { + global $theme, $user, $theme_key; + if (defined('MAINTENANCE_MODE')) { + $drupal_theme_initialize_rebuild = &drupal_static('theme_switch_drupal_theme_initialize_rebuild', FALSE); + $drupal_theme_initialize_rebuild = TRUE; + } + else { + $drupal_theme_initialize_rebuild = &drupal_static('theme_switch_drupal_theme_initialize_rebuild', FALSE); + } // If $theme is already set, assume the others are set, too, and do nothing - if (isset($theme)) { + //unless force_theme is set, or static caches are cleared + if (isset($theme) && $force_theme == '' && $drupal_theme_initialize_rebuild) { return; } + elseif ($force_theme != '') { + drupal_static_reset('theme_switch_theme'); + drupal_static_reset('theme_switch_theme_get_registry'); + drupal_static_reset('theme_switch__theme_registry_callback'); + drupal_static_reset('drupal_add_css'); + drupal_static_reset('drupal_add_js'); + drupal_theme_rebuild(); + } + $drupal_theme_initialize_rebuild = TRUE; drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE); $themes = list_themes(); @@ -86,7 +106,7 @@ function drupal_theme_initialize() { // Allow modules to override the theme. Validation has already been performed // inside menu_get_custom_theme(), so we do not need to check it again here. $custom_theme = menu_get_custom_theme(); - $theme = !empty($custom_theme) ? $custom_theme : $theme; + $theme = !empty($force_theme) ? $force_theme : (!empty($custom_theme) ? $custom_theme : $theme); // Store the identifier for retrieving theme settings with. $theme_key = $theme; @@ -242,11 +262,13 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb * The theme registry array if it has been stored in memory, NULL otherwise. */ function theme_get_registry() { - static $theme_registry = NULL; + $theme_registry = &drupal_static('theme_switch_theme_get_registry'); if (!isset($theme_registry)) { list($callback, $arguments) = _theme_registry_callback(); - $theme_registry = call_user_func_array($callback, $arguments); + if (isset($callback)) { + $theme_registry = call_user_func_array($callback, $arguments); + } } return $theme_registry; @@ -261,10 +283,12 @@ function theme_get_registry() { * The arguments to pass to the function. */ function _theme_registry_callback($callback = NULL, array $arguments = array()) { - static $stored; + $stored = &drupal_static('theme_switch__theme_registry_callback', NULL); if (isset($callback)) { $stored = array($callback, $arguments); } return $stored; } @@ -736,7 +760,12 @@ function list_themes($refresh = FALSE) { * An HTML string representing the themed output. */ function theme($hook, $variables = array()) { - static $hooks = NULL; + // Use the advanced drupal_static() pattern, since this is called very often. + static $drupal_static_fast; + if (!isset($drupal_static_fast)) { + $drupal_static_fast['theme'] = &drupal_static('theme_switch_theme'); + } + $hooks = &$drupal_static_fast['theme']; // If called before all modules are loaded, we do not necessarily have a full // theme registry to work with, and therefore cannot process the theme diff --git modules/simpletest/tests/theme.test modules/simpletest/tests/theme.test index 9e2f387..82bf63b 100644 --- modules/simpletest/tests/theme.test +++ modules/simpletest/tests/theme.test @@ -188,6 +188,44 @@ class ThemeItemListUnitTest extends DrupalWebTestCase { } /** + * Unit tests for drupal_theme_initialize(). + */ +class ThemeSwitchUnitTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Theme Switch', + 'description' => 'Test the drupal_theme_initialize($force_theme) function to change the theme.', + 'group' => 'Theme', + ); + } + + /** + * Test custom theme rendering. + */ + function testThemeSwitch() { + drupal_theme_initialize('seven'); + $node1 = $this->drupalCreateNode(); + $output1 = node_view($node1); + $output1 = drupal_render_page($output1); + $this->assertTheme('seven', 'bartik', path_to_theme(), $output1); + drupal_theme_initialize('bartik'); + $node2 = $this->drupalCreateNode(); + $output2 = node_view($node2); + $output2 = drupal_render_page($output2); + $this->assertTheme('bartik', 'seven', path_to_theme(), $output2); + + + } + + function assertTheme($name, $previous_theme, $path, $output, $message = '', $group = 'Other') { + return $this->assert((strpos($path, $name) && strpos($output, $path) && !strpos($output, $previous_theme)), + $message ? $message : t('Switching to theme \'@name\'', array('@name' => $name)), + $group); + + } +} + +/** * Unit tests for theme_links(). */ class ThemeLinksUnitTest extends DrupalUnitTestCase {