WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#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)

comment:1 @mrubiolvn4 years ago

Sorry, where I said $postId+1 I meant the new inserted post

comment:2 @SergeyBiryukov4 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*/));
}

comment:3 @scribu4 years ago

  • Cc scribu added

comment:4 @mrubiolvn4 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.

comment:5 @transom4 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"?

comment:7 @transom4 years ago

Thanks for the pointer - clearly we have been down this road before.

comment:8 @mrubiolvn4 years ago

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #17817

comment:9 @SergeyBiryukov4 years ago

  • Milestone Awaiting Review deleted
Note: See TracTickets for help on using tickets.