rest_sanitize_value_from_schema

The timeline below displays how wordpress function rest_sanitize_value_from_schema has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 * @since 5.5.0 Added the `$param` parameter.
 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
 * @since 5.9.0 Added `text-field` and `textarea-field` formats.
 *
 * @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|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 = '')
{
    if (isset($args['anyOf'])) {
        $matching_schema = rest_find_any_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    if (isset($args['oneOf'])) {
        $matching_schema = rest_find_one_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    $allowed_types = array('array', 'object', 'string', 'number', 'integer', 'boolean', 'null');
    if (!isset($args['type'])) {
        /* translators: %s: Parameter. */
        _doing_it_wrong(__FUNCTION__, sprintf(__('The "type" schema keyword for %s is required.'), $param), '5.5.0');
    }
    if (is_array($args['type'])) {
        $best_type = rest_handle_multi_type_schema($value, $args, $param);
        if (!$best_type) {
            return null;
        }
        $args['type'] = $best_type;
    }
    if (!in_array($args['type'], $allowed_types, true)) {
        _doing_it_wrong(
            __FUNCTION__,
            /* translators: 1: Parameter, 2: The list of allowed types. */
            wp_sprintf(__('The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.'), $param, $allowed_types),
            '5.5.0'
        );
    }
    if ('array' === $args['type']) {
        $value = rest_sanitize_array($value);
        if (!empty($args['items'])) {
            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: %s: Parameter. */
            return new WP_Error('rest_duplicate_items', sprintf(__('%s has duplicate items.'), $param));
        }
        return $value;
    }
    if ('object' === $args['type']) {
        $value = rest_sanitize_object($value);
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property], $param . '[' . $property . ']');
                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'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties'], $param . '[' . $property . ']');
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    // This behavior matches rest_validate_value_from_schema().
    if (isset($args['format']) && (!isset($args['type']) || 'string' === $args['type'] || !in_array($args['type'], $allowed_types, true))) {
        switch ($args['format']) {
            case 'hex-color':
                return (string) sanitize_hex_color($value);
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return sanitize_url($value);
            case 'ip':
                return sanitize_text_field($value);
            case 'uuid':
                return sanitize_text_field($value);
            case 'text-field':
                return sanitize_text_field($value);
            case 'textarea-field':
                return sanitize_textarea_field($value);
        }
    }
    if ('string' === $args['type']) {
        return (string) $value;
    }
    return $value;
}

WordPress Version: 5.9

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 * @since 5.5.0 Added the `$param` parameter.
 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
 * @since 5.9.0 Added `text-field` and `textarea-field` formats.
 *
 * @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|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 = '')
{
    if (isset($args['anyOf'])) {
        $matching_schema = rest_find_any_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    if (isset($args['oneOf'])) {
        $matching_schema = rest_find_one_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    $allowed_types = array('array', 'object', 'string', 'number', 'integer', 'boolean', 'null');
    if (!isset($args['type'])) {
        /* translators: %s: Parameter. */
        _doing_it_wrong(__FUNCTION__, sprintf(__('The "type" schema keyword for %s is required.'), $param), '5.5.0');
    }
    if (is_array($args['type'])) {
        $best_type = rest_handle_multi_type_schema($value, $args, $param);
        if (!$best_type) {
            return null;
        }
        $args['type'] = $best_type;
    }
    if (!in_array($args['type'], $allowed_types, true)) {
        _doing_it_wrong(
            __FUNCTION__,
            /* translators: 1: Parameter, 2: The list of allowed types. */
            wp_sprintf(__('The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.'), $param, $allowed_types),
            '5.5.0'
        );
    }
    if ('array' === $args['type']) {
        $value = rest_sanitize_array($value);
        if (!empty($args['items'])) {
            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: %s: Parameter. */
            return new WP_Error('rest_duplicate_items', sprintf(__('%s has duplicate items.'), $param));
        }
        return $value;
    }
    if ('object' === $args['type']) {
        $value = rest_sanitize_object($value);
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property], $param . '[' . $property . ']');
                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'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties'], $param . '[' . $property . ']');
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    // This behavior matches rest_validate_value_from_schema().
    if (isset($args['format']) && (!isset($args['type']) || 'string' === $args['type'] || !in_array($args['type'], $allowed_types, true))) {
        switch ($args['format']) {
            case 'hex-color':
                return (string) sanitize_hex_color($value);
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
            case 'uuid':
                return sanitize_text_field($value);
            case 'text-field':
                return sanitize_text_field($value);
            case 'textarea-field':
                return sanitize_textarea_field($value);
        }
    }
    if ('string' === $args['type']) {
        return (string) $value;
    }
    return $value;
}

WordPress Version: 5.7

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 * @since 5.5.0 Added the `$param` parameter.
 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
 *
 * @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|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 = '')
{
    if (isset($args['anyOf'])) {
        $matching_schema = rest_find_any_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    if (isset($args['oneOf'])) {
        $matching_schema = rest_find_one_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    $allowed_types = array('array', 'object', 'string', 'number', 'integer', 'boolean', 'null');
    if (!isset($args['type'])) {
        /* translators: %s: Parameter. */
        _doing_it_wrong(__FUNCTION__, sprintf(__('The "type" schema keyword for %s is required.'), $param), '5.5.0');
    }
    if (is_array($args['type'])) {
        $best_type = rest_handle_multi_type_schema($value, $args, $param);
        if (!$best_type) {
            return null;
        }
        $args['type'] = $best_type;
    }
    if (!in_array($args['type'], $allowed_types, true)) {
        _doing_it_wrong(
            __FUNCTION__,
            /* translators: 1: Parameter, 2: The list of allowed types. */
            wp_sprintf(__('The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.'), $param, $allowed_types),
            '5.5.0'
        );
    }
    if ('array' === $args['type']) {
        $value = rest_sanitize_array($value);
        if (!empty($args['items'])) {
            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: %s: Parameter. */
            return new WP_Error('rest_duplicate_items', sprintf(__('%s has duplicate items.'), $param));
        }
        return $value;
    }
    if ('object' === $args['type']) {
        $value = rest_sanitize_object($value);
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property], $param . '[' . $property . ']');
                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'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties'], $param . '[' . $property . ']');
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    // This behavior matches rest_validate_value_from_schema().
    if (isset($args['format']) && (!isset($args['type']) || 'string' === $args['type'] || !in_array($args['type'], $allowed_types, true))) {
        switch ($args['format']) {
            case 'hex-color':
                return (string) sanitize_hex_color($value);
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
            case 'uuid':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return (string) $value;
    }
    return $value;
}

WordPress Version: 5.6

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 * @since 5.5.0 Added the `$param` parameter.
 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
 *
 * @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|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 = '')
{
    if (isset($args['anyOf'])) {
        $matching_schema = rest_find_any_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    if (isset($args['oneOf'])) {
        $matching_schema = rest_find_one_matching_schema($value, $args, $param);
        if (is_wp_error($matching_schema)) {
            return $matching_schema;
        }
        if (!isset($args['type'])) {
            $args['type'] = $matching_schema['type'];
        }
        $value = rest_sanitize_value_from_schema($value, $matching_schema, $param);
    }
    $allowed_types = array('array', 'object', 'string', 'number', 'integer', 'boolean', 'null');
    if (!isset($args['type'])) {
        /* translators: %s: Parameter. */
        _doing_it_wrong(__FUNCTION__, sprintf(__('The "type" schema keyword for %s is required.'), $param), '5.5.0');
    }
    if (is_array($args['type'])) {
        $best_type = rest_handle_multi_type_schema($value, $args, $param);
        if (!$best_type) {
            return null;
        }
        $args['type'] = $best_type;
    }
    if (!in_array($args['type'], $allowed_types, true)) {
        _doing_it_wrong(
            __FUNCTION__,
            /* translators: 1: Parameter, 2: The list of allowed types. */
            wp_sprintf(__('The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.'), $param, $allowed_types),
            '5.5.0'
        );
    }
    if ('array' === $args['type']) {
        $value = rest_sanitize_array($value);
        if (!empty($args['items'])) {
            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;
    }
    if ('object' === $args['type']) {
        $value = rest_sanitize_object($value);
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property], $param . '[' . $property . ']');
                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'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties'], $param . '[' . $property . ']');
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    // This behavior matches rest_validate_value_from_schema().
    if (isset($args['format']) && (!isset($args['type']) || 'string' === $args['type'] || !in_array($args['type'], $allowed_types, true))) {
        switch ($args['format']) {
            case 'hex-color':
                return (string) sanitize_hex_color($value);
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
            case 'uuid':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return (string) $value;
    }
    return $value;
}

WordPress Version: 5.5

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 * @since 5.5.0 Added the `$param` parameter.
 *
 * @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|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');
    if (!isset($args['type'])) {
        /* translators: 1. Parameter */
        _doing_it_wrong(__FUNCTION__, sprintf(__('The "type" schema keyword for %s is required.'), $param), '5.5.0');
    }
    if (is_array($args['type'])) {
        $best_type = rest_handle_multi_type_schema($value, $args, $param);
        if (!$best_type) {
            return null;
        }
        $args['type'] = $best_type;
    }
    if (!in_array($args['type'], $allowed_types, true)) {
        _doing_it_wrong(
            __FUNCTION__,
            /* translators: 1. Parameter. 2. The list of allowed types. */
            wp_sprintf(__('The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.'), $param, $allowed_types),
            '5.5.0'
        );
    }
    if ('array' === $args['type']) {
        $value = rest_sanitize_array($value);
        if (!empty($args['items'])) {
            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;
    }
    if ('object' === $args['type']) {
        $value = rest_sanitize_object($value);
        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'])) {
                if (false === $args['additionalProperties']) {
                    unset($value[$property]);
                } elseif (is_array($args['additionalProperties'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties'], $param . '[' . $property . ']');
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    // This behavior matches rest_validate_value_from_schema().
    if (isset($args['format']) && (!isset($args['type']) || 'string' === $args['type'] || !in_array($args['type'], $allowed_types, true))) {
        switch ($args['format']) {
            case 'hex-color':
                return (string) sanitize_hex_color($value);
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
            case 'uuid':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 5.4

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if (is_array($args['type'])) {
        // Determine which type the value was validated against,
        // and use that type when performing sanitization.
        $validated_type = '';
        foreach ($args['type'] as $type) {
            $type_args = $args;
            $type_args['type'] = $type;
            if (!is_wp_error(rest_validate_value_from_schema($value, $type_args))) {
                $validated_type = $type;
                break;
            }
        }
        if (!$validated_type) {
            return null;
        }
        $args['type'] = $validated_type;
    }
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        $value = wp_parse_list($value);
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('object' === $args['type']) {
        if ($value instanceof stdClass) {
            $value = (array) $value;
        }
        if ($value instanceof JsonSerializable) {
            $value = $value->jsonSerialize();
        }
        if (!is_array($value)) {
            return array();
        }
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property]);
            } elseif (isset($args['additionalProperties'])) {
                if (false === $args['additionalProperties']) {
                    unset($value[$property]);
                } elseif (is_array($args['additionalProperties'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties']);
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                // sanitize_email() validates, which would be unexpected.
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 5.3

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if (is_array($args['type'])) {
        // Determine which type the value was validated against, and use that type when performing sanitization
        $validated_type = '';
        foreach ($args['type'] as $type) {
            $type_args = $args;
            $type_args['type'] = $type;
            if (!is_wp_error(rest_validate_value_from_schema($value, $type_args))) {
                $validated_type = $type;
                break;
            }
        }
        if (!$validated_type) {
            return null;
        }
        $args['type'] = $validated_type;
    }
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        $value = wp_parse_list($value);
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected
        // is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('object' === $args['type']) {
        if ($value instanceof stdClass) {
            $value = (array) $value;
        }
        if ($value instanceof JsonSerializable) {
            $value = $value->jsonSerialize();
        }
        if (!is_array($value)) {
            return array();
        }
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property]);
            } elseif (isset($args['additionalProperties'])) {
                if (false === $args['additionalProperties']) {
                    unset($value[$property]);
                } elseif (is_array($args['additionalProperties'])) {
                    $value[$property] = rest_sanitize_value_from_schema($v, $args['additionalProperties']);
                }
            }
        }
        return $value;
    }
    if ('null' === $args['type']) {
        return null;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                /*
                 * sanitize_email() validates, which would be unexpected.
                 */
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 5.1

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        $value = wp_parse_list($value);
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected
        // is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('object' === $args['type']) {
        if ($value instanceof stdClass) {
            $value = (array) $value;
        }
        if (!is_array($value)) {
            return array();
        }
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property]);
            } elseif (isset($args['additionalProperties']) && false === $args['additionalProperties']) {
                unset($value[$property]);
            }
        }
        return $value;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                /*
                 * sanitize_email() validates, which would be unexpected.
                 */
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 4.9

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        if (!is_array($value)) {
            $value = preg_split('/[\s,]+/', $value);
        }
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected
        // is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('object' === $args['type']) {
        if ($value instanceof stdClass) {
            $value = (array) $value;
        }
        if (!is_array($value)) {
            return array();
        }
        foreach ($value as $property => $v) {
            if (isset($args['properties'][$property])) {
                $value[$property] = rest_sanitize_value_from_schema($v, $args['properties'][$property]);
            } elseif (isset($args['additionalProperties']) && false === $args['additionalProperties']) {
                unset($value[$property]);
            }
        }
        return $value;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                /*
                 * sanitize_email() validates, which would be unexpected.
                 */
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 4.8

/**
 * Sanitize a value based on a schema.
 *
 * @since 4.7.0
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        if (!is_array($value)) {
            $value = preg_split('/[\s,]+/', $value);
        }
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected
        // is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                /*
                 * sanitize_email() validates, which would be unexpected.
                 */
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}

WordPress Version: 4.7

/**
 * Sanitize a value based on a schema.
 *
 * @param mixed $value The value to sanitize.
 * @param array $args  Schema array to use for sanitization.
 * @return true|WP_Error
 */
function rest_sanitize_value_from_schema($value, $args)
{
    if ('array' === $args['type']) {
        if (empty($args['items'])) {
            return (array) $value;
        }
        if (!is_array($value)) {
            $value = preg_split('/[\s,]+/', $value);
        }
        foreach ($value as $index => $v) {
            $value[$index] = rest_sanitize_value_from_schema($v, $args['items']);
        }
        // Normalize to numeric array so nothing unexpected
        // is in the keys.
        $value = array_values($value);
        return $value;
    }
    if ('integer' === $args['type']) {
        return (int) $value;
    }
    if ('number' === $args['type']) {
        return (float) $value;
    }
    if ('boolean' === $args['type']) {
        return rest_sanitize_boolean($value);
    }
    if (isset($args['format'])) {
        switch ($args['format']) {
            case 'date-time':
                return sanitize_text_field($value);
            case 'email':
                /*
                 * sanitize_email() validates, which would be unexpected.
                 */
                return sanitize_text_field($value);
            case 'uri':
                return esc_url_raw($value);
            case 'ip':
                return sanitize_text_field($value);
        }
    }
    if ('string' === $args['type']) {
        return strval($value);
    }
    return $value;
}