diff --git a/core/includes/common.inc b/core/includes/common.inc index 4229d52..14192ad 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -7269,13 +7269,14 @@ function drupal_implode_tags($tags) { /** * Flush all cached data on the site. * - * Empties cache tables, rebuilds the menu cache and theme registries, and - * invokes a hook so that other modules' cache data can be cleared as well. + * Clears static caches, empties cache tables, rebuilds the menu cache and theme + * registries, and invokes a hook so that other modules' cache data can be + * cleared as well. + * Note that after clearing all static caches also the theme is not initialized + * any more and any possible previously added Javascript or CSS is gone. */ function drupal_flush_all_caches() { - // Change query-strings on css/js files to enforce reload for all users. - _drupal_flush_css_js(); - + // Rebuild class registry and module information. registry_rebuild(); drupal_clear_css_cache(); drupal_clear_js_cache(); @@ -7283,28 +7284,44 @@ function drupal_flush_all_caches() { // Rebuild the theme data. Note that the module data is rebuilt above, as // part of registry_rebuild(). system_rebuild_theme_data(); - drupal_theme_rebuild(); - node_types_rebuild(); - // node_menu() defines menu items based on node types so it needs to come - // after node types are rebuilt. - menu_rebuild(); - - // Synchronize to catch any actions that were added or removed. - actions_synchronize(); + // Now clear all static caches as well as all cache bins, such that afterwards + // any triggered rebuild runs with fresh caches. + drupal_static_reset(); + // First clear all cache bins of core, then invoke hook_flush_caches() to get + // contrib cache bins to clear. That way we ensure core caches are cleared + // before an contrib might trigger any cache rebuild in an implementation of + // hook_flush_caches(). // Don't clear cache_form - in-progress form submissions may break. // Ordered so clearing the page cache will always be the last action. - $core = array('cache', 'path', 'filter', 'bootstrap', 'page'); - $cache_bins = array_merge(module_invoke_all('flush_caches'), $core); - foreach ($cache_bins as $bin) { + // Page cache is cleared separately below, after most rebuilds (especially + // menu rebuild) have been done. + foreach (array('bootstrap', 'cache', 'path') as $bin) { + cache($bin)->flush(); + } + foreach (module_invoke_all('flush_caches') as $bin) { cache($bin)->flush(); } + // Menu rebuilding is going to trigger lots of cache rebuilds. + menu_rebuild(); + + // Synchronize to catch any actions that were added or removed. + actions_synchronize(); + // Change query-strings on css/js files to enforce reload for all users. + _drupal_flush_css_js(); + // Clear the page cache after all cache flushes and rebuilds. + cache('page')->flush(); + // Rebuild the bootstrap module list. We do this here so that developers // can get new hook_boot() implementations registered without having to // write a hook_update_N() function. _system_update_bootstrap_status(); + + // Unset the global theme variable so drupal_theme_initialize() and + // drupal_maintenance_theme() re-initialize the theme if necessary. + unset($GLOBALS['theme']); } /** diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 66426fb..e7d7b68 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1524,6 +1524,8 @@ function install_finished(&$install_state) { // do not leave stale cached data, and that any content types or other items // registered by the install profile are registered correctly. drupal_flush_all_caches(); + // After flushing caches we have to re-initialize the maintenance theme again. + drupal_maintenance_theme(); // Remember the profile which was used. variable_set('install_profile', drupal_get_profile()); diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 1e45b2a..93d502d 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -884,7 +884,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(__FUNCTION__); + } + $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/core/modules/filter/filter.module b/core/modules/filter/filter.module index 2ad725a..f25a470 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -772,6 +772,13 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE) } /** + * Implements hook_flush_caches(). + */ +function filter_flush_caches() { + return array('filter'); +} + +/** * Expands an element into a base element with text format selector attached. * * The form element will be expanded into two separate form elements, one diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 0c3cfb7..4b642c8 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -736,7 +736,9 @@ function _node_types_build($rebuild = FALSE) { } asort($_node_types->names); - + // Set caches. + $static = &drupal_static(__FUNCTION__); + $static = $_node_types; cache()->set($cid, $_node_types); return $_node_types; @@ -1952,10 +1954,6 @@ function node_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); - // @todo Remove this loop when we have a 'description callback' property. - // Reset internal static cache of _node_types_build(), forces to rebuild the - // node type information. - node_type_cache_reset(); foreach (node_type_get_types() as $type) { $type_url_str = str_replace('_', '-', $type->type); $items['node/add/' . $type_url_str] = array( @@ -3893,6 +3891,14 @@ function node_modules_enabled($modules) { if (!node_access_needs_rebuild() && array_intersect($modules, module_implements('node_grants'))) { node_access_needs_rebuild(TRUE); } + node_types_rebuild(); +} + +/** + * Implements hook_modules_disabled(). + */ +function node_modules_disabled($modules) { + node_types_rebuild(); } /**