Changeset 48306 for trunk/src/wp-includes/rest-api.php
- Timestamp:
- 07/05/2020 12:13:37 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r48302 r48306 987 987 988 988 /** 989 * Parses an RFC3339 time into a Unix timestamp.990 *991 * @since 4.4.0992 *993 * @param string $date RFC3339 timestamp.994 * @param bool $force_utc Optional. Whether to force UTC timezone instead of using995 * the timestamp's timezone. Default false.996 * @return int Unix timestamp.997 */998 function rest_parse_date( $date, $force_utc = false ) {999 if ( $force_utc ) {1000 $date = preg_replace( '/[+-]\d+:?\d+$/', '+00:00', $date );1001 }1002 1003 $regex = '#^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}(?::\d{2})?)?$#';1004 1005 if ( ! preg_match( $regex, $date, $matches ) ) {1006 return false;1007 }1008 1009 return strtotime( $date );1010 }1011 1012 /**1013 * Parses a 3 or 6 digit hex color (with #).1014 *1015 * @since 5.4.01016 *1017 * @param string $color 3 or 6 digit hex color (with #).1018 * @return string|false1019 */1020 function rest_parse_hex_color( $color ) {1021 $regex = '|^#([A-Fa-f0-9]{3}){1,2}$|';1022 if ( ! preg_match( $regex, $color, $matches ) ) {1023 return false;1024 }1025 1026 return $color;1027 }1028 1029 /**1030 * Parses a date into both its local and UTC equivalent, in MySQL datetime format.1031 *1032 * @since 4.4.01033 *1034 * @see rest_parse_date()1035 *1036 * @param string $date RFC3339 timestamp.1037 * @param bool $is_utc Whether the provided date should be interpreted as UTC. Default false.1038 * @return array|null Local and UTC datetime strings, in MySQL datetime format (Y-m-d H:i:s),1039 * null on failure.1040 */1041 function rest_get_date_with_gmt( $date, $is_utc = false ) {1042 /*1043 * Whether or not the original date actually has a timezone string1044 * changes the way we need to do timezone conversion.1045 * Store this info before parsing the date, and use it later.1046 */1047 $has_timezone = preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date );1048 1049 $date = rest_parse_date( $date );1050 1051 if ( empty( $date ) ) {1052 return null;1053 }1054 1055 /*1056 * At this point $date could either be a local date (if we were passed1057 * a *local* date without a timezone offset) or a UTC date (otherwise).1058 * Timezone conversion needs to be handled differently between these two cases.1059 */1060 if ( ! $is_utc && ! $has_timezone ) {1061 $local = gmdate( 'Y-m-d H:i:s', $date );1062 $utc = get_gmt_from_date( $local );1063 } else {1064 $utc = gmdate( 'Y-m-d H:i:s', $date );1065 $local = get_date_from_gmt( $utc );1066 }1067 1068 return array( $local, $utc );1069 }1070 1071 /**1072 * Returns a contextual HTTP error code for authorization failure.1073 *1074 * @since 4.7.01075 *1076 * @return integer 401 if the user is not logged in, 403 if the user is logged in.1077 */1078 function rest_authorization_required_code() {1079 return is_user_logged_in() ? 403 : 401;1080 }1081 1082 /**1083 * Validate a request argument based on details registered to the route.1084 *1085 * @since 4.7.01086 *1087 * @param mixed $value1088 * @param WP_REST_Request $request1089 * @param string $param1090 * @return true|WP_Error1091 */1092 function rest_validate_request_arg( $value, $request, $param ) {1093 $attributes = $request->get_attributes();1094 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) {1095 return true;1096 }1097 $args = $attributes['args'][ $param ];1098 1099 return rest_validate_value_from_schema( $value, $args, $param );1100 }1101 1102 /**1103 * Sanitize a request argument based on details registered to the route.1104 *1105 * @since 4.7.01106 *1107 * @param mixed $value1108 * @param WP_REST_Request $request1109 * @param string $param1110 * @return mixed1111 */1112 function rest_sanitize_request_arg( $value, $request, $param ) {1113 $attributes = $request->get_attributes();1114 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) {1115 return $value;1116 }1117 $args = $attributes['args'][ $param ];1118 1119 return rest_sanitize_value_from_schema( $value, $args );1120 }1121 1122 /**1123 * Parse a request argument based on details registered to the route.1124 *1125 * Runs a validation check and sanitizes the value, primarily to be used via1126 * the `sanitize_callback` arguments in the endpoint args registration.1127 *1128 * @since 4.7.01129 *1130 * @param mixed $value1131 * @param WP_REST_Request $request1132 * @param string $param1133 * @return mixed1134 */1135 function rest_parse_request_arg( $value, $request, $param ) {1136 $is_valid = rest_validate_request_arg( $value, $request, $param );1137 1138 if ( is_wp_error( $is_valid ) ) {1139 return $is_valid;1140 }1141 1142 $value = rest_sanitize_request_arg( $value, $request, $param );1143 1144 return $value;1145 }1146 1147 /**1148 * Determines if an IP address is valid.1149 *1150 * Handles both IPv4 and IPv6 addresses.1151 *1152 * @since 4.7.01153 *1154 * @param string $ip IP address.1155 * @return string|false The valid IP address, otherwise false.1156 */1157 function rest_is_ip_address( $ip ) {1158 $ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';1159 1160 if ( ! preg_match( $ipv4_pattern, $ip ) && ! Requests_IPv6::check_ipv6( $ip ) ) {1161 return false;1162 }1163 1164 return $ip;1165 }1166 1167 /**1168 * Changes a boolean-like value into the proper boolean value.1169 *1170 * @since 4.7.01171 *1172 * @param bool|string|int $value The value being evaluated.1173 * @return boolean Returns the proper associated boolean value.1174 */1175 function rest_sanitize_boolean( $value ) {1176 // String values are translated to `true`; make sure 'false' is false.1177 if ( is_string( $value ) ) {1178 $value = strtolower( $value );1179 if ( in_array( $value, array( 'false', '0' ), true ) ) {1180 $value = false;1181 }1182 }1183 1184 // Everything else will map nicely to boolean.1185 return (bool) $value;1186 }1187 1188 /**1189 * Determines if a given value is boolean-like.1190 *1191 * @since 4.7.01192 *1193 * @param bool|string $maybe_bool The value being evaluated.1194 * @return boolean True if a boolean, otherwise false.1195 */1196 function rest_is_boolean( $maybe_bool ) {1197 if ( is_bool( $maybe_bool ) ) {1198 return true;1199 }1200 1201 if ( is_string( $maybe_bool ) ) {1202 $maybe_bool = strtolower( $maybe_bool );1203 1204 $valid_boolean_values = array(1205 'false',1206 'true',1207 '0',1208 '1',1209 );1210 1211 return in_array( $maybe_bool, $valid_boolean_values, true );1212 }1213 1214 if ( is_int( $maybe_bool ) ) {1215 return in_array( $maybe_bool, array( 0, 1 ), true );1216 }1217 1218 return false;1219 }1220 1221 /**1222 989 * Retrieves the avatar urls in various sizes. 1223 990 * … … 1264 1031 1265 1032 /** 1033 * Parses an RFC3339 time into a Unix timestamp. 1034 * 1035 * @since 4.4.0 1036 * 1037 * @param string $date RFC3339 timestamp. 1038 * @param bool $force_utc Optional. Whether to force UTC timezone instead of using 1039 * the timestamp's timezone. Default false. 1040 * @return int Unix timestamp. 1041 */ 1042 function rest_parse_date( $date, $force_utc = false ) { 1043 if ( $force_utc ) { 1044 $date = preg_replace( '/[+-]\d+:?\d+$/', '+00:00', $date ); 1045 } 1046 1047 $regex = '#^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}(?::\d{2})?)?$#'; 1048 1049 if ( ! preg_match( $regex, $date, $matches ) ) { 1050 return false; 1051 } 1052 1053 return strtotime( $date ); 1054 } 1055 1056 /** 1057 * Parses a 3 or 6 digit hex color (with #). 1058 * 1059 * @since 5.4.0 1060 * 1061 * @param string $color 3 or 6 digit hex color (with #). 1062 * @return string|false 1063 */ 1064 function rest_parse_hex_color( $color ) { 1065 $regex = '|^#([A-Fa-f0-9]{3}){1,2}$|'; 1066 if ( ! preg_match( $regex, $color, $matches ) ) { 1067 return false; 1068 } 1069 1070 return $color; 1071 } 1072 1073 /** 1074 * Parses a date into both its local and UTC equivalent, in MySQL datetime format. 1075 * 1076 * @since 4.4.0 1077 * 1078 * @see rest_parse_date() 1079 * 1080 * @param string $date RFC3339 timestamp. 1081 * @param bool $is_utc Whether the provided date should be interpreted as UTC. Default false. 1082 * @return array|null Local and UTC datetime strings, in MySQL datetime format (Y-m-d H:i:s), 1083 * null on failure. 1084 */ 1085 function rest_get_date_with_gmt( $date, $is_utc = false ) { 1086 /* 1087 * Whether or not the original date actually has a timezone string 1088 * changes the way we need to do timezone conversion. 1089 * Store this info before parsing the date, and use it later. 1090 */ 1091 $has_timezone = preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date ); 1092 1093 $date = rest_parse_date( $date ); 1094 1095 if ( empty( $date ) ) { 1096 return null; 1097 } 1098 1099 /* 1100 * At this point $date could either be a local date (if we were passed 1101 * a *local* date without a timezone offset) or a UTC date (otherwise). 1102 * Timezone conversion needs to be handled differently between these two cases. 1103 */ 1104 if ( ! $is_utc && ! $has_timezone ) { 1105 $local = gmdate( 'Y-m-d H:i:s', $date ); 1106 $utc = get_gmt_from_date( $local ); 1107 } else { 1108 $utc = gmdate( 'Y-m-d H:i:s', $date ); 1109 $local = get_date_from_gmt( $utc ); 1110 } 1111 1112 return array( $local, $utc ); 1113 } 1114 1115 /** 1116 * Returns a contextual HTTP error code for authorization failure. 1117 * 1118 * @since 4.7.0 1119 * 1120 * @return integer 401 if the user is not logged in, 403 if the user is logged in. 1121 */ 1122 function rest_authorization_required_code() { 1123 return is_user_logged_in() ? 403 : 401; 1124 } 1125 1126 /** 1127 * Validate a request argument based on details registered to the route. 1128 * 1129 * @since 4.7.0 1130 * 1131 * @param mixed $value 1132 * @param WP_REST_Request $request 1133 * @param string $param 1134 * @return true|WP_Error 1135 */ 1136 function rest_validate_request_arg( $value, $request, $param ) { 1137 $attributes = $request->get_attributes(); 1138 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { 1139 return true; 1140 } 1141 $args = $attributes['args'][ $param ]; 1142 1143 return rest_validate_value_from_schema( $value, $args, $param ); 1144 } 1145 1146 /** 1147 * Sanitize a request argument based on details registered to the route. 1148 * 1149 * @since 4.7.0 1150 * 1151 * @param mixed $value 1152 * @param WP_REST_Request $request 1153 * @param string $param 1154 * @return mixed 1155 */ 1156 function rest_sanitize_request_arg( $value, $request, $param ) { 1157 $attributes = $request->get_attributes(); 1158 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { 1159 return $value; 1160 } 1161 $args = $attributes['args'][ $param ]; 1162 1163 return rest_sanitize_value_from_schema( $value, $args, $param ); 1164 } 1165 1166 /** 1167 * Parse a request argument based on details registered to the route. 1168 * 1169 * Runs a validation check and sanitizes the value, primarily to be used via 1170 * the `sanitize_callback` arguments in the endpoint args registration. 1171 * 1172 * @since 4.7.0 1173 * 1174 * @param mixed $value 1175 * @param WP_REST_Request $request 1176 * @param string $param 1177 * @return mixed 1178 */ 1179 function rest_parse_request_arg( $value, $request, $param ) { 1180 $is_valid = rest_validate_request_arg( $value, $request, $param ); 1181 1182 if ( is_wp_error( $is_valid ) ) { 1183 return $is_valid; 1184 } 1185 1186 $value = rest_sanitize_request_arg( $value, $request, $param ); 1187 1188 return $value; 1189 } 1190 1191 /** 1192 * Determines if an IP address is valid. 1193 * 1194 * Handles both IPv4 and IPv6 addresses. 1195 * 1196 * @since 4.7.0 1197 * 1198 * @param string $ip IP address. 1199 * @return string|false The valid IP address, otherwise false. 1200 */ 1201 function rest_is_ip_address( $ip ) { 1202 $ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/'; 1203 1204 if ( ! preg_match( $ipv4_pattern, $ip ) && ! Requests_IPv6::check_ipv6( $ip ) ) { 1205 return false; 1206 } 1207 1208 return $ip; 1209 } 1210 1211 /** 1212 * Changes a boolean-like value into the proper boolean value. 1213 * 1214 * @since 4.7.0 1215 * 1216 * @param bool|string|int $value The value being evaluated. 1217 * @return boolean Returns the proper associated boolean value. 1218 */ 1219 function rest_sanitize_boolean( $value ) { 1220 // String values are translated to `true`; make sure 'false' is false. 1221 if ( is_string( $value ) ) { 1222 $value = strtolower( $value ); 1223 if ( in_array( $value, array( 'false', '0' ), true ) ) { 1224 $value = false; 1225 } 1226 } 1227 1228 // Everything else will map nicely to boolean. 1229 return (bool) $value; 1230 } 1231 1232 /** 1233 * Determines if a given value is boolean-like. 1234 * 1235 * @since 4.7.0 1236 * 1237 * @param bool|string $maybe_bool The value being evaluated. 1238 * @return boolean True if a boolean, otherwise false. 1239 */ 1240 function rest_is_boolean( $maybe_bool ) { 1241 if ( is_bool( $maybe_bool ) ) { 1242 return true; 1243 } 1244 1245 if ( is_string( $maybe_bool ) ) { 1246 $maybe_bool = strtolower( $maybe_bool ); 1247 1248 $valid_boolean_values = array( 1249 'false', 1250 'true', 1251 '0', 1252 '1', 1253 ); 1254 1255 return in_array( $maybe_bool, $valid_boolean_values, true ); 1256 } 1257 1258 if ( is_int( $maybe_bool ) ) { 1259 return in_array( $maybe_bool, array( 0, 1 ), true ); 1260 } 1261 1262 return false; 1263 } 1264 1265 /** 1266 * Determines if a given value is integer-like. 1267 * 1268 * @since 5.5.0 1269 * 1270 * @param mixed $maybe_integer The value being evaluated. 1271 * @return bool True if an integer, otherwise false. 1272 */ 1273 function rest_is_integer( $maybe_integer ) { 1274 return round( floatval( $maybe_integer ) ) === floatval( $maybe_integer ); 1275 } 1276 1277 /** 1278 * Determines if a given value is array-like. 1279 * 1280 * @since 5.5.0 1281 * 1282 * @param mixed $maybe_array The value being evaluated. 1283 * @return bool 1284 */ 1285 function rest_is_array( $maybe_array ) { 1286 if ( is_scalar( $maybe_array ) ) { 1287 $maybe_array = wp_parse_list( $maybe_array ); 1288 } 1289 1290 return wp_is_numeric_array( $maybe_array ); 1291 } 1292 1293 /** 1294 * Converts an array-like value to an array. 1295 * 1296 * @since 5.5.0 1297 * 1298 * @param mixed $maybe_array The value being evaluated. 1299 * @return array Returns the array extracted from the value. 1300 */ 1301 function rest_sanitize_array( $maybe_array ) { 1302 if ( is_scalar( $maybe_array ) ) { 1303 return wp_parse_list( $maybe_array ); 1304 } 1305 1306 if ( ! is_array( $maybe_array ) ) { 1307 return array(); 1308 } 1309 1310 // Normalize to numeric array so nothing unexpected is in the keys. 1311 return array_values( $maybe_array ); 1312 } 1313 1314 /** 1315 * Determines if a given value is object-like. 1316 * 1317 * @since 5.5.0 1318 * 1319 * @param mixed $maybe_object The value being evaluated. 1320 * @return bool True if object like, otherwise false. 1321 */ 1322 function rest_is_object( $maybe_object ) { 1323 if ( '' === $maybe_object ) { 1324 return true; 1325 } 1326 1327 if ( $maybe_object instanceof stdClass ) { 1328 return true; 1329 } 1330 1331 if ( $maybe_object instanceof JsonSerializable ) { 1332 $maybe_object = $maybe_object->jsonSerialize(); 1333 } 1334 1335 return is_array( $maybe_object ); 1336 } 1337 1338 /** 1339 * Converts an object-like value to an object. 1340 * 1341 * @since 5.5.0 1342 * 1343 * @param mixed $maybe_object The value being evaluated. 1344 * @return array Returns the object extracted from the value. 1345 */ 1346 function rest_sanitize_object( $maybe_object ) { 1347 if ( '' === $maybe_object ) { 1348 return array(); 1349 } 1350 1351 if ( $maybe_object instanceof stdClass ) { 1352 return (array) $maybe_object; 1353 } 1354 1355 if ( $maybe_object instanceof JsonSerializable ) { 1356 $maybe_object = $maybe_object->jsonSerialize(); 1357 } 1358 1359 if ( ! is_array( $maybe_object ) ) { 1360 return array(); 1361 } 1362 1363 return $maybe_object; 1364 } 1365 1366 /** 1367 * Gets the best type for a value. 1368 * 1369 * @since 5.5.0 1370 * 1371 * @param mixed $value The value to check. 1372 * @param array $types The list of possible types. 1373 * @return string The best matching type, an empty string if no types match. 1374 */ 1375 function rest_get_best_type_for_value( $value, $types ) { 1376 static $checks = array( 1377 'array' => 'rest_is_array', 1378 'object' => 'rest_is_object', 1379 'integer' => 'rest_is_integer', 1380 'number' => 'is_numeric', 1381 'boolean' => 'rest_is_boolean', 1382 'string' => 'is_string', 1383 'null' => 'is_null', 1384 ); 1385 1386 // Both arrays and objects allow empty strings to be converted to their types. 1387 // But the best answer for this type is a string. 1388 if ( '' === $value && in_array( 'string', $types, true ) ) { 1389 return 'string'; 1390 } 1391 1392 foreach ( $types as $type ) { 1393 if ( isset( $checks[ $type ] ) && $checks[ $type ]( $value ) ) { 1394 return $type; 1395 } 1396 } 1397 1398 return ''; 1399 } 1400 1401 /** 1402 * Handles getting the best type for a multi-type schema. 1403 * 1404 * This is a wrapper for {@see rest_get_best_type_for_value()} that handles 1405 * backward compatibility for schemas that use invalid types. 1406 * 1407 * @since 5.5.0 1408 * 1409 * @param mixed $value The value to check. 1410 * @param array $args The schema array to use. 1411 * @param string $param The parameter name, used in error messages. 1412 * @return string 1413 */ 1414 function rest_handle_multi_type_schema( $value, $args, $param = '' ) { 1415 $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); 1416 $invalid_types = array_diff( $args['type'], $allowed_types ); 1417 1418 if ( $invalid_types ) { 1419 _doing_it_wrong( 1420 __FUNCTION__, 1421 /* translators: 1. Parameter. 2. List of allowed types. */ 1422 wp_sprintf( __( 'The "type" schema keyword for %1$s can only contain the built-in types: %2$l.' ), $param, $allowed_types ), 1423 '5.5.0' 1424 ); 1425 } 1426 1427 $best_type = rest_get_best_type_for_value( $value, $args['type'] ); 1428 1429 if ( ! $best_type ) { 1430 if ( ! $invalid_types ) { 1431 return ''; 1432 } 1433 1434 // Backward compatibility for previous behavior which allowed the value if there was an invalid type used. 1435 $best_type = reset( $invalid_types ); 1436 } 1437 1438 return $best_type; 1439 } 1440 1441 /** 1266 1442 * Validate a value based on a schema. 1267 1443 * … … 1285 1461 1286 1462 if ( ! isset( $args['type'] ) ) { 1287 _doing_it_wrong( __FUNCTION__, __( 'The "type" schema keyword is required.' ), '5.5.0' ); 1463 /* translators: 1. Parameter */ 1464 _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' ); 1288 1465 } 1289 1466 1290 1467 if ( is_array( $args['type'] ) ) { 1291 foreach ( $args['type'] as $type ) { 1292 $type_args = $args; 1293 $type_args['type'] = $type; 1294 1295 if ( true === rest_validate_value_from_schema( $value, $type_args, $param ) ) { 1296 return true; 1297 } 1298 } 1299 1300 /* translators: 1: Parameter, 2: List of types. */ 1301 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ) ); 1468 $best_type = rest_handle_multi_type_schema( $value, $args, $param ); 1469 1470 if ( ! $best_type ) { 1471 /* translators: 1: Parameter, 2: List of types. */ 1472 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ) ); 1473 } 1474 1475 $args['type'] = $best_type; 1302 1476 } 1303 1477 … … 1305 1479 _doing_it_wrong( 1306 1480 __FUNCTION__, 1307 /* translators: 1. The list of allowed types. */1308 wp_sprintf( __( 'The "type" schema keyword can only be on of the built-in types: %l.' ), $allowed_types ),1481 /* translators: 1. Parameter 2. The list of allowed types. */ 1482 wp_sprintf( __( 'The "type" schema keyword for %1$s can only be on of the built-in types: %2$l.' ), $param, $allowed_types ), 1309 1483 '5.5.0' 1310 1484 ); … … 1312 1486 1313 1487 if ( 'array' === $args['type'] ) { 1314 if ( ! is_null( $value ) ) { 1315 $value = wp_parse_list( $value ); 1316 } 1317 1318 if ( ! wp_is_numeric_array( $value ) ) { 1488 if ( ! rest_is_array( $value ) ) { 1319 1489 /* translators: 1: Parameter, 2: Type name. */ 1320 1490 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ) ); 1321 1491 } 1492 1493 $value = rest_sanitize_array( $value ); 1322 1494 1323 1495 foreach ( $value as $index => $v ) { … … 1340 1512 1341 1513 if ( 'object' === $args['type'] ) { 1342 if ( '' === $value ) { 1343 $value = array(); 1344 } 1345 1346 if ( $value instanceof stdClass ) { 1347 $value = (array) $value; 1348 } 1349 1350 if ( $value instanceof JsonSerializable ) { 1351 $value = $value->jsonSerialize(); 1352 } 1353 1354 if ( ! is_array( $value ) ) { 1514 if ( ! rest_is_object( $value ) ) { 1355 1515 /* translators: 1: Parameter, 2: Type name. */ 1356 1516 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ) ); 1357 1517 } 1518 1519 $value = rest_sanitize_object( $value ); 1358 1520 1359 1521 if ( isset( $args['required'] ) && is_array( $args['required'] ) ) { // schema version 4 … … 1416 1578 } 1417 1579 1418 if ( 'integer' === $args['type'] && round( floatval( $value ) ) !== floatval( $value ) ) {1580 if ( 'integer' === $args['type'] && ! rest_is_integer( $value ) ) { 1419 1581 /* translators: 1: Parameter, 2: Type name. */ 1420 1582 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ) ); … … 1552 1714 * 1553 1715 * @since 4.7.0 1554 * 1555 * @param mixed $value The value to sanitize. 1556 * @param array $args Schema array to use for sanitization. 1716 * @since 5.5.0 Added the `$param` parameter. 1717 * 1718 * @param mixed $value The value to sanitize. 1719 * @param array $args Schema array to use for sanitization. 1720 * @param string $param The parameter name, used in error messages. 1557 1721 * @return true|WP_Error 1558 1722 */ 1559 function rest_sanitize_value_from_schema( $value, $args ) {1723 function rest_sanitize_value_from_schema( $value, $args, $param = '' ) { 1560 1724 $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); 1561 1725 1562 1726 if ( ! isset( $args['type'] ) ) { 1563 _doing_it_wrong( __FUNCTION__, __( 'The "type" schema keyword is required.' ), '5.5.0' ); 1727 /* translators: 1. Parameter */ 1728 _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' ); 1564 1729 } 1565 1730 1566 1731 if ( is_array( $args['type'] ) ) { 1567 // Determine which type the value was validated against, 1568 // and use that type when performing sanitization. 1569 $validated_type = ''; 1570 1571 foreach ( $args['type'] as $type ) { 1572 $type_args = $args; 1573 $type_args['type'] = $type; 1574 1575 if ( ! is_wp_error( rest_validate_value_from_schema( $value, $type_args ) ) ) { 1576 $validated_type = $type; 1577 break; 1578 } 1579 } 1580 1581 if ( ! $validated_type ) { 1732 $best_type = rest_handle_multi_type_schema( $value, $args, $param ); 1733 1734 if ( ! $best_type ) { 1582 1735 return null; 1583 1736 } 1584 1737 1585 $args['type'] = $ validated_type;1738 $args['type'] = $best_type; 1586 1739 } 1587 1740 … … 1589 1742 _doing_it_wrong( 1590 1743 __FUNCTION__, 1591 /* translators: 1. The list of allowed types. */1592 wp_sprintf( __( 'The "type" schema keyword can only be on of the built-in types: %l.' ), $allowed_types ),1744 /* translators: 1. Parameter. 2. The list of allowed types. */ 1745 wp_sprintf( __( 'The "type" schema keyword for %1$s can only be on of the built-in types: %2$l.' ), $param, $allowed_types ), 1593 1746 '5.5.0' 1594 1747 ); … … 1596 1749 1597 1750 if ( 'array' === $args['type'] ) { 1751 $value = rest_sanitize_array( $value ); 1752 1598 1753 if ( empty( $args['items'] ) ) { 1599 return (array) $value; 1600 } 1601 1602 $value = wp_parse_list( $value ); 1754 return $value; 1755 } 1756 1603 1757 foreach ( $value as $index => $v ) { 1604 $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'] ); 1605 } 1606 1607 // Normalize to numeric array so nothing unexpected is in the keys. 1608 $value = array_values( $value ); 1758 $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' ); 1759 } 1760 1609 1761 return $value; 1610 1762 } 1611 1763 1612 1764 if ( 'object' === $args['type'] ) { 1613 if ( $value instanceof stdClass ) { 1614 $value = (array) $value; 1615 } 1616 1617 if ( $value instanceof JsonSerializable ) { 1618 $value = $value->jsonSerialize(); 1619 } 1620 1621 if ( ! is_array( $value ) ) { 1622 return array(); 1623 } 1765 $value = rest_sanitize_object( $value ); 1624 1766 1625 1767 foreach ( $value as $property => $v ) { 1626 1768 if ( isset( $args['properties'][ $property ] ) ) { 1627 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ] );1769 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' ); 1628 1770 } elseif ( isset( $args['additionalProperties'] ) ) { 1629 1771 if ( false === $args['additionalProperties'] ) { 1630 1772 unset( $value[ $property ] ); 1631 1773 } elseif ( is_array( $args['additionalProperties'] ) ) { 1632 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'] );1774 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' ); 1633 1775 } 1634 1776 }
Note: See TracChangeset
for help on using the changeset viewer.