#19015 closed defect (bug) (duplicate)
do_action fails on nested calls
Reported by: | mrubiolvn | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.2.1 |
Component: | Plugins | Keywords: | |
Focuses: | Cc: |
Description
I'll explain directly with an example of the scenario, for better understanding I hope.
A function registered through add_action('save_post','callme_back');
with the following code:
function callme_back($postId) { static $runmeOnce=true; if ($runmeOnce) { $runmeOnce = false; wp_insert_post(get_post(21431/*whatever, just to trigger save_post again*/)); } }
causes the internal array pointer of $wp_filter[ $tag ] to skip all
the remaining calls to the filters for $postId, as a result of having already called all of them for $postId+1 and reached the end of the pointer.
A solution is making a copy of $wp_filter[ $tag ] first.
Change History (9)
#2
@
13 years ago
A proper code would probably be:
function callme_back($postId) { remove_action('save_post','callme_back'); wp_insert_post(get_post(21431/*whatever, just to trigger save_post again*/)); }
#4
@
13 years ago
To better clarify:
I've got a plugin which on saving a certain post type(i.e: foo_post), starts a cascade routine, updating some child posts. That messes up the filter array pointer, and makes all the plugins with a lower priority, to miss foo_post. They still get triggered for all the updated child posts.
#5
@
13 years ago
This speaks to a situation I ran into today.
A plugin using a construct similar to SergeyBiryukov (above) was causing my plugin (who had a lower priority tied to the same hook) to not execute.
My theory is that since remove_action (and remove_filter) "unset" the element in the same array that do_action (do_action_ref_array, et al) are iterating over, the index shifts and whatever action is next in the list fails to execute.
But interating over a copy of the current functions hooked would keep one from removing a function further down the priority list (if that was desired)
The question becomes "which one is doing it wrong"?
Sorry, where I said $postId+1 I meant the new inserted post