Opened 9 years ago
Closed 9 years ago
#36199 closed defect (bug) (duplicate)
Calling do_action within the same action causes next priority block to be skipped.
Reported by: | dougwollison | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 4.6 |
Component: | Plugins | Keywords: | |
Focuses: | Cc: |
Description
The do-while loop that do_action()
and apply_filters()
use—rather than a foreach loop—to iterate over the the hooks for an action/filter seems to cause some issues that can result in the callbacks in the next priority block to be skipped altogether.
For example, a theme I was testing something with called get_posts()
within the pre_get_posts
action so it could get a list of posts to exclude from the main query. Since that function calls the same action, the current handling of do_action and apply_filters (and their ref_array version) causes the filter list to be reset in the middle of it being performed, causing the next priority block to be skipped.
The same issue occurs when a callback removes itself to prevent an infinite loop and fails to re-add itself when it's done (though this can be blamed on programmer error for having it remove itself before the should-proceed check).
The only way around the issue without messing with core code would be to add throwaway hooks as a buffer between the known offending hooks, which frankly is ridiculous.
I've attached two patches made to plugin.php
on trunk; one copies the $wp_filter[$tag]
to a new variable to be iterated over in the do-while loop, and the other replaces the do-while loop with a foreach loop. I feel the later is the better option but I can't be sure there wasn't good reason for using the do-while loop in the first place. Both also include some code cleanup; adding curly braces to the various blocks that aren't using them.
This patch uses the $hooks = $wp_filters[$tag] method, copying the array before manipulating it via iteration.