diff --git a/includes/module.inc b/includes/module.inc index 779b668..714957a 100644 --- a/includes/module.inc +++ b/includes/module.inc @@ -425,6 +425,8 @@ function module_enable($module_list, $enable_dependencies = TRUE) { registry_update(); // Refresh the schema to include it. drupal_get_schema(NULL, TRUE); + // Update the theme registry to include it. + drupal_theme_rebuild(); // Clear entity cache. entity_info_cache_clear(); @@ -545,6 +547,8 @@ function module_disable($module_list, $disable_dependents = TRUE) { // Update the registry to remove the newly-disabled module. registry_update(); _system_update_bootstrap_status(); + // Update the theme registry to remove the newly-disabled module. + drupal_theme_rebuild(); } // If there remains no more node_access module, rebuilding will be diff --git a/includes/theme.inc b/includes/theme.inc index 3ae5000..e156ccc 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -241,7 +241,7 @@ 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(__FUNCTION__); if (!isset($theme_registry)) { list($callback, $arguments) = _theme_registry_callback(); @@ -310,6 +310,7 @@ function _theme_save_registry($theme, $registry) { */ function drupal_theme_rebuild() { cache_clear_all('theme_registry', 'cache', TRUE); + drupal_static_reset('theme_get_registry'); } /** @@ -749,7 +750,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['hooks'] = &drupal_static('theme_get_registry'); + } + $hooks = &$drupal_static_fast['hooks']; // 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 a/modules/simpletest/tests/theme.test b/modules/simpletest/tests/theme.test index f1e1bd5..26fa35f 100644 --- a/modules/simpletest/tests/theme.test +++ b/modules/simpletest/tests/theme.test @@ -101,6 +101,17 @@ class ThemeUnitTest extends DrupalWebTestCase { $this->drupalGet('theme-test/suggestion'); variable_set('preprocess_css', 0); } + + /** + * Ensures the theme registry is rebuilt when modules are disabled/enabled. + */ + function testRegistryRebuild() { + $this->assertIdentical(theme('theme_test_foo', array('foo' => 'a')), 'a', t('The theme registry contains theme_test_foo.')); + module_disable(array('theme_test'), FALSE); + $this->assertIdentical(theme('theme_test_foo', array('foo' => 'b')), '', t('The theme registry does not contain theme_test_foo, because the module is disabled.')); + module_enable(array('theme_test'), FALSE); + $this->assertIdentical(theme('theme_test_foo', array('foo' => 'c')), 'c', t('The theme registry contains theme_test_foo again after re-enabling the module.')); + } } /** diff --git a/modules/simpletest/tests/theme_test.module b/modules/simpletest/tests/theme_test.module index 160d192..f8cb6a5 100644 --- a/modules/simpletest/tests/theme_test.module +++ b/modules/simpletest/tests/theme_test.module @@ -1,6 +1,24 @@ array( + 'variables' => array('foo' => NULL), + ), + ); +} + +/** + * Theme function for testing theme('theme_test_foo'). + */ +function theme_theme_test_foo($variables) { + return $variables['foo']; +} + +/** * Implements hook_menu(). */ function theme_test_menu() {