函数文档

rest_find_one_matching_schema()

💡 云策文档标注

概述

rest_find_one_matching_schema() 函数用于在 JSON Schema 的 "oneOf" 结构中查找与给定值匹配的单个模式。它通过遍历模式数组并验证值,返回匹配的模式或错误信息。

关键要点

  • 函数用于处理 "oneOf" 模式匹配,确保值仅匹配一个模式。
  • 参数包括 $value(要验证的值)、$args(模式数组)、$param(参数名)和 $stop_after_first_match(可选,控制是否在首次匹配后停止)。
  • 返回匹配的模式数组或 WP_Error 实例(当匹配模式数不为一时)。
  • 内部使用 rest_validate_value_from_schema() 进行验证,并可能调用 rest_get_combining_operation_error() 处理错误。
  • 支持错误消息国际化,使用 __() 和 wp_sprintf() 函数。

代码示例

function rest_find_one_matching_schema( $value, $args, $param, $stop_after_first_match = false ) {
    $matching_schemas = array();
    $errors           = array();

    foreach ( $args['oneOf'] as $index => $schema ) {
        if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) {
            $schema['type'] = $args['type'];
        }

        $is_valid = rest_validate_value_from_schema( $value, $schema, $param );
        if ( ! is_wp_error( $is_valid ) ) {
            if ( $stop_after_first_match ) {
                return $schema;
            }

            $matching_schemas[] = array(
                'schema_object' => $schema,
                'index'         => $index,
            );
        } else {
            $errors[] = array(
                'error_object' => $is_valid,
                'schema'       => $schema,
                'index'        => $index,
            );
        }
    }

    if ( ! $matching_schemas ) {
        return rest_get_combining_operation_error( $value, $param, $errors );
    }

    if ( count( $matching_schemas ) > 1 ) {
        $schema_positions = array();
        $schema_titles    = array();

        foreach ( $matching_schemas as $schema ) {
            $schema_positions[] = $schema['index'];

            if ( isset( $schema['schema_object']['title'] ) ) {
                $schema_titles[] = $schema['schema_object']['title'];
            }
        }

        // If each schema has a title, include those titles in the error message.
        if ( count( $schema_titles ) === count( $matching_schemas ) ) {
            return new WP_Error(
                'rest_one_of_multiple_matches',
                /* translators: 1: Parameter, 2: Schema titles. */
                wp_sprintf( __( '%1$s matches %2$l, but should match only one.' ), $param, $schema_titles ),
                array( 'positions' => $schema_positions )
            );
        }

        return new WP_Error(
            'rest_one_of_multiple_matches',
            /* translators: %s: Parameter. */
            sprintf( __( '%s matches more than one of the expected formats.' ), $param ),
            array( 'positions' => $schema_positions )
        );
    }

    return $matching_schemas[0]['schema_object'];
}

注意事项

  • 函数自 WordPress 5.6.0 版本引入,用于 REST API 的 JSON Schema 验证。
  • 当 $stop_after_first_match 为 true 时,函数在首次匹配后立即返回,可能忽略其他潜在匹配。
  • 错误处理包括无匹配和多个匹配的情况,使用 WP_Error 提供详细错误信息。
  • 相关函数包括 rest_validate_value_from_schema() 和 rest_get_combining_operation_error(),用于辅助验证和错误生成。

📄 原文内容

Finds the matching schema among the “oneOf” schemas.

Parameters

$valuemixedrequired
The value to validate.
$argsarrayrequired
The schema array to use.
$paramstringrequired
The parameter name, used in error messages.
$stop_after_first_matchbooloptional
Whether the process should stop after the first successful match.

Default:false

Return

array|WP_Error The matching schema or WP_Error instance if the number of matching schemas is not equal to one.

Source

function rest_find_one_matching_schema( $value, $args, $param, $stop_after_first_match = false ) {
	$matching_schemas = array();
	$errors           = array();

	foreach ( $args['oneOf'] as $index => $schema ) {
		if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) {
			$schema['type'] = $args['type'];
		}

		$is_valid = rest_validate_value_from_schema( $value, $schema, $param );
		if ( ! is_wp_error( $is_valid ) ) {
			if ( $stop_after_first_match ) {
				return $schema;
			}

			$matching_schemas[] = array(
				'schema_object' => $schema,
				'index'         => $index,
			);
		} else {
			$errors[] = array(
				'error_object' => $is_valid,
				'schema'       => $schema,
				'index'        => $index,
			);
		}
	}

	if ( ! $matching_schemas ) {
		return rest_get_combining_operation_error( $value, $param, $errors );
	}

	if ( count( $matching_schemas ) > 1 ) {
		$schema_positions = array();
		$schema_titles    = array();

		foreach ( $matching_schemas as $schema ) {
			$schema_positions[] = $schema['index'];

			if ( isset( $schema['schema_object']['title'] ) ) {
				$schema_titles[] = $schema['schema_object']['title'];
			}
		}

		// If each schema has a title, include those titles in the error message.
		if ( count( $schema_titles ) === count( $matching_schemas ) ) {
			return new WP_Error(
				'rest_one_of_multiple_matches',
				/* translators: 1: Parameter, 2: Schema titles. */
				wp_sprintf( __( '%1$s matches %2$l, but should match only one.' ), $param, $schema_titles ),
				array( 'positions' => $schema_positions )
			);
		}

		return new WP_Error(
			'rest_one_of_multiple_matches',
			/* translators: %s: Parameter. */
			sprintf( __( '%s matches more than one of the expected formats.' ), $param ),
			array( 'positions' => $schema_positions )
		);
	}

	return $matching_schemas[0]['schema_object'];
}

Changelog

Version Description
5.6.0 Introduced.