Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/wp-includes/plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,8 @@ function do_action( $hook_name, ...$arg ) {
$wp_current_filter[] = $hook_name;
}

if ( empty( $arg ) ) {
if ( array() === $arg ) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably missing something but this change doesn't seem to be part of the trac ticket?

This changes the behavior for false, null, 0, etc. (all things considered "empty" in PHP). After this patch $arg will not be an empty string in these cases, right? Thinking this is a potentially big back-compat break, and also not part of the proposed fix as in the trac ticket.

If this is intentional please open a new ticket with reasoning why this is needed and tests to confirm the back-compat issues it may introduce.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$arg is a variadic parameter which means it'll only ever be an array. This change could have been made as part of r46322.

$arg[] = '';
} elseif ( is_array( $arg[0] ) && 1 === count( $arg[0] ) && isset( $arg[0][0] ) && is_object( $arg[0][0] ) ) {
// Backward compatibility for PHP4-style passing of `array( &$this )` as action `$arg`.
$arg[0] = $arg[0][0];
}

$wp_filter[ $hook_name ]->do_action( $arg );
Expand Down
20 changes: 20 additions & 0 deletions tests/phpunit/includes/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,26 @@ public function action2( $arg ) {
return $arg;
}

/**
* @since 6.9.0
*/
public function action3( array $arg ) {
$current_filter = $this->current_filter();

if ( $this->debug ) {
dmp( __FUNCTION__, $current_filter );
}

$this->events[] = array(
'action' => __FUNCTION__,
'hook_name' => $current_filter,
'tag' => $current_filter, // Back compat.
'args' => func_get_args(),
);

return $arg;
}

/**
* @since UT (3.7.0)
*/
Expand Down
15 changes: 9 additions & 6 deletions tests/phpunit/tests/actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,27 @@ public function test_action_args_3() {
}

/**
* Tests PHP 4 notation for calling actions while passing in an object by reference.
* One hook which is passed an array containing one object. This test ensures it will stay an array and not become an object.
*
* @ticket 48312
* @ticket 60190
*
* @covers ::do_action
*/
public function test_action_args_with_php4_syntax() {
public function test_action_array_of_object_arg() {
$a = new MockAction();
$hook_name = __FUNCTION__;
$val = new stdClass();
$arg = array( $val );

add_action( $hook_name, array( &$a, 'action' ) );
// Call the action with PHP 4 notation for passing object by reference.
do_action( $hook_name, array( &$val ) );
add_action( $hook_name, array( $a, 'action3' ) );
do_action( $hook_name, $arg );

$call_count = $a->get_call_count();
$argsvar = $a->get_args();
$this->assertSame( array( $val ), array_pop( $argsvar ) );

// nested since func_get_args() returns the args as an array
$this->assertSame( array( $arg ), array_pop( $argsvar ) );
}

/**
Expand Down
Loading