Make WordPress Core

Opened 12 years ago

Closed 12 years ago

#28142 closed defect (bug) (fixed)

removing all callbacks from an action results in NULL callback

Reported by: sphoid Owned by: wonderboymusic
Priority: normal Milestone: 4.0
Component: Plugins Version: 3.8.3
Severity: normal Keywords: has-patch
Cc: Focuses:

Description

If you remove all callbacks for an action and the action is triggered afterwards you will receive a php warning (Warning: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given)

The following code will demonstrate this:

function do_something(){

	echo 'do_something called<br/>';

	do_action( 'test_action_1234', 'test' );

}

function test_action_callback( $param ){

	echo 'test_action happened<br/>';

}
add_action( 'test_action_1234', 'test_action_callback', 10 );

do_something();

remove_action( 'test_action_1234', 'test_action_callback', 10 );

do_something();

This happens on line 427 in wp-includes/plugin.php:

foreach ( (array) current($wp_filter[$tag]) as $the_ )

when $wp_filter['test_action_1234'] is empty it is converted to a single element array that contains a null value which php then complains about not being a valid callback, which makes sense.

Expected behavior is that no warning should occur when all callbacks are removed from an action.

When all tags are removed for an action then the tag should be removed from $wp_filter to prevent this. I am attaching a patch for wp-includes/plugin.php remove_filter function that does this.

Attachments (1)

plugin.diff (482 bytes ) - added by sphoid 12 years ago.
Patch that unsets $wp_filter[$tag] if it contains no callbacks

Download all attachments as: .zip

Change History (3)

@sphoid
12 years ago

Patch that unsets $wp_filter[$tag] if it contains no callbacks

#1 @SergeyBiryukov
12 years ago

  • Keywords has-patch added
  • Milestone Awaiting Review4.0

#2 @wonderboymusic
12 years ago

  • Owner set to wonderboymusic
  • Resolutionfixed
  • Status newclosed

In 28884:

After [28883], remove_filter() should set $GLOBALS['wp_filter'][ $tag ] to array() when empty.

Props wonderboymusic, sphoid.
Fixes #28142.

Note: See TracTickets for help on using tickets.