Commit 453032c1 authored by webchick's avatar webchick

#692950 by effulgentsia, chx, aaron, catch, moshe weitzman, sun: Use...

#692950 by effulgentsia, chx, aaron, catch, moshe weitzman, sun: Use hook_module_implements_alter() to allow modules to alter the weight of hooks in module_implements().
parent df17569a
......@@ -4591,86 +4591,6 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
return $files;
}
/**
* Hands off alterable variables to type-specific *_alter implementations.
*
* This dispatch function hands off the passed in variables to type-specific
* hook_TYPE_alter() implementations in modules. It ensures a consistent
* interface for all altering operations.
*
* A maximum of 2 alterable arguments is supported. In case more arguments need
* to be passed and alterable, modules provide additional variables assigned by
* reference in the last $context argument:
* @code
* $context = array(
* 'alterable' => &$alterable,
* 'unalterable' => $unalterable,
* 'foo' => 'bar',
* );
* drupal_alter('mymodule_data', $alterable1, $alterable2, $context);
* @endcode
*
* Note that objects are always passed by reference in PHP5. If it is absolutely
* required that no implementation alters a passed object in $context, then an
* object needs to be cloned:
* @code
* $context = array(
* 'unalterable_object' => clone $object,
* );
* drupal_alter('mymodule_data', $data, $context);
* @endcode
*
* @param $type
* A string describing the data type of the alterable $data. 'form', 'links',
* 'node_content', and so on are several examples.
* @param &$data
* The primary data to be altered.
* @param &$context1
* (optional) An additional variable that is passed by reference.
* @param &$context2
* (optional) An additional variable that is passed by reference. If more
* context needs to be provided to implementations, then this should be an
* keyed array as described above.
*/
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = 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['functions'] = &drupal_static(__FUNCTION__);
}
$functions = &$drupal_static_fast['functions'];
// 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;
}
// 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);
}
}
/**
* Set the main page content value for later use.
*
......
......@@ -596,6 +596,11 @@ function module_implements($hook, $sort = FALSE, $reset = FALSE) {
$implementations['#write_cache'] = TRUE;
}
}
// Allow modules to change the weight of specific implementations but avoid
// an infinite loop.
if ($hook != 'module_implements_alter') {
drupal_alter('module_implements', $implementations[$hook], $hook);
}
}
else {
foreach ($implementations[$hook] as $module => $group) {
......@@ -749,3 +754,83 @@ function drupal_required_modules() {
return $required;
}
/**
* Hands off alterable variables to type-specific *_alter implementations.
*
* This dispatch function hands off the passed in variables to type-specific
* hook_TYPE_alter() implementations in modules. It ensures a consistent
* interface for all altering operations.
*
* A maximum of 2 alterable arguments is supported. In case more arguments need
* to be passed and alterable, modules provide additional variables assigned by
* reference in the last $context argument:
* @code
* $context = array(
* 'alterable' => &$alterable,
* 'unalterable' => $unalterable,
* 'foo' => 'bar',
* );
* drupal_alter('mymodule_data', $alterable1, $alterable2, $context);
* @endcode
*
* Note that objects are always passed by reference in PHP5. If it is absolutely
* required that no implementation alters a passed object in $context, then an
* object needs to be cloned:
* @code
* $context = array(
* 'unalterable_object' => clone $object,
* );
* drupal_alter('mymodule_data', $data, $context);
* @endcode
*
* @param $type
* A string describing the data type of the alterable $data. 'form', 'links',
* 'node_content', and so on are several examples.
* @param &$data
* The primary data to be altered.
* @param &$context1
* (optional) An additional variable that is passed by reference.
* @param &$context2
* (optional) An additional variable that is passed by reference. If more
* context needs to be provided to implementations, then this should be an
* keyed array as described above.
*/
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = 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['functions'] = &drupal_static(__FUNCTION__);
}
$functions = &$drupal_static_fast['functions'];
// 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;
}
// 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);
}
}
......@@ -981,6 +981,32 @@ function hook_mail_alter(&$message) {
}
}
/**
* Alter the registry of modules implementing a hook.
*
* This hook is invoked during module_implements(). A module may implement this
* hook in order to reorder the implementing modules, which are otherwise
* ordered by the module's system weight.
*
* @param &$implementations
* An array keyed by the module's name. The value of each item corresponds
* to a $group, which is usually FALSE, unless the implementation is in a
* file named $module.$group.inc.
* @param $hook
* The name of the module hook being implemented.
*/
function hook_module_implements_alter(&$implementations, $hook) {
if ($hook == 'rdf_mapping') {
// Move my_module_rdf_mapping() to the end of the list. module_implements()
// iterates through $implementations with a foreach loop which PHP iterates
// in the order that the items were added, so to move an item to the end of
// the array, we remove it and then add it.
$group = $implementations['my_module'];
unset($implementations['my_module']);
$implementations['my_module'] = $group;
}
}
/**
* Alter the information parsed from module and theme .info files
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment