Make WordPress Core

Opened 10 years ago

Closed 10 years ago

#28142 closed defect (bug) (fixed)

removing all callbacks from an action results in NULL callback

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

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 10 years ago.
Patch that unsets $wp_filter[$tag] if it contains no callbacks

Download all attachments as: .zip

Change History (3)

@sphoid
10 years ago

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

#1 @SergeyBiryukov
10 years ago

  • Keywords has-patch added
  • Milestone changed from Awaiting Review to 4.0

#2 @wonderboymusic
10 years ago

  • Owner set to wonderboymusic
  • Resolution set to fixed
  • Status changed from new to closed

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.