diff --git a/core/includes/module.inc b/core/includes/module.inc index 1a52a80..76e8331 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -424,6 +424,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(); // Allow modules to react prior to the installation of a module. module_invoke_all('modules_preinstall', array($module)); @@ -543,6 +545,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(); } } diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 40c4f35..927a815 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -237,7 +237,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb /** * Get the theme registry. * - * @param $complete + * @param bool $complete * Optional boolean to indicate whether to return the complete theme registry * array or an instance of the ThemeRegistry class. If TRUE, the complete * theme registry array will be returned. This is useful if you want to @@ -252,7 +252,20 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb * class. */ function theme_get_registry($complete = TRUE) { - static $theme_registry = array(); + // Use the advanced drupal_static() pattern, since this is called very often. + static $drupal_static_fast; + if (!isset($drupal_static_fast)) { + $drupal_static_fast['registry'] = &drupal_static('theme_get_registry'); + } + $theme_registry = &$drupal_static_fast['registry']; + + // Initialize the theme, if this is called early in the bootstrap, or after + // static variables have been reset. + if (!is_array($theme_registry)) { + drupal_theme_initialize(); + $theme_registry = array(); + } + $key = (int) $complete; if (!isset($theme_registry[$key])) { @@ -335,6 +348,7 @@ function _theme_save_registry($theme, $registry) { * to add more theme hooks. */ function drupal_theme_rebuild() { + drupal_static_reset('theme_get_registry'); cache()->deletePrefix('theme_registry'); } @@ -899,8 +913,6 @@ function list_themes($refresh = FALSE) { * @see themeable */ function theme($hook, $variables = array()) { - static $hooks = NULL; - // 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 // request properly. See also _theme_load_registry(). @@ -908,10 +920,7 @@ function theme($hook, $variables = array()) { throw new Exception(t('theme() may not be called until all modules are loaded.')); } - if (!isset($hooks)) { - drupal_theme_initialize(); - $hooks = theme_get_registry(FALSE); - } + $hooks = theme_get_registry(FALSE); // If an array of hook candidates were passed, use the first one that has an // implementation. diff --git a/core/modules/simpletest/tests/theme.test b/core/modules/simpletest/tests/theme.test index 9870545..b88efdf 100644 --- a/core/modules/simpletest/tests/theme.test +++ b/core/modules/simpletest/tests/theme.test @@ -113,6 +113,19 @@ class ThemeUnitTest extends DrupalWebTestCase { $this->drupalGet('theme-test/template-test'); $this->assertText('Success: Template overridden.', t('Template overridden by defined \'template\' filename.')); } + + /** + * 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/core/modules/simpletest/tests/theme_test.module b/core/modules/simpletest/tests/theme_test.module index 570b72c..4c3d9e9 100644 --- a/core/modules/simpletest/tests/theme_test.module +++ b/core/modules/simpletest/tests/theme_test.module @@ -10,6 +10,9 @@ function theme_test_theme($existing, $type, $theme, $path) { $items['theme_test_template_test_2'] = array( 'template' => 'theme_test.template_test', ); + $items['theme_test_foo'] = array( + 'variables' => array('foo' => NULL), + ); return $items; } @@ -131,6 +134,13 @@ function _theme_test_suggestion() { } /** + * Theme function for testing theme('theme_test_foo'). + */ +function theme_theme_test_foo($variables) { + return $variables['foo']; +} + +/** * Implements hook_preprocess_breadcrumb(). * * Set a variable that can later be tested to see if this function ran.