[wp-trac] [WordPress Trac] #17817: do_action/apply_filters/etc. recursion on same filter kills underlying call
WordPress Trac
wp-trac at lists.automattic.com
Thu Jun 16 18:04:05 UTC 2011
#17817: do_action/apply_filters/etc. recursion on same filter kills underlying call
--------------------------+-----------------------------
Reporter: kernfel | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: minor | Keywords:
--------------------------+-----------------------------
Affects @wp-includes/plugin.php: do_action, do_action_ref_array,
apply_filters, apply_filters_ref_array, _wp_call_all_hook
When calling a specific hook from a function that was called through that
same hook, the remaining hooked functions from the first iteration will be
discarded.[[BR]]
This is due to the handling of the array of registered functions using
internal array pointers instead of a more robust approach.
In my example, this problem arose when I tried to programmatically delete
a menu in reaction to the removal of a category. I hooked into the
delete_term action to do so, upon which another function hooked into
delete_term would no longer fire.[[BR]]
The obvious workaround is to adjust the priorities accordingly, but it
shouldn't be necessary.
The current implementation as in apply_filters is:
{{{
reset( $wp_filter[ $tag ] );
if ( empty($args) )
$args = func_get_args();
do {
foreach( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'],
array_slice($args, 1, (int) $the_['accepted_args']));
}
} while ( next($wp_filter[$tag]) !== false );
}}}
Using the following method instead, both iterations would develop
properly:
{{{
if ( empty($args) )
$args = func_get_args();
foreach ( $wp_filter[$tag] as $filters )
foreach( (array) $filters as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'],
array_slice($args, 1, (int) $the_['accepted_args']));
}
}}}
--
Ticket URL: <http://core.trac.wordpress.org/ticket/17817>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list