Make WordPress Core


Ignore:
Timestamp:
07/07/2020 03:20:34 AM (4 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Add support for the uniqueItems keyword.

Props sorenbronsted.
Fixes #48821.

File:
1 edited

Legend:

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

    r48307 r48357  
    14401440
    14411441/**
     1442 * Checks if an array is made up of unique items.
     1443 *
     1444 * @since 5.5.0
     1445 *
     1446 * @param array $array The array to check.
     1447 * @return bool True if the array contains unique items, false otherwise.
     1448 */
     1449function rest_validate_array_contains_unique_items( $array ) {
     1450    $seen = array();
     1451
     1452    foreach ( $array as $item ) {
     1453        $stabilized = rest_stabilize_value( $item );
     1454        $key        = serialize( $stabilized );
     1455
     1456        if ( ! isset( $seen[ $key ] ) ) {
     1457            $seen[ $key ] = true;
     1458
     1459            continue;
     1460        }
     1461
     1462        return false;
     1463    }
     1464
     1465    return true;
     1466}
     1467
     1468/**
     1469 * Stabilizes a value following JSON Schema semantics.
     1470 *
     1471 * For lists, order is preserved. For objects, properties are reordered alphabetically.
     1472 *
     1473 * @since 5.5.0
     1474 *
     1475 * @param mixed $value The value to stabilize. Must already be sanitized. Objects should have been converted to arrays.
     1476 * @return mixed The stabilized value.
     1477 */
     1478function rest_stabilize_value( $value ) {
     1479    if ( is_scalar( $value ) || is_null( $value ) ) {
     1480        return $value;
     1481    }
     1482
     1483    if ( is_object( $value ) ) {
     1484        _doing_it_wrong( __FUNCTION__, __( 'Cannot stabilize objects. Convert the object to an array first.' ), '5.5.0' );
     1485
     1486        return $value;
     1487    }
     1488
     1489    ksort( $value );
     1490
     1491    foreach ( $value as $k => $v ) {
     1492        $value[ $k ] = rest_stabilize_value( $v );
     1493    }
     1494
     1495    return $value;
     1496}
     1497
     1498/**
    14421499 * Validate a value based on a schema.
    14431500 *
     
    14491506 * @since 5.5.0 Add the "uuid" and "hex-color" formats.
    14501507 *              Support the "minLength", "maxLength" and "pattern" keywords for strings.
     1508 *              Support the "minItems", "maxItems" and "uniqueItems" keywords for arrays.
    14511509 *              Validate required properties.
    1452  *              Support the "minItems" and "maxItems" keywords for arrays.
    14531510 *
    14541511 * @param mixed  $value The value to validate.
     
    14931550        $value = rest_sanitize_array( $value );
    14941551
    1495         foreach ( $value as $index => $v ) {
    1496             $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
    1497             if ( is_wp_error( $is_valid ) ) {
    1498                 return $is_valid;
     1552        if ( isset( $args['items'] ) ) {
     1553            foreach ( $value as $index => $v ) {
     1554                $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
     1555                if ( is_wp_error( $is_valid ) ) {
     1556                    return $is_valid;
     1557                }
    14991558            }
    15001559        }
     
    15081567            /* translators: 1: Parameter, 2: Number. */
    15091568            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
     1569        }
     1570
     1571        if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
     1572            /* translators: 1: Parameter */
     1573            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
    15101574        }
    15111575    }
     
    17191783 * @param array  $args  Schema array to use for sanitization.
    17201784 * @param string $param The parameter name, used in error messages.
    1721  * @return mixed The sanitized value.
     1785 * @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
    17221786 */
    17231787function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
     
    17511815        $value = rest_sanitize_array( $value );
    17521816
    1753         if ( empty( $args['items'] ) ) {
    1754             return $value;
    1755         }
    1756 
    1757         foreach ( $value as $index => $v ) {
    1758             $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
     1817        if ( ! empty( $args['items'] ) ) {
     1818            foreach ( $value as $index => $v ) {
     1819                $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
     1820            }
     1821        }
     1822
     1823        if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
     1824            /* translators: 1: Parameter */
     1825            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
    17591826        }
    17601827
Note: See TracChangeset for help on using the changeset viewer.