diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 06bb9f9..34e1c59 100644
|
a
|
b
|
function rest_validate_value_from_schema( $value, $args, $param = '' ) { |
| 1051 | 1051 | } |
| 1052 | 1052 | } |
| 1053 | 1053 | } |
| | 1054 | |
| | 1055 | if ( 'object' === $args['type'] ) { |
| | 1056 | if ( $value instanceof stdClass ) { |
| | 1057 | $value = (array) $value; |
| | 1058 | } |
| | 1059 | if ( ! is_array( $value ) ) { |
| | 1060 | /* translators: 1: parameter, 2: type name */ |
| | 1061 | return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ) ); |
| | 1062 | } |
| | 1063 | |
| | 1064 | foreach ( $value as $property => $v ) { |
| | 1065 | if ( ! isset( $args['properties'][ $property ] ) ) { |
| | 1066 | continue; |
| | 1067 | } |
| | 1068 | $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' ); |
| | 1069 | |
| | 1070 | if ( is_wp_error( $is_valid ) ) { |
| | 1071 | return $is_valid; |
| | 1072 | } |
| | 1073 | } |
| | 1074 | } |
| | 1075 | |
| 1054 | 1076 | if ( ! empty( $args['enum'] ) ) { |
| 1055 | 1077 | if ( ! in_array( $value, $args['enum'], true ) ) { |
| 1056 | 1078 | /* translators: 1: parameter, 2: list of valid values */ |
| … |
… |
function rest_sanitize_value_from_schema( $value, $args ) { |
| 1170 | 1192 | $value = array_values( $value ); |
| 1171 | 1193 | return $value; |
| 1172 | 1194 | } |
| | 1195 | |
| | 1196 | if ( 'object' === $args['type'] ) { |
| | 1197 | if ( $value instanceof stdClass ) { |
| | 1198 | $value = (array) $value; |
| | 1199 | } |
| | 1200 | if ( ! is_array( $value ) ) { |
| | 1201 | return array(); |
| | 1202 | } |
| | 1203 | |
| | 1204 | foreach ( $value as $property => $v ) { |
| | 1205 | if ( ! isset( $args['properties'][ $property ] ) ) { |
| | 1206 | unset( $value[ $property ] ); |
| | 1207 | continue; |
| | 1208 | } |
| | 1209 | $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ] ); |
| | 1210 | } |
| | 1211 | |
| | 1212 | return $value; |
| | 1213 | } |
| | 1214 | |
| 1173 | 1215 | if ( 'integer' === $args['type'] ) { |
| 1174 | 1216 | return (int) $value; |
| 1175 | 1217 | } |
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
index 76802fe..ed10181 100644
|
a
|
b
|
class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { |
| 391 | 391 | 'context' => array( 'view', 'edit', 'embed' ), |
| 392 | 392 | 'arg_options' => array( |
| 393 | 393 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 394 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 394 | 395 | ), |
| 395 | 396 | 'properties' => array( |
| 396 | 397 | 'raw' => array( |
| … |
… |
class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { |
| 413 | 414 | 'context' => array( 'view', 'edit' ), |
| 414 | 415 | 'arg_options' => array( |
| 415 | 416 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 417 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 416 | 418 | ), |
| 417 | 419 | 'properties' => array( |
| 418 | 420 | 'raw' => array( |
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
index 810a3fb..415ba8e 100644
|
a
|
b
|
class WP_REST_Comments_Controller extends WP_REST_Controller { |
| 1200 | 1200 | 'context' => array( 'view', 'edit', 'embed' ), |
| 1201 | 1201 | 'arg_options' => array( |
| 1202 | 1202 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 1203 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 1203 | 1204 | ), |
| 1204 | 1205 | 'properties' => array( |
| 1205 | 1206 | 'raw' => array( |
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 018b66e..80027cf 100644
|
a
|
b
|
class WP_REST_Posts_Controller extends WP_REST_Controller { |
| 1846 | 1846 | 'context' => array( 'view', 'edit', 'embed' ), |
| 1847 | 1847 | 'arg_options' => array( |
| 1848 | 1848 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 1849 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 1849 | 1850 | ), |
| 1850 | 1851 | 'properties' => array( |
| 1851 | 1852 | 'raw' => array( |
| … |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
| 1870 | 1871 | 'context' => array( 'view', 'edit' ), |
| 1871 | 1872 | 'arg_options' => array( |
| 1872 | 1873 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 1874 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 1873 | 1875 | ), |
| 1874 | 1876 | 'properties' => array( |
| 1875 | 1877 | 'raw' => array( |
| … |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
| 1908 | 1910 | 'context' => array( 'view', 'edit', 'embed' ), |
| 1909 | 1911 | 'arg_options' => array( |
| 1910 | 1912 | 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database() |
| | 1913 | 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() |
| 1911 | 1914 | ), |
| 1912 | 1915 | 'properties' => array( |
| 1913 | 1916 | 'raw' => array( |
diff --git a/tests/phpunit/tests/rest-api/rest-schema-sanitization.php b/tests/phpunit/tests/rest-api/rest-schema-sanitization.php
index e1ae29d..cb224b3 100644
|
a
|
b
|
class WP_Test_REST_Schema_Sanitization extends WP_UnitTestCase { |
| 146 | 146 | $this->assertEquals( array( '1', '2' ), rest_sanitize_value_from_schema( array( 'first' => '1', 'second' => '2' ), $schema ) ); |
| 147 | 147 | } |
| 148 | 148 | |
| | 149 | public function test_type_object() { |
| | 150 | $schema = array( |
| | 151 | 'type' => 'object', |
| | 152 | 'properties' => array( |
| | 153 | 'a' => array( |
| | 154 | 'type' => 'number' |
| | 155 | ), |
| | 156 | ), |
| | 157 | ); |
| | 158 | $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => 1 ), $schema ) ); |
| | 159 | $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => '1' ), $schema ) ); |
| | 160 | } |
| | 161 | |
| | 162 | public function test_type_object_nested() { |
| | 163 | $schema = array( |
| | 164 | 'type' => 'object', |
| | 165 | 'properties' => array( |
| | 166 | 'a' => array( |
| | 167 | 'type' => 'object', |
| | 168 | 'properties' => array( |
| | 169 | 'b' => array( 'type' => 'number' ), |
| | 170 | 'c' => array( 'type' => 'number' ), |
| | 171 | ) |
| | 172 | ) |
| | 173 | ), |
| | 174 | ); |
| | 175 | |
| | 176 | $this->assertEquals( |
| | 177 | array( |
| | 178 | 'a' => array( |
| | 179 | 'b' => 1, |
| | 180 | 'c' => 3, |
| | 181 | ), |
| | 182 | ), |
| | 183 | rest_sanitize_value_from_schema( |
| | 184 | array( |
| | 185 | 'a' => array( |
| | 186 | 'b' => '1', |
| | 187 | 'c' => '3', |
| | 188 | ), |
| | 189 | ), |
| | 190 | $schema |
| | 191 | ) |
| | 192 | ); |
| | 193 | $this->assertEquals( |
| | 194 | array( |
| | 195 | 'a' => array( |
| | 196 | 'b' => 1, |
| | 197 | 'c' => 3, |
| | 198 | ), |
| | 199 | ), |
| | 200 | rest_sanitize_value_from_schema( |
| | 201 | array( |
| | 202 | 'a' => array( |
| | 203 | 'b' => '1', |
| | 204 | 'c' => '3', |
| | 205 | 'd' => '1', |
| | 206 | ), |
| | 207 | 'b' => 1, |
| | 208 | ), |
| | 209 | $schema |
| | 210 | ) |
| | 211 | ); |
| | 212 | $this->assertEquals( array( 'a' => array() ), rest_sanitize_value_from_schema( array( 'a' => null ), $schema ) ); |
| | 213 | } |
| | 214 | |
| | 215 | public function test_type_object_stdclass() { |
| | 216 | $schema = array( |
| | 217 | 'type' => 'object', |
| | 218 | 'properties' => array( |
| | 219 | 'a' => array( |
| | 220 | 'type' => 'number' |
| | 221 | ), |
| | 222 | ), |
| | 223 | ); |
| | 224 | $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( (object) array( 'a' => '1' ), $schema ) ); |
| | 225 | } |
| | 226 | |
| 149 | 227 | public function test_type_unknown() { |
| 150 | 228 | $schema = array( |
| 151 | 229 | 'type' => 'lalala', |
diff --git a/tests/phpunit/tests/rest-api/rest-schema-validation.php b/tests/phpunit/tests/rest-api/rest-schema-validation.php
index 82f58e5..9932538 100644
|
a
|
b
|
class WP_Test_REST_Schema_Validation extends WP_UnitTestCase { |
| 181 | 181 | $this->assertWPError( rest_validate_value_from_schema( array( 'first' => '1', 'second' => '2' ), $schema ) ); |
| 182 | 182 | } |
| 183 | 183 | |
| | 184 | public function test_type_object() { |
| | 185 | $schema = array( |
| | 186 | 'type' => 'object', |
| | 187 | 'properties' => array( |
| | 188 | 'a' => array( |
| | 189 | 'type' => 'number' |
| | 190 | ), |
| | 191 | ), |
| | 192 | ); |
| | 193 | $this->assertTrue( rest_validate_value_from_schema( array( 'a' => 1 ), $schema ) ); |
| | 194 | $this->assertWPError( rest_validate_value_from_schema( array( 'a' => 'invalid' ), $schema ) ); |
| | 195 | } |
| | 196 | |
| | 197 | public function test_type_object_nested() { |
| | 198 | $schema = array( |
| | 199 | 'type' => 'object', |
| | 200 | 'properties' => array( |
| | 201 | 'a' => array( |
| | 202 | 'type' => 'object', |
| | 203 | 'properties' => array( |
| | 204 | 'b' => array( 'type' => 'number' ), |
| | 205 | 'c' => array( 'type' => 'number' ), |
| | 206 | ) |
| | 207 | ) |
| | 208 | ), |
| | 209 | ); |
| | 210 | $this->assertTrue( |
| | 211 | rest_validate_value_from_schema( |
| | 212 | array( |
| | 213 | 'a' => array( |
| | 214 | 'b' => '1', |
| | 215 | 'c' => 3, |
| | 216 | ), |
| | 217 | ), |
| | 218 | $schema |
| | 219 | ) |
| | 220 | ); |
| | 221 | $this->assertWPError( rest_validate_value_from_schema( array( 'a' => array( 'b' => 1, 'c' => 'invalid' ) ), $schema ) ); |
| | 222 | $this->assertWPError( rest_validate_value_from_schema( array( 'a' => 1 ), $schema ) ); |
| | 223 | } |
| | 224 | |
| | 225 | public function test_type_object_stdclass() { |
| | 226 | $schema = array( |
| | 227 | 'type' => 'object', |
| | 228 | 'properties' => array( |
| | 229 | 'a' => array( |
| | 230 | 'type' => 'number' |
| | 231 | ), |
| | 232 | ), |
| | 233 | ); |
| | 234 | $this->assertTrue( rest_validate_value_from_schema( (object) array( 'a' => 1 ), $schema ) ); |
| | 235 | } |
| | 236 | |
| 184 | 237 | public function test_type_unknown() { |
| 185 | 238 | $schema = array( |
| 186 | 239 | 'type' => 'lalala', |