[wp-trac] [WordPress Trac] #51525: Add new functions apply_filters_single_type() and apply_filters_ref_array_single_type()

WordPress Trac noreply at wordpress.org
Tue Feb 2 17:56:21 UTC 2021


#51525: Add new functions apply_filters_single_type() and
apply_filters_ref_array_single_type()
------------------------------------------------+--------------------------
 Reporter:  jrf                                 |       Owner:  (none)
     Type:  feature request                     |      Status:  new
 Priority:  normal                              |   Milestone:  Future
                                                |  Release
Component:  General                             |     Version:
 Severity:  normal                              |  Resolution:
 Keywords:  2nd-opinion needs-patch php8 early  |     Focuses:
------------------------------------------------+--------------------------

Comment (by herregroen):

 I would suggest two functions

 `apply_filters_typesafe( $tag, $value, ...$args )` which uses `gettype` to
 retrieve the type of the `$value` and the uses the appropriate `is_`
 function to validate that type.

 `apply_filters_typed( $type, $tag, $value, ...$args )` in which $type is
 either a primitive or a class name. Primitives are validated using the
 appropriate `is_` function and class names are validated using `is_a ||
 is_subclass_of`. In the future we could allow for arrays as `$type` to
 allow multiple return types but that can be added later or even more
 complex objects to, for example, describe the shape of arrays. But the
 first implementation should remain simple and focus on just a string
 `$type` argument.

 The `mixed` type should also be supported for the simple reason that this
 will allow `apply_filters`, `apply_filters_typesafe` and
 `apply_filters_typed` to share one single implementation.

 `apply_filters( ... )` is simply `apply_filters_typed( 'mixed', ... )`.
 `apply_filters_typesafe( ... _` is simply `apply_filters_typed( gettype(
 $value ), ... )`.

 This means we have just one function to maintain and test as opposed to
 multiple.

 Type-checking would be the following function:
 {{{#!php
 <?php
 /**
  * Checks whether the given variable is a certain type.
  *
  * Returns whether `$value` is certain type.
  *
  * @since 5.8.0
  *
  * @param string $type  The type to check.
  * @param mixed  $value The variable to check.
  * @return bool Whether the variable is of the type.
  */
 function is_type( $type, $value ) {
         if ( $type === 'mixed' ) {
                 return true;
         }
         if (
                 in_array(
                         $type,
                         [
                                 'boolean',
                                 'integer',
                                 'double',
                                 'string',
                                 'array',
                                 'object',
                                 'resource',
                                 'resource (closed)',
                                 'NULL',
                                 'unknown type',
                         ],
                         true
                 )
         ) {
                 switch( $type ) {
                         case 'boolean':
                                 return is_bool( $value );
                         case 'integer':
                                 return is_int( $value );
                         case 'double':
                                 return is_float( $value );
                         case 'string':
                                 return is_string( $value );
                         case 'array':
                                 return is_array( $value );
                         case 'object':
                                 return is_object( $value );
                         case 'resource':
                         case 'resource (closed)':
                                 return is_resource( $value );
                         case 'NULL':
                                 return is_null( $value );
                         default:
                                 return false;
                 }
         }

         return is_a( $value, $type ) || is_subclass_of( $value, $type );
 }
 }}}
 The main apply_filters loop in `WP_Hook` would have to be as follows
 {{{#!php
 <?php
 // Avoid the array_slice() if possible.
 if ( 0 == $the_['accepted_args'] ) {
         $next_value = call_user_func( $the_['function'] );
 } elseif ( $the_['accepted_args'] >= $num_args ) {
         $next_value = call_user_func_array( $the_['function'], $args );
 } else {
         $next_value = call_user_func_array( $the_['function'],
 array_slice( $args, 0, (int) $the_['accepted_args'] ) );
 }
 if ( ! is_type( $type, $next_value ) ) {
         _doing_it_wrong(
                 $the_['function'],
                 sprintf(
                         __( 'Invalid type returned in filter. Expected
 %1$s but received %2$s' ),
                         $type,
                         gettype( $next_value )
                 ),
                 '5.8'
         );
 } else {
         $value = $next_value;
 }
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/51525#comment:21>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list