﻿id,summary,reporter,owner,description,type,status,priority,milestone,component,version,severity,resolution,keywords,cc
23035,do_action() can't be nested because of global variable,cheeserolls,,"wp-includes/plugin.php lines 401-408:


{{{
reset( $wp_filter[ $tag ] );

do {
	foreach ( (array) current($wp_filter[$tag]) as $the_ )
		if ( !is_null($the_['function']) )
			call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

} while ( next($wp_filter[$tag]) !== false );
}}}



The loop relies on the internal pointer of a global variable:  $wp_filter[$tag]

This means that an action cannot be nested inside the same action, because nested calls to do_action will try to use the same pointer for the loop.

For example:
The WPML plugin (wordpress multilingual) maintains duplicates of posts which haven't yet been translated.  Whenever you update the main post, WPML will also update the duplicates for you.

It does this using the 'save_post' action.  When the 'save_post' action occurs, WPML loops through the duplicated posts and saves them as well.  However, saving the duplicates, causes the 'save_post' action to be triggered again.

$wp_filter['save_post'] is reset and looped for each of the duplicates.  When all the duplicates are done, the loop exits and we return to the outer 'save_post' action.  But the inner loop and outer loop share the same pointer.  So the outer loop thinks it is finished, and exits.  Any other 'save_post' actions that were queued up for the main post don't get executed.

Suggest instead the following patch, to ensure that each call to do_action gets it's own private loop:


{{{
$this_filter = $wp_filter[$tag]; // get a copy of the array to loop over
reset( $this_filter );

do {
	foreach ( (array) current($this_filter) as $the_ )
		if ( !is_null($the_['function']) )
			call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

} while ( next($this_filter) !== false );
}}}
",defect (bug),closed,normal,,Plugins,3.5,normal,duplicate,has-patch,info@…
