From 8a62f46beb934744aaec1377972007885976960f Mon Sep 17 00:00:00 2001 From: Timothy Jacobs Date: Thu, 20 Feb 2020 16:56:17 +0000 Subject: [PATCH] REST API: Don't assume all item schemas have properties. All schema types, not just objects, are permitted as the base type of a resource. A future patch could add validation support for those types, but this fix only prevents a PHP warning from being issued. Props dhavalkasvala, johnwatkins0, birgire. Fixes #48785. git-svn-id: https://develop.svn.wordpress.org/trunk@47328 602fd350-edb4-49c9-b593-d223f7449a82 --- .../endpoints/class-wp-rest-controller.php | 6 +- tests/phpunit/includes/bootstrap.php | 1 + ...s-wp-rest-test-configurable-controller.php | 60 +++++++++++++++++++ .../tests/rest-api/rest-controller.php | 33 ++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tests/phpunit/includes/class-wp-rest-test-configurable-controller.php diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php index dd40d93d2b..b32f012542 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php @@ -344,8 +344,10 @@ abstract class WP_REST_Controller { $schema = $this->get_item_schema(); - foreach ( $schema['properties'] as &$property ) { - unset( $property['arg_options'] ); + if ( ! empty( $schema['properties'] ) ) { + foreach ( $schema['properties'] as &$property ) { + unset( $property['arg_options'] ); + } } return $schema; diff --git a/tests/phpunit/includes/bootstrap.php b/tests/phpunit/includes/bootstrap.php index 2f48fc6bb2..ed0a35bc66 100644 --- a/tests/phpunit/includes/bootstrap.php +++ b/tests/phpunit/includes/bootstrap.php @@ -154,6 +154,7 @@ require __DIR__ . '/exceptions.php'; require __DIR__ . '/utils.php'; require __DIR__ . '/spy-rest-server.php'; require __DIR__ . '/class-wp-rest-test-search-handler.php'; +require __DIR__ . '/class-wp-rest-test-configurable-controller.php'; require __DIR__ . '/class-wp-fake-block-type.php'; /** diff --git a/tests/phpunit/includes/class-wp-rest-test-configurable-controller.php b/tests/phpunit/includes/class-wp-rest-test-configurable-controller.php new file mode 100644 index 0000000000..f67bbeb5ae --- /dev/null +++ b/tests/phpunit/includes/class-wp-rest-test-configurable-controller.php @@ -0,0 +1,60 @@ +test_schema = $test_schema; + } + + /** + * Provides the test schema. + * + * @since 5.4.0 + * + * @return array Test schema. + */ + public function get_test_schema() { + return $this->test_schema; + } + + /** + * Get the item's schema, conforming to JSON Schema. + * + * @since 5.4.0 + * + * @return array + */ + public function get_item_schema() { + return $this->add_additional_fields_schema( $this->get_test_schema() ); + } +} diff --git a/tests/phpunit/tests/rest-api/rest-controller.php b/tests/phpunit/tests/rest-api/rest-controller.php index 91e1d0c5b7..6de5cf5482 100644 --- a/tests/phpunit/tests/rest-api/rest-controller.php +++ b/tests/phpunit/tests/rest-api/rest-controller.php @@ -343,6 +343,39 @@ class WP_Test_REST_Controller extends WP_Test_REST_TestCase { $this->assertGreaterThan( 0, $listener->get_call_count( $method ) ); } + /** + * @ticket 48785 + */ + public function test_get_public_item_schema_with_properties() { + $schema = ( new WP_REST_Test_Controller() )->get_public_item_schema(); + + // Double-check that the public item schema set in WP_REST_Test_Controller still has properties. + $this->assertArrayHasKey( 'properties', $schema ); + + // But arg_options should be removed. + $this->assertArrayNotHasKey( 'arg_options', $schema['properties']['someargoptions'] ); + } + + /** + * @ticket 48785 + */ + public function test_get_public_item_schema_no_properties() { + $controller = new WP_REST_Test_Configurable_Controller( + array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'foo', + 'type' => 'string', + 'description' => 'This is my magical endpoint that just returns a string.', + ) + ); + + // Initial check that the test class is working as expected. + $this->assertArrayNotHasKey( 'properties', $controller->get_public_item_schema() ); + + // Test that the schema lacking 'properties' is returned as expected. + $this->assertEqualSetsWithIndex( $controller->get_public_item_schema(), $controller->get_test_schema() ); + } + public function test_add_additional_fields_to_object_respects_fields_param() { $controller = new WP_REST_Test_Controller(); $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );