Make WordPress Core

Ticket #51525: typed-apply-filters.patch

File typed-apply-filters.patch, 5.9 KB (added by herregroen, 3 years ago)
  • src/wp-includes/class-wp-hook.php

    diff --git src/wp-includes/class-wp-hook.php src/wp-includes/class-wp-hook.php
    index eb43c10c05..bacc4c4149 100644
    final class WP_Hook implements Iterator, ArrayAccess { 
    267267         * @return mixed The filtered value after all hooked functions are applied to it.
    268268         */
    269269        public function apply_filters( $value, $args ) {
     270                return $this->apply_filters_typed( 'mixed', $value, $args );
     271        }
     272
     273        /**
     274         * Calls the callback functions that have been added to a filter hook in a typesafe manner.
     275         *
     276         * @since 5.8.0
     277         *
     278         * @param mixed $value The value to filter.
     279         * @param array $args  Additional parameters to pass to the callback functions.
     280         *                     This array is expected to include $value at index 0.
     281         * @return mixed The filtered value after all hooked functions are applied to it.
     282         */
     283        public function apply_filters_typesafe( $value, $args ) {
     284                return $this->apply_filters_typed( gettype( $value ), $value, $args );
     285        }
     286
     287        /**
     288         * Calls the callback functions that have been added to a filter hook in a typed manner.
     289         *
     290         * @since 5.8.0
     291         *
     292         * @param mixed $value The value to filter.
     293         * @param array $args  Additional parameters to pass to the callback functions.
     294         *                     This array is expected to include $value at index 0.
     295         * @return mixed The filtered value after all hooked functions are applied to it.
     296         */
     297        public function apply_filters_typed( $type, $value, $args ) {
    270298                if ( ! $this->callbacks ) {
    271299                        return $value;
    272300                }
    final class WP_Hook implements Iterator, ArrayAccess { 
    287315
    288316                                // Avoid the array_slice() if possible.
    289317                                if ( 0 == $the_['accepted_args'] ) {
    290                                         $value = call_user_func( $the_['function'] );
     318                                        $next_value = call_user_func( $the_['function'] );
    291319                                } elseif ( $the_['accepted_args'] >= $num_args ) {
    292                                         $value = call_user_func_array( $the_['function'], $args );
     320                                        $next_value = call_user_func_array( $the_['function'], $args );
    293321                                } else {
    294                                         $value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int) $the_['accepted_args'] ) );
     322                                        $next_value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int) $the_['accepted_args'] ) );
     323                                }
     324                                if ( ! is_type( $type, $next_value ) ) {
     325                                        _doing_it_wrong(
     326                                                $the_['function'],
     327                                                sprintf(
     328                                                        __( 'Invalid type returned in filter. Expected %1$s but received %2$s' ),
     329                                                        $type,
     330                                                        gettype( $next_value )
     331                                                ),
     332                                                '5.8'
     333                                        );
    295334                                }
     335                                $value = $next_value;
    296336                        }
    297337                } while ( false !== next( $this->iterations[ $nesting_level ] ) );
    298338
  • src/wp-includes/load.php

    diff --git src/wp-includes/load.php src/wp-includes/load.php
    index a68e6db435..8281a48347 100644
    function is_wp_error( $thing ) { 
    15171517        return $is_wp_error;
    15181518}
    15191519
     1520/**
     1521 * Checks whether the given variable is a certain type.
     1522 *
     1523 * Returns whether `$value` is certain type.
     1524 *
     1525 * @since 5.8.0
     1526 *
     1527 * @param string $type  The type to check.
     1528 * @param mixed  $value The variable to check.
     1529 * @return bool Whether the variable is of the type.
     1530 */
     1531function is_type( $type, $value ) {
     1532        switch( $type ) {
     1533                case 'boolean':
     1534                        return is_bool( $value );
     1535                case 'integer':
     1536                        return is_int( $value );
     1537                case 'double':
     1538                        return is_float( $value );
     1539                case 'string':
     1540                        return is_string( $value );
     1541                case 'array':
     1542                        return is_array( $value );
     1543                case 'object':
     1544                        return is_object( $value );
     1545                case 'resource':
     1546                case 'resource (closed)':
     1547                        return is_resource( $value );
     1548                case 'NULL':
     1549                        return is_null( $value );
     1550                case 'unknown_type':
     1551                        return false;
     1552                case 'mixed':
     1553                        return true;
     1554                default:
     1555                        return is_a( $value, $type ) || is_subclass_of( $value, $type );
     1556        }
     1557}
     1558
    15201559/**
    15211560 * Determines whether file modifications are allowed.
    15221561 *
  • src/wp-includes/plugin.php

    diff --git src/wp-includes/plugin.php src/wp-includes/plugin.php
    index 7bcfc7aa94..5a0736d6b2 100644
    function has_filter( $tag, $function_to_check = false ) { 
    184184 * @param mixed  ...$args Additional parameters to pass to the callback functions.
    185185 * @return mixed The filtered value after all hooked functions are applied to it.
    186186 */
    187 function apply_filters( $tag, $value ) {
     187function apply_filters( $tag, $value, ...$args ) {
     188        return apply_filters_typed( 'mixed', $tag, $value, ...$args );
     189}
     190
     191/**
     192 * Calls the callback functions that have been added to a filter hook in a typesafe manner.
     193 *
     194 * @param string $tag     The name of the filter hook.
     195 * @param mixed  $value   The value to filter.
     196 * @param mixed  ...$args Additional parameters to pass to the callback functions.
     197 * @return mixed The filtered value after all hooked functions are applied to it.
     198 */
     199function apply_filters_typesafe( $tag, $value, ...$args ) {
     200        return apply_filters_typed( gettype( $value ), $tag, $value, ...$args );
     201}
     202
     203/**
     204 * Calls the callback functions that have been added to a filter hook in a typed manner.
     205 *
     206 * @param string $type    The type the return value should have.
     207 * @param string $tag     The name of the filter hook.
     208 * @param mixed  $value   The value to filter.
     209 * @param mixed  ...$args Additional parameters to pass to the callback functions.
     210 * @return mixed The filtered value after all hooked functions are applied to it.
     211 */
     212function apply_filters_typed( $type, $tag, $value ) {
    188213        global $wp_filter, $wp_current_filter;
    189214
    190215        $args = func_get_args();
     216        // Don't pass the type to the 'all' actions.
     217        array_shift( $args );
    191218
    192219        // Do 'all' actions first.
    193220        if ( isset( $wp_filter['all'] ) ) {
    function apply_filters( $tag, $value ) { 
    209236        // Don't pass the tag name to WP_Hook.
    210237        array_shift( $args );
    211238
    212         $filtered = $wp_filter[ $tag ]->apply_filters( $value, $args );
     239        $filtered = $wp_filter[ $tag ]->apply_filters_typed( $type, $value, $args );
    213240
    214241        array_pop( $wp_current_filter );
    215242