Make WordPress Core

Changeset 52952


Ignore:
Timestamp:
03/18/2022 06:21:40 PM (3 years ago)
Author:
johnbillion
Message:

Plugins: Convert apply_filters() into a proper variadic function.

This makes its signature more correct by implementing the spread operator, and adjusts the internal logic correspondingly without affecting performance.

Props jrf, SergeyBiryukov, davidbaumwald, mauriac, johnbillion

Fixes #53218

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/plugin.php

    r52300 r52952  
    152152 *
    153153 * @since 0.71
     154 * @since 6.0.0 Formalized the existing and already documented `...$args` parameter
     155 *              by adding it to the function signature.
    154156 *
    155157 * @global WP_Hook[] $wp_filter         Stores all of the filters and actions.
     
    161163 * @return mixed The filtered value after all hooked functions are applied to it.
    162164 */
    163 function apply_filters( $hook_name, $value ) {
     165function apply_filters( $hook_name, $value, ...$args ) {
    164166    global $wp_filter, $wp_current_filter;
    165 
    166     $args = func_get_args();
    167167
    168168    // Do 'all' actions first.
    169169    if ( isset( $wp_filter['all'] ) ) {
    170170        $wp_current_filter[] = $hook_name;
    171         _wp_call_all_hook( $args );
     171
     172        $all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
     173        _wp_call_all_hook( $all_args );
    172174    }
    173175
     
    184186    }
    185187
    186     // Don't pass the tag name to WP_Hook.
    187     array_shift( $args );
     188    // Pass the value to WP_Hook.
     189    array_unshift( $args, $value );
    188190
    189191    $filtered = $wp_filter[ $hook_name ]->apply_filters( $value, $args );
  • trunk/tests/phpunit/tests/filters.php

    r52010 r52952  
    217217
    218218    /**
     219     * @ticket 53218
     220     */
     221    public function test_filter_with_ref_value() {
     222        $obj = new stdClass();
     223        $ref = &$obj;
     224        $a   = new MockAction();
     225        $tag = __FUNCTION__;
     226
     227        add_action( $tag, array( $a, 'filter' ) );
     228
     229        $filtered = apply_filters( $tag, $ref );
     230
     231        $args = $a->get_args();
     232        $this->assertSame( $args[0][0], $obj );
     233        $this->assertSame( $filtered, $obj );
     234        // Just in case we don't trust assertSame().
     235        $obj->foo = true;
     236        $this->assertNotEmpty( $args[0][0]->foo );
     237        $this->assertNotEmpty( $filtered->foo );
     238    }
     239
     240    /**
     241     * @ticket 53218
     242     */
     243    public function test_filter_with_ref_argument() {
     244        $obj = new stdClass();
     245        $ref = &$obj;
     246        $a   = new MockAction();
     247        $tag = __FUNCTION__;
     248        $val = 'Hello';
     249
     250        add_action( $tag, array( $a, 'filter' ), 10, 2 );
     251
     252        apply_filters( $tag, $val, $ref );
     253
     254        $args = $a->get_args();
     255        $this->assertSame( $args[0][1], $obj );
     256        // Just in case we don't trust assertSame().
     257        $obj->foo = true;
     258        $this->assertNotEmpty( $args[0][1]->foo );
     259    }
     260
     261    /**
    219262     * @ticket 9886
    220263     */
Note: See TracChangeset for help on using the changeset viewer.