summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/common.inc44
-rw-r--r--includes/module.inc1
-rw-r--r--includes/theme.inc3
-rw-r--r--modules/node/node.test3
4 files changed, 33 insertions, 18 deletions
diff --git a/includes/common.inc b/includes/common.inc
index 5744006bd..7f165dc49 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -4700,27 +4700,37 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
* keyed array as described above.
*/
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
- $hook = $type . '_alter';
- foreach (module_implements($hook) as $module) {
- $function = $module . '_' . $hook;
- $function($data, $context1, $context2);
- }
- // Allow the theme to alter variables after the theme system has been
- // initialized.
- global $theme, $base_theme_info;
- if (isset($theme)) {
- $theme_keys = array();
- foreach ($base_theme_info as $base) {
- $theme_keys[] = $base->name;
+ $functions = &drupal_static(__FUNCTION__, array());
+
+ // Some alter hooks are invoked many times per page request, so statically
+ // cache the list of functions to call, and on subsequent calls, iterate
+ // through them quickly.
+ if (!isset($functions[$type])) {
+ $functions[$type] = array();
+ $hook = $type . '_alter';
+ foreach (module_implements($hook) as $module) {
+ $functions[$type][] = $module . '_' . $hook;
}
- $theme_keys[] = $theme;
- foreach ($theme_keys as $theme_key) {
- $function = $theme_key . '_' . $hook;
- if (function_exists($function)) {
- $function($data, $context1, $context2);
+ // Allow the theme to alter variables after the theme system has been
+ // initialized.
+ global $theme, $base_theme_info;
+ if (isset($theme)) {
+ $theme_keys = array();
+ foreach ($base_theme_info as $base) {
+ $theme_keys[] = $base->name;
+ }
+ $theme_keys[] = $theme;
+ foreach ($theme_keys as $theme_key) {
+ $function = $theme_key . '_' . $hook;
+ if (function_exists($function)) {
+ $functions[$type][] = $function;
+ }
}
}
}
+ foreach ($functions[$type] as $function) {
+ $function($data, $context1, $context2);
+ }
}
/**
diff --git a/includes/module.inc b/includes/module.inc
index 975aaf29d..fd73f9fce 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -383,6 +383,7 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
$implementations = array();
cache_set('module_implements', array());
drupal_static_reset('module_hook_info');
+ drupal_static_reset('drupal_alter');
cache_clear_all('hook_info', 'cache');
return;
}
diff --git a/includes/theme.inc b/includes/theme.inc
index 0f26fde27..2258e5602 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -85,6 +85,9 @@ function drupal_theme_initialize() {
$ancestor = $themes[$ancestor]->base_theme;
}
_drupal_theme_initialize($themes[$theme], array_reverse($base_theme));
+
+ // Themes can have alter functions, so reset the drupal_alter() cache.
+ drupal_static_reset('drupal_alter');
}
/**
diff --git a/modules/node/node.test b/modules/node/node.test
index a2a8e4420..1e8ea8532 100644
--- a/modules/node/node.test
+++ b/modules/node/node.test
@@ -758,7 +758,8 @@ class NodeAccessRecordsUnitTest extends DrupalWebTestCase {
$web_user = $this->drupalCreateUser(array('access content'));
foreach ($operations as $op) {
$grants = node_test_node_grants($op, $web_user);
- $altered_grants = drupal_alter($grants, $web_user, $op);
+ $altered_grants = $grants;
+ drupal_alter('node_grants', $altered_grants, $web_user, $op);
$this->assertNotEqual($grants, $altered_grants, t('Altered the %op grant for a user.', array('%op' => $op)));
}
}