REST API: Support the patternProperties JSON Schema keyword.

Props yakimun.
Fixes #51024.

Built from https://develop.svn.wordpress.org/trunk@49082


git-svn-id: http://core.svn.wordpress.org/trunk@48844 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
TimothyBlynJacobs 2020-10-01 02:49:12 +00:00
parent 0d52ba511c
commit 69b9b23c49
2 changed files with 80 additions and 11 deletions

View File

@ -1539,6 +1539,42 @@ function rest_stabilize_value( $value ) {
return $value;
}
/**
* Validates if the JSON Schema pattern matches a value.
*
* @since 5.6.0
*
* @param string $pattern The pattern to match against.
* @param string $value The value to check.
* @return bool True if the pattern matches the given value, false otherwise.
*/
function rest_validate_json_schema_pattern( $pattern, $value ) {
$escaped_pattern = str_replace( '#', '\\#', $pattern );
return 1 === preg_match( '#' . $escaped_pattern . '#u', $value );
}
/**
* Finds the schema for a property using the patternProperties keyword.
*
* @since 5.6.0
*
* @param string $property The property name to check.
* @param array $args The schema array to use.
* @return array|null The schema of matching pattern property, or null if no patterns match.
*/
function rest_find_matching_pattern_property_schema( $property, $args ) {
if ( isset( $args['patternProperties'] ) ) {
foreach ( $args['patternProperties'] as $pattern => $child_schema ) {
if ( rest_validate_json_schema_pattern( $pattern, $property ) ) {
return $child_schema;
}
}
}
return null;
}
/**
* Validate a value based on a schema.
*
@ -1553,6 +1589,7 @@ function rest_stabilize_value( $value ) {
* Validate required properties.
* @since 5.6.0 Support the "minProperties" and "maxProperties" keywords for objects.
* Support the "multipleOf" keyword for numbers and integers.
* Support the "patternProperties" keyword for objects.
*
* @param mixed $value The value to validate.
* @param array $args Schema array to use for validation.
@ -1650,7 +1687,19 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
}
} elseif ( isset( $args['additionalProperties'] ) ) {
continue;
}
$pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
if ( null !== $pattern_property_schema ) {
$is_valid = rest_validate_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
}
continue;
}
if ( isset( $args['additionalProperties'] ) ) {
if ( false === $args['additionalProperties'] ) {
/* translators: %s: Property of an object. */
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) );
@ -1744,12 +1793,9 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
);
}
if ( isset( $args['pattern'] ) ) {
$pattern = str_replace( '#', '\\#', $args['pattern'] );
if ( ! preg_match( '#' . $pattern . '#u', $value ) ) {
/* translators: 1: Parameter, 2: Pattern. */
return new WP_Error( 'rest_invalid_pattern', sprintf( __( '%1$s does not match pattern %2$s.' ), $param, $args['pattern'] ) );
}
if ( isset( $args['pattern'] ) && ! rest_validate_json_schema_pattern( $args['pattern'], $value ) ) {
/* translators: 1: Parameter, 2: Pattern. */
return new WP_Error( 'rest_invalid_pattern', sprintf( __( '%1$s does not match pattern %2$s.' ), $param, $args['pattern'] ) );
}
}
@ -1897,7 +1943,16 @@ function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
foreach ( $value as $property => $v ) {
if ( isset( $args['properties'][ $property ] ) ) {
$value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );
} elseif ( isset( $args['additionalProperties'] ) ) {
continue;
}
$pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
if ( null !== $pattern_property_schema ) {
$value[ $property ] = rest_sanitize_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
continue;
}
if ( isset( $args['additionalProperties'] ) ) {
if ( false === $args['additionalProperties'] ) {
unset( $value[ $property ] );
} elseif ( is_array( $args['additionalProperties'] ) ) {
@ -2053,6 +2108,7 @@ function rest_parse_embed_param( $embed ) {
* Filters the response to remove any fields not available in the given context.
*
* @since 5.5.0
* @since 5.6.0 Support the "patternProperties" keyword for objects.
*
* @param array|object $data The response data to modify.
* @param array $schema The schema for the endpoint used to filter the response.
@ -2093,8 +2149,13 @@ function rest_filter_response_by_context( $data, $schema, $context ) {
} elseif ( $is_object_type ) {
if ( isset( $schema['properties'][ $key ] ) ) {
$check = $schema['properties'][ $key ];
} elseif ( $has_additional_properties ) {
$check = $schema['additionalProperties'];
} else {
$pattern_property_schema = rest_find_matching_pattern_property_schema( $key, $schema );
if ( null !== $pattern_property_schema ) {
$check = $pattern_property_schema;
} elseif ( $has_additional_properties ) {
$check = $schema['additionalProperties'];
}
}
}
@ -2132,6 +2193,7 @@ function rest_filter_response_by_context( $data, $schema, $context ) {
* Sets the "additionalProperties" to false by default for all object definitions in the schema.
*
* @since 5.5.0
* @since 5.6.0 Support the "patternProperties" keyword.
*
* @param array $schema The schema to modify.
* @return array The modified schema.
@ -2146,6 +2208,12 @@ function rest_default_additional_properties_to_false( $schema ) {
}
}
if ( isset( $schema['patternProperties'] ) ) {
foreach ( $schema['patternProperties'] as $key => $child_schema ) {
$schema['patternProperties'][ $key ] = rest_default_additional_properties_to_false( $child_schema );
}
}
if ( ! isset( $schema['additionalProperties'] ) ) {
$schema['additionalProperties'] = false;
}
@ -2300,6 +2368,7 @@ function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::C
'items',
'properties',
'additionalProperties',
'patternProperties',
'minProperties',
'maxProperties',
'minimum',

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.6-alpha-49081';
$wp_version = '5.6-alpha-49082';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.