REST API: Add support for the uniqueItems keyword.

Props sorenbronsted.
Fixes #48821.

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


git-svn-id: http://core.svn.wordpress.org/trunk@48126 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
TimothyBlynJacobs 2020-07-07 03:22:03 +00:00
parent 49d23a2bbe
commit d76e635459
2 changed files with 78 additions and 11 deletions

View File

@ -1438,6 +1438,63 @@ function rest_handle_multi_type_schema( $value, $args, $param = '' ) {
return $best_type;
}
/**
* Checks if an array is made up of unique items.
*
* @since 5.5.0
*
* @param array $array The array to check.
* @return bool True if the array contains unique items, false otherwise.
*/
function rest_validate_array_contains_unique_items( $array ) {
$seen = array();
foreach ( $array as $item ) {
$stabilized = rest_stabilize_value( $item );
$key = serialize( $stabilized );
if ( ! isset( $seen[ $key ] ) ) {
$seen[ $key ] = true;
continue;
}
return false;
}
return true;
}
/**
* Stabilizes a value following JSON Schema semantics.
*
* For lists, order is preserved. For objects, properties are reordered alphabetically.
*
* @since 5.5.0
*
* @param mixed $value The value to stabilize. Must already be sanitized. Objects should have been converted to arrays.
* @return mixed The stabilized value.
*/
function rest_stabilize_value( $value ) {
if ( is_scalar( $value ) || is_null( $value ) ) {
return $value;
}
if ( is_object( $value ) ) {
_doing_it_wrong( __FUNCTION__, __( 'Cannot stabilize objects. Convert the object to an array first.' ), '5.5.0' );
return $value;
}
ksort( $value );
foreach ( $value as $k => $v ) {
$value[ $k ] = rest_stabilize_value( $v );
}
return $value;
}
/**
* Validate a value based on a schema.
*
@ -1448,8 +1505,8 @@ function rest_handle_multi_type_schema( $value, $args, $param = '' ) {
* @since 5.4.0 Convert an empty string to an empty object.
* @since 5.5.0 Add the "uuid" and "hex-color" formats.
* Support the "minLength", "maxLength" and "pattern" keywords for strings.
* Support the "minItems", "maxItems" and "uniqueItems" keywords for arrays.
* Validate required properties.
* Support the "minItems" and "maxItems" keywords for arrays.
*
* @param mixed $value The value to validate.
* @param array $args Schema array to use for validation.
@ -1492,10 +1549,12 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
$value = rest_sanitize_array( $value );
foreach ( $value as $index => $v ) {
$is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
if ( isset( $args['items'] ) ) {
foreach ( $value as $index => $v ) {
$is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
}
}
}
@ -1508,6 +1567,11 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
/* translators: 1: Parameter, 2: Number. */
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
}
if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
/* translators: 1: Parameter */
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
}
}
if ( 'object' === $args['type'] ) {
@ -1718,7 +1782,7 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
* @param mixed $value The value to sanitize.
* @param array $args Schema array to use for sanitization.
* @param string $param The parameter name, used in error messages.
* @return mixed The sanitized value.
* @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
*/
function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
$allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
@ -1750,12 +1814,15 @@ function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
if ( 'array' === $args['type'] ) {
$value = rest_sanitize_array( $value );
if ( empty( $args['items'] ) ) {
return $value;
if ( ! empty( $args['items'] ) ) {
foreach ( $value as $index => $v ) {
$value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
}
}
foreach ( $value as $index => $v ) {
$value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
/* translators: 1: Parameter */
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
}
return $value;

View File

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