? .project ? install_cache_change.patch ? module_implements_cache_rerolled-10.patch ? module_implements_cache_rerolled-11.patch ? module_implements_cache_rerolled-2.patch ? module_implements_cache_rerolled-3.patch ? module_implements_cache_rerolled-4-test.patch ? module_implements_cache_rerolled-5.patch ? module_implements_cache_rerolled-6.patch ? module_implements_cache_rerolled-7.patch ? module_implements_cache_rerolled-8.patch ? module_implements_cache_rerolled-9.patch ? module_implements_cache_rerolled.patch ? sites/all/modules/coder ? sites/default/files ? sites/default/private ? sites/default/settings.php Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.303 diff -u -p -r1.303 update.php --- update.php 14 Sep 2009 07:33:55 -0000 1.303 +++ update.php 15 Sep 2009 14:04:55 -0000 @@ -292,6 +292,9 @@ if (empty($op) && $update_access_allowed drupal_load('module', 'system'); drupal_load('module', 'filter'); + // Reset the module_implements() cache. + module_implements('', FALSE, TRUE); + // Set up $language, since the installer components require it. drupal_language_initialize(); Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.988 diff -u -p -r1.988 common.inc --- includes/common.inc 11 Sep 2009 15:12:29 -0000 1.988 +++ includes/common.inc 15 Sep 2009 14:04:58 -0000 @@ -2403,6 +2403,7 @@ function drupal_page_footer() { _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE); drupal_cache_system_paths(); + module_implements_write_cache(); } /** Index: includes/module.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/module.inc,v retrieving revision 1.157 diff -u -p -r1.157 module.inc --- includes/module.inc 24 Aug 2009 00:14:18 -0000 1.157 +++ includes/module.inc 15 Sep 2009 14:04:58 -0000 @@ -14,7 +14,6 @@ function module_load_all($bootstrap = FA foreach (module_list(TRUE, $bootstrap) as $module) { drupal_load('module', $module); } - module_implements('', FALSE, TRUE); } /** @@ -344,19 +343,41 @@ function module_hook($module, $hook) { * An array with the names of the modules which are implementing this hook. */ function module_implements($hook, $sort = FALSE, $refresh = FALSE) { - static $implementations; - + $implementations = &drupal_static(__FUNCTION__, array()); if ($refresh) { $implementations = array(); + cache_set('module_implements', array()); return; } + if (empty($implementations)) { + $implementations = cache_get('module_implements'); + if ($implementations === FALSE) { + $implementations = array(); + } + else { + $implementations = $implementations->data; + } + } + if (!isset($implementations[$hook])) { $implementations[$hook] = array(); $list = module_list(FALSE, FALSE, $sort); foreach ($list as $module) { if (module_hook($module, $hook)) { - $implementations[$hook][] = $module; + $implementations[$hook][$module] = $module; + // We added something to the cache, so write it when we're done. + $implementations['#write_cache'] = TRUE; + } + } + } + else { + foreach ($implementations[$hook] as $module) { + if (!module_hook($module, $hook)) { + // Ensure no undefined function errors for calling functions. + unset($implementations[$hook][$module]); + // Write the cache later as we changed the $implementations array. + $implementations['#write_cache'] = TRUE; } } } @@ -371,6 +392,19 @@ function module_implements($hook, $sort } /** + * Write to the module_implements() cache. + */ +function module_implements_write_cache() { + $implementations = &drupal_static('module_implements'); + // Check wether we need to write the cache. + // We omit writing the cache as well when we're on POST request to not clutter the + // cache with POST-only hooks. + if (isset($implementations['#write_cache']) && drupal_page_is_cacheable()) { + cache_set('module_implements', $implementations); + } +} + +/** * Invoke a hook in a particular module. * * @param $module