Abilities: Strip internal schema keywords from abilities REST responses.
Remove WordPress-internal properties (`sanitize_callback`, `validate_callback`, `arg_options`) from ability `input_schema` and `output_schema` fields in REST responses. These properties are used server-side but are not valid JSON Schema keywords and cause client-side validators to fail. Props jorgefilipecosta, ocean90, gziolo. Fixes #65035. Built from https://develop.svn.wordpress.org/trunk@62221 git-svn-id: http://core.svn.wordpress.org/trunk@61501 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
@@ -215,6 +215,81 @@ class WP_REST_Abilities_V1_List_Controller extends WP_REST_Controller {
|
|||||||
return $schema;
|
return $schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WordPress-internal schema keywords to strip from REST responses.
|
||||||
|
*
|
||||||
|
* @since 7.0.0
|
||||||
|
* @var array<string, true>
|
||||||
|
*/
|
||||||
|
private const INTERNAL_SCHEMA_KEYWORDS = array(
|
||||||
|
'sanitize_callback' => true,
|
||||||
|
'validate_callback' => true,
|
||||||
|
'arg_options' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively removes WordPress-internal keywords from a schema.
|
||||||
|
*
|
||||||
|
* Ability schemas may include WordPress-internal properties like
|
||||||
|
* `sanitize_callback`, `validate_callback`, and `arg_options` that are
|
||||||
|
* used server-side but are not valid JSON Schema keywords. This method
|
||||||
|
* removes those specific keys so they are not exposed in REST responses.
|
||||||
|
*
|
||||||
|
* @since 7.0.0
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $schema The schema array.
|
||||||
|
* @return array<string, mixed> The schema without WordPress-internal keywords.
|
||||||
|
*/
|
||||||
|
private function strip_internal_schema_keywords( array $schema ): array {
|
||||||
|
$schema = array_diff_key( $schema, self::INTERNAL_SCHEMA_KEYWORDS );
|
||||||
|
|
||||||
|
// Sub-schema maps: keys are user-defined, values are sub-schemas.
|
||||||
|
// Note: 'dependencies' values can also be property-dependency arrays
|
||||||
|
// (numeric arrays of strings) which are skipped via wp_is_numeric_array().
|
||||||
|
foreach ( array( 'properties', 'patternProperties', 'definitions', 'dependencies' ) as $keyword ) {
|
||||||
|
if ( isset( $schema[ $keyword ] ) && is_array( $schema[ $keyword ] ) ) {
|
||||||
|
foreach ( $schema[ $keyword ] as $key => $child_schema ) {
|
||||||
|
if ( is_array( $child_schema ) && ! wp_is_numeric_array( $child_schema ) ) {
|
||||||
|
$schema[ $keyword ][ $key ] = $this->strip_internal_schema_keywords( $child_schema );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single sub-schema keywords.
|
||||||
|
foreach ( array( 'not', 'additionalProperties', 'additionalItems' ) as $keyword ) {
|
||||||
|
if ( isset( $schema[ $keyword ] ) && is_array( $schema[ $keyword ] ) ) {
|
||||||
|
$schema[ $keyword ] = $this->strip_internal_schema_keywords( $schema[ $keyword ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items: single schema or tuple array of schemas.
|
||||||
|
if ( isset( $schema['items'] ) ) {
|
||||||
|
if ( wp_is_numeric_array( $schema['items'] ) ) {
|
||||||
|
foreach ( $schema['items'] as $index => $item_schema ) {
|
||||||
|
if ( is_array( $item_schema ) ) {
|
||||||
|
$schema['items'][ $index ] = $this->strip_internal_schema_keywords( $item_schema );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ( is_array( $schema['items'] ) ) {
|
||||||
|
$schema['items'] = $this->strip_internal_schema_keywords( $schema['items'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array-of-schemas keywords.
|
||||||
|
foreach ( array( 'anyOf', 'oneOf', 'allOf' ) as $keyword ) {
|
||||||
|
if ( isset( $schema[ $keyword ] ) && is_array( $schema[ $keyword ] ) ) {
|
||||||
|
foreach ( $schema[ $keyword ] as $index => $sub_schema ) {
|
||||||
|
if ( is_array( $sub_schema ) ) {
|
||||||
|
$schema[ $keyword ][ $index ] = $this->strip_internal_schema_keywords( $sub_schema );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares an ability for response.
|
* Prepares an ability for response.
|
||||||
*
|
*
|
||||||
@@ -230,8 +305,12 @@ class WP_REST_Abilities_V1_List_Controller extends WP_REST_Controller {
|
|||||||
'label' => $ability->get_label(),
|
'label' => $ability->get_label(),
|
||||||
'description' => $ability->get_description(),
|
'description' => $ability->get_description(),
|
||||||
'category' => $ability->get_category(),
|
'category' => $ability->get_category(),
|
||||||
'input_schema' => $this->normalize_schema_empty_object_defaults( $ability->get_input_schema() ),
|
'input_schema' => $this->strip_internal_schema_keywords(
|
||||||
'output_schema' => $this->normalize_schema_empty_object_defaults( $ability->get_output_schema() ),
|
$this->normalize_schema_empty_object_defaults( $ability->get_input_schema() )
|
||||||
|
),
|
||||||
|
'output_schema' => $this->strip_internal_schema_keywords(
|
||||||
|
$this->normalize_schema_empty_object_defaults( $ability->get_output_schema() )
|
||||||
|
),
|
||||||
'meta' => $ability->get_meta(),
|
'meta' => $ability->get_meta(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '7.1-alpha-62219';
|
$wp_version = '7.1-alpha-62221';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|||||||
Reference in New Issue
Block a user