Make WordPress Core

Changeset 49257


Ignore:
Timestamp:
10/20/2020 08:17:20 PM (4 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Make sure all supported JSON Schema keywords are output in the index.

Previously, only a small subset of keywords were exposed which limited the utility of OPTIONS requests.

Props raubvogel, TimothyBlynJacobs.
Fixes #51020.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api.php

    r49246 r49257  
    18761876
    18771877/**
    1878  * Validate a value based on a schema.
    1879  *
    1880  * @since 4.7.0
    1881  * @since 4.9.0 Support the "object" type.
    1882  * @since 5.2.0 Support validating "additionalProperties" against a schema.
    1883  * @since 5.3.0 Support multiple types.
    1884  * @since 5.4.0 Convert an empty string to an empty object.
    1885  * @since 5.5.0 Add the "uuid" and "hex-color" formats.
    1886  *              Support the "minLength", "maxLength" and "pattern" keywords for strings.
    1887  *              Support the "minItems", "maxItems" and "uniqueItems" keywords for arrays.
    1888  *              Validate required properties.
    1889  * @since 5.6.0 Support the "minProperties" and "maxProperties" keywords for objects.
    1890  *              Support the "multipleOf" keyword for numbers and integers.
    1891  *              Support the "patternProperties" keyword for objects.
    1892  *              Support the "anyOf" and "oneOf" keywords.
    1893  *
    1894  * @param mixed  $value The value to validate.
    1895  * @param array  $args  Schema array to use for validation.
    1896  * @param string $param The parameter name, used in error messages.
    1897  * @return true|WP_Error
    1898  */
    1899 function rest_validate_value_from_schema( $value, $args, $param = '' ) {
    1900     if ( isset( $args['anyOf'] ) ) {
    1901         $matching_schema = rest_find_any_matching_schema( $value, $args, $param );
    1902         if ( is_wp_error( $matching_schema ) ) {
    1903             return $matching_schema;
    1904         }
    1905 
    1906         if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) {
    1907             $args['type'] = $matching_schema['type'];
    1908         }
    1909     }
    1910 
    1911     if ( isset( $args['oneOf'] ) ) {
    1912         $matching_schema = rest_find_one_matching_schema( $value, $args, $param );
    1913         if ( is_wp_error( $matching_schema ) ) {
    1914             return $matching_schema;
    1915         }
    1916 
    1917         if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) {
    1918             $args['type'] = $matching_schema['type'];
    1919         }
    1920     }
    1921 
    1922     $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
    1923 
    1924     if ( ! isset( $args['type'] ) ) {
    1925         /* translators: %s: Parameter. */
    1926         _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' );
    1927     }
    1928 
    1929     if ( is_array( $args['type'] ) ) {
    1930         $best_type = rest_handle_multi_type_schema( $value, $args, $param );
    1931 
    1932         if ( ! $best_type ) {
    1933             return new WP_Error(
    1934                 'rest_invalid_type',
    1935                 /* translators: 1: Parameter, 2: List of types. */
    1936                 sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ),
    1937                 array( 'param' => $param )
    1938             );
    1939         }
    1940 
    1941         $args['type'] = $best_type;
    1942     }
    1943 
    1944     if ( ! in_array( $args['type'], $allowed_types, true ) ) {
    1945         _doing_it_wrong(
    1946             __FUNCTION__,
    1947             /* translators: 1: Parameter, 2: The list of allowed types. */
    1948             wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ),
    1949             '5.5.0'
    1950         );
    1951     }
    1952 
    1953     if ( 'array' === $args['type'] ) {
    1954         if ( ! rest_is_array( $value ) ) {
    1955             return new WP_Error(
    1956                 'rest_invalid_type',
    1957                 /* translators: 1: Parameter, 2: Type name. */
    1958                 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ),
    1959                 array( 'param' => $param )
    1960             );
    1961         }
    1962 
    1963         $value = rest_sanitize_array( $value );
    1964 
    1965         if ( isset( $args['items'] ) ) {
    1966             foreach ( $value as $index => $v ) {
    1967                 $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
    1968                 if ( is_wp_error( $is_valid ) ) {
    1969                     return $is_valid;
    1970                 }
    1971             }
    1972         }
    1973 
    1974         if ( isset( $args['minItems'] ) && count( $value ) < $args['minItems'] ) {
    1975             /* translators: 1: Parameter, 2: Number. */
    1976             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at least %2$s items.' ), $param, number_format_i18n( $args['minItems'] ) ) );
    1977         }
    1978 
    1979         if ( isset( $args['maxItems'] ) && count( $value ) > $args['maxItems'] ) {
    1980             /* translators: 1: Parameter, 2: Number. */
    1981             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
    1982         }
    1983 
    1984         if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
    1985             /* translators: 1: Parameter. */
    1986             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
    1987         }
    1988     }
    1989 
    1990     if ( 'object' === $args['type'] ) {
    1991         if ( ! rest_is_object( $value ) ) {
    1992             return new WP_Error(
    1993                 'rest_invalid_type',
    1994                 /* translators: 1: Parameter, 2: Type name. */
    1995                 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ),
    1996                 array( 'param' => $param )
    1997             );
    1998         }
    1999 
    2000         $value = rest_sanitize_object( $value );
    2001 
    2002         if ( isset( $args['required'] ) && is_array( $args['required'] ) ) { // schema version 4
    2003             foreach ( $args['required'] as $name ) {
    2004                 if ( ! array_key_exists( $name, $value ) ) {
    2005                     /* translators: 1: Property of an object, 2: Parameter. */
    2006                     return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) );
    2007                 }
    2008             }
    2009         } elseif ( isset( $args['properties'] ) ) { // schema version 3
    2010             foreach ( $args['properties'] as $name => $property ) {
    2011                 if ( isset( $property['required'] ) && true === $property['required'] && ! array_key_exists( $name, $value ) ) {
    2012                     /* translators: 1: Property of an object, 2: Parameter. */
    2013                     return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) );
    2014                 }
    2015             }
    2016         }
    2017 
    2018         foreach ( $value as $property => $v ) {
    2019             if ( isset( $args['properties'][ $property ] ) ) {
    2020                 $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );
    2021                 if ( is_wp_error( $is_valid ) ) {
    2022                     return $is_valid;
    2023                 }
    2024                 continue;
    2025             }
    2026 
    2027             $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
    2028             if ( null !== $pattern_property_schema ) {
    2029                 $is_valid = rest_validate_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
    2030                 if ( is_wp_error( $is_valid ) ) {
    2031                     return $is_valid;
    2032                 }
    2033                 continue;
    2034             }
    2035 
    2036             if ( isset( $args['additionalProperties'] ) ) {
    2037                 if ( false === $args['additionalProperties'] ) {
    2038                     /* translators: %s: Property of an object. */
    2039                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) );
    2040                 }
    2041 
    2042                 if ( is_array( $args['additionalProperties'] ) ) {
    2043                     $is_valid = rest_validate_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' );
    2044                     if ( is_wp_error( $is_valid ) ) {
    2045                         return $is_valid;
    2046                     }
    2047                 }
    2048             }
    2049         }
    2050 
    2051         if ( isset( $args['minProperties'] ) && count( $value ) < $args['minProperties'] ) {
    2052             /* translators: 1: Parameter, 2: Number. */
    2053             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at least %2$s properties.' ), $param, number_format_i18n( $args['minProperties'] ) ) );
    2054         }
    2055 
    2056         if ( isset( $args['maxProperties'] ) && count( $value ) > $args['maxProperties'] ) {
    2057             /* translators: 1: Parameter, 2: Number. */
    2058             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s properties.' ), $param, number_format_i18n( $args['maxProperties'] ) ) );
    2059         }
    2060     }
    2061 
    2062     if ( 'null' === $args['type'] ) {
    2063         if ( null !== $value ) {
    2064             return new WP_Error(
    2065                 'rest_invalid_type',
    2066                 /* translators: 1: Parameter, 2: Type name. */
    2067                 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'null' ),
    2068                 array( 'param' => $param )
    2069             );
    2070         }
    2071 
    2072         return true;
    2073     }
    2074 
    2075     if ( ! empty( $args['enum'] ) ) {
    2076         if ( ! in_array( $value, $args['enum'], true ) ) {
    2077             /* translators: 1: Parameter, 2: List of valid values. */
    2078             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), $param, implode( ', ', $args['enum'] ) ) );
    2079         }
    2080     }
    2081 
    2082     if ( in_array( $args['type'], array( 'integer', 'number' ), true ) ) {
    2083         if ( ! is_numeric( $value ) ) {
    2084             return new WP_Error(
    2085                 'rest_invalid_type',
    2086                 /* translators: 1: Parameter, 2: Type name. */
    2087                 sprintf( __( '%1$s is not of type %2$s.' ), $param, $args['type'] ),
    2088                 array( 'param' => $param )
    2089             );
    2090         }
    2091 
    2092         if ( isset( $args['multipleOf'] ) && fmod( $value, $args['multipleOf'] ) !== 0.0 ) {
    2093             /* translators: 1: Parameter, 2: Multiplier. */
    2094             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be a multiple of %2$s.' ), $param, $args['multipleOf'] ) );
    2095         }
    2096     }
    2097 
    2098     if ( 'integer' === $args['type'] && ! rest_is_integer( $value ) ) {
    2099         return new WP_Error(
    2100             'rest_invalid_type',
    2101             /* translators: 1: Parameter, 2: Type name. */
    2102             sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ),
    2103             array( 'param' => $param )
    2104         );
    2105     }
    2106 
    2107     if ( 'boolean' === $args['type'] && ! rest_is_boolean( $value ) ) {
    2108         return new WP_Error(
    2109             'rest_invalid_type',
    2110             /* translators: 1: Parameter, 2: Type name. */
    2111             sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ),
    2112             array( 'param' => $param )
    2113         );
    2114     }
    2115 
    2116     if ( 'string' === $args['type'] ) {
    2117         if ( ! is_string( $value ) ) {
    2118             return new WP_Error(
    2119                 'rest_invalid_type',
    2120                 /* translators: 1: Parameter, 2: Type name. */
    2121                 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ),
    2122                 array( 'param' => $param )
    2123             );
    2124         }
    2125 
    2126         if ( isset( $args['minLength'] ) && mb_strlen( $value ) < $args['minLength'] ) {
    2127             return new WP_Error(
    2128                 'rest_invalid_param',
    2129                 sprintf(
    2130                     /* translators: 1: Parameter, 2: Number of characters. */
    2131                     _n( '%1$s must be at least %2$s character long.', '%1$s must be at least %2$s characters long.', $args['minLength'] ),
    2132                     $param,
    2133                     number_format_i18n( $args['minLength'] )
    2134                 )
    2135             );
    2136         }
    2137 
    2138         if ( isset( $args['maxLength'] ) && mb_strlen( $value ) > $args['maxLength'] ) {
    2139             return new WP_Error(
    2140                 'rest_invalid_param',
    2141                 sprintf(
    2142                     /* translators: 1: Parameter, 2: Number of characters. */
    2143                     _n( '%1$s must be at most %2$s character long.', '%1$s must be at most %2$s characters long.', $args['maxLength'] ),
    2144                     $param,
    2145                     number_format_i18n( $args['maxLength'] )
    2146                 )
    2147             );
    2148         }
    2149 
    2150         if ( isset( $args['pattern'] ) && ! rest_validate_json_schema_pattern( $args['pattern'], $value ) ) {
    2151             /* translators: 1: Parameter, 2: Pattern. */
    2152             return new WP_Error( 'rest_invalid_pattern', sprintf( __( '%1$s does not match pattern %2$s.' ), $param, $args['pattern'] ) );
    2153         }
    2154     }
    2155 
    2156     // The "format" keyword should only be applied to strings. However, for backward compatibility,
    2157     // we allow the "format" keyword if the type keyword was not specified, or was set to an invalid value.
    2158     if ( isset( $args['format'] )
    2159         && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) )
    2160     ) {
    2161         switch ( $args['format'] ) {
    2162             case 'hex-color':
    2163                 if ( ! rest_parse_hex_color( $value ) ) {
    2164                     return new WP_Error( 'rest_invalid_hex_color', __( 'Invalid hex color.' ) );
    2165                 }
    2166                 break;
    2167 
    2168             case 'date-time':
    2169                 if ( ! rest_parse_date( $value ) ) {
    2170                     return new WP_Error( 'rest_invalid_date', __( 'Invalid date.' ) );
    2171                 }
    2172                 break;
    2173 
    2174             case 'email':
    2175                 if ( ! is_email( $value ) ) {
    2176                     return new WP_Error( 'rest_invalid_email', __( 'Invalid email address.' ) );
    2177                 }
    2178                 break;
    2179             case 'ip':
    2180                 if ( ! rest_is_ip_address( $value ) ) {
    2181                     /* translators: %s: IP address. */
    2182                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IP address.' ), $param ) );
    2183                 }
    2184                 break;
    2185             case 'uuid':
    2186                 if ( ! wp_is_uuid( $value ) ) {
    2187                     /* translators: %s: The name of a JSON field expecting a valid UUID. */
    2188                     return new WP_Error( 'rest_invalid_uuid', sprintf( __( '%s is not a valid UUID.' ), $param ) );
    2189                 }
    2190                 break;
    2191         }
    2192     }
    2193 
    2194     if ( in_array( $args['type'], array( 'number', 'integer' ), true ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) {
    2195         if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) {
    2196             if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) {
    2197                 /* translators: 1: Parameter, 2: Minimum number. */
    2198                 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than %2$d' ), $param, $args['minimum'] ) );
    2199             } elseif ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) {
    2200                 /* translators: 1: Parameter, 2: Minimum number. */
    2201                 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than or equal to %2$d' ), $param, $args['minimum'] ) );
    2202             }
    2203         } elseif ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) {
    2204             if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) {
    2205                 /* translators: 1: Parameter, 2: Maximum number. */
    2206                 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than %2$d' ), $param, $args['maximum'] ) );
    2207             } elseif ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) {
    2208                 /* translators: 1: Parameter, 2: Maximum number. */
    2209                 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than or equal to %2$d' ), $param, $args['maximum'] ) );
    2210             }
    2211         } elseif ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) {
    2212             if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) {
    2213                 if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) {
    2214                     /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
    2215                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
    2216                 }
    2217             } elseif ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) {
    2218                 if ( $value >= $args['maximum'] || $value < $args['minimum'] ) {
    2219                     /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
    2220                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
    2221                 }
    2222             } elseif ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) {
    2223                 if ( $value > $args['maximum'] || $value <= $args['minimum'] ) {
    2224                     /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
    2225                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
    2226                 }
    2227             } elseif ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) {
    2228                 if ( $value > $args['maximum'] || $value < $args['minimum'] ) {
    2229                     /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
    2230                     return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
    2231                 }
    2232             }
    2233         }
    2234     }
    2235 
    2236     return true;
    2237 }
    2238 
    2239 /**
    2240  * Sanitize a value based on a schema.
    2241  *
    2242  * @since 4.7.0
    2243  * @since 5.5.0 Added the `$param` parameter.
    2244  * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
    2245  *
    2246  * @param mixed  $value The value to sanitize.
    2247  * @param array  $args  Schema array to use for sanitization.
    2248  * @param string $param The parameter name, used in error messages.
    2249  * @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
    2250  */
    2251 function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
    2252     if ( isset( $args['anyOf'] ) ) {
    2253         $matching_schema = rest_find_any_matching_schema( $value, $args, $param );
    2254         if ( is_wp_error( $matching_schema ) ) {
    2255             return $matching_schema;
    2256         }
    2257 
    2258         if ( ! isset( $args['type'] ) ) {
    2259             $args['type'] = $matching_schema['type'];
    2260         }
    2261 
    2262         $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param );
    2263     }
    2264 
    2265     if ( isset( $args['oneOf'] ) ) {
    2266         $matching_schema = rest_find_one_matching_schema( $value, $args, $param );
    2267         if ( is_wp_error( $matching_schema ) ) {
    2268             return $matching_schema;
    2269         }
    2270 
    2271         if ( ! isset( $args['type'] ) ) {
    2272             $args['type'] = $matching_schema['type'];
    2273         }
    2274 
    2275         $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param );
    2276     }
    2277 
    2278     $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
    2279 
    2280     if ( ! isset( $args['type'] ) ) {
    2281         /* translators: %s: Parameter. */
    2282         _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' );
    2283     }
    2284 
    2285     if ( is_array( $args['type'] ) ) {
    2286         $best_type = rest_handle_multi_type_schema( $value, $args, $param );
    2287 
    2288         if ( ! $best_type ) {
    2289             return null;
    2290         }
    2291 
    2292         $args['type'] = $best_type;
    2293     }
    2294 
    2295     if ( ! in_array( $args['type'], $allowed_types, true ) ) {
    2296         _doing_it_wrong(
    2297             __FUNCTION__,
    2298             /* translators: 1: Parameter, 2: The list of allowed types. */
    2299             wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ),
    2300             '5.5.0'
    2301         );
    2302     }
    2303 
    2304     if ( 'array' === $args['type'] ) {
    2305         $value = rest_sanitize_array( $value );
    2306 
    2307         if ( ! empty( $args['items'] ) ) {
    2308             foreach ( $value as $index => $v ) {
    2309                 $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
    2310             }
    2311         }
    2312 
    2313         if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
    2314             /* translators: 1: Parameter. */
    2315             return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
    2316         }
    2317 
    2318         return $value;
    2319     }
    2320 
    2321     if ( 'object' === $args['type'] ) {
    2322         $value = rest_sanitize_object( $value );
    2323 
    2324         foreach ( $value as $property => $v ) {
    2325             if ( isset( $args['properties'][ $property ] ) ) {
    2326                 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );
    2327                 continue;
    2328             }
    2329 
    2330             $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
    2331             if ( null !== $pattern_property_schema ) {
    2332                 $value[ $property ] = rest_sanitize_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
    2333                 continue;
    2334             }
    2335 
    2336             if ( isset( $args['additionalProperties'] ) ) {
    2337                 if ( false === $args['additionalProperties'] ) {
    2338                     unset( $value[ $property ] );
    2339                 } elseif ( is_array( $args['additionalProperties'] ) ) {
    2340                     $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' );
    2341                 }
    2342             }
    2343         }
    2344 
    2345         return $value;
    2346     }
    2347 
    2348     if ( 'null' === $args['type'] ) {
    2349         return null;
    2350     }
    2351 
    2352     if ( 'integer' === $args['type'] ) {
    2353         return (int) $value;
    2354     }
    2355 
    2356     if ( 'number' === $args['type'] ) {
    2357         return (float) $value;
    2358     }
    2359 
    2360     if ( 'boolean' === $args['type'] ) {
    2361         return rest_sanitize_boolean( $value );
    2362     }
    2363 
    2364     // This behavior matches rest_validate_value_from_schema().
    2365     if ( isset( $args['format'] )
    2366         && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) )
    2367     ) {
    2368         switch ( $args['format'] ) {
    2369             case 'hex-color':
    2370                 return (string) sanitize_hex_color( $value );
    2371 
    2372             case 'date-time':
    2373                 return sanitize_text_field( $value );
    2374 
    2375             case 'email':
    2376                 // sanitize_email() validates, which would be unexpected.
    2377                 return sanitize_text_field( $value );
    2378 
    2379             case 'uri':
    2380                 return esc_url_raw( $value );
    2381 
    2382             case 'ip':
    2383                 return sanitize_text_field( $value );
    2384 
    2385             case 'uuid':
    2386                 return sanitize_text_field( $value );
    2387         }
    2388     }
    2389 
    2390     if ( 'string' === $args['type'] ) {
    2391         return (string) $value;
    2392     }
    2393 
    2394     return $value;
    2395 }
    2396 
    2397 /**
    2398  * Append result of internal request to REST API for purpose of preloading data to be attached to a page.
    2399  * Expected to be called in the context of `array_reduce`.
    2400  *
    2401  * @since 5.0.0
    2402  *
    2403  * @param array  $memo Reduce accumulator.
    2404  * @param string $path REST API path to preload.
    2405  * @return array Modified reduce accumulator.
    2406  */
    2407 function rest_preload_api_request( $memo, $path ) {
    2408     // array_reduce() doesn't support passing an array in PHP 5.2,
    2409     // so we need to make sure we start with one.
    2410     if ( ! is_array( $memo ) ) {
    2411         $memo = array();
    2412     }
    2413 
    2414     if ( empty( $path ) ) {
    2415         return $memo;
    2416     }
    2417 
    2418     $method = 'GET';
    2419     if ( is_array( $path ) && 2 === count( $path ) ) {
    2420         $method = end( $path );
    2421         $path   = reset( $path );
    2422 
    2423         if ( ! in_array( $method, array( 'GET', 'OPTIONS' ), true ) ) {
    2424             $method = 'GET';
    2425         }
    2426     }
    2427 
    2428     $path_parts = parse_url( $path );
    2429     if ( false === $path_parts ) {
    2430         return $memo;
    2431     }
    2432 
    2433     $request = new WP_REST_Request( $method, $path_parts['path'] );
    2434     if ( ! empty( $path_parts['query'] ) ) {
    2435         parse_str( $path_parts['query'], $query_params );
    2436         $request->set_query_params( $query_params );
    2437     }
    2438 
    2439     $response = rest_do_request( $request );
    2440     if ( 200 === $response->status ) {
    2441         $server = rest_get_server();
    2442         $data   = (array) $response->get_data();
    2443         $links  = $server::get_compact_response_links( $response );
    2444         if ( ! empty( $links ) ) {
    2445             $data['_links'] = $links;
    2446         }
    2447 
    2448         if ( 'OPTIONS' === $method ) {
    2449             $response = rest_send_allow_header( $response, $server, $request );
    2450 
    2451             $memo[ $method ][ $path ] = array(
    2452                 'body'    => $data,
    2453                 'headers' => $response->headers,
    2454             );
    2455         } else {
    2456             $memo[ $path ] = array(
    2457                 'body'    => $data,
    2458                 'headers' => $response->headers,
    2459             );
    2460         }
    2461     }
    2462 
    2463     return $memo;
    2464 }
    2465 
    2466 /**
    2467  * Parses the "_embed" parameter into the list of resources to embed.
    2468  *
    2469  * @since 5.4.0
    2470  *
    2471  * @param string|array $embed Raw "_embed" parameter value.
    2472  * @return true|string[] Either true to embed all embeds, or a list of relations to embed.
    2473  */
    2474 function rest_parse_embed_param( $embed ) {
    2475     if ( ! $embed || 'true' === $embed || '1' === $embed ) {
    2476         return true;
    2477     }
    2478 
    2479     $rels = wp_parse_list( $embed );
    2480 
    2481     if ( ! $rels ) {
    2482         return true;
    2483     }
    2484 
    2485     return $rels;
    2486 }
    2487 
    2488 /**
    2489  * Filters the response to remove any fields not available in the given context.
    2490  *
    2491  * @since 5.5.0
    2492  * @since 5.6.0 Support the "patternProperties" keyword for objects.
    2493  *              Support the "anyOf" and "oneOf" keywords.
    2494  *
    2495  * @param array|object $data    The response data to modify.
    2496  * @param array        $schema  The schema for the endpoint used to filter the response.
    2497  * @param string       $context The requested context.
    2498  * @return array|object The filtered response data.
    2499  */
    2500 function rest_filter_response_by_context( $data, $schema, $context ) {
    2501     if ( isset( $schema['anyOf'] ) ) {
    2502         $matching_schema = rest_find_any_matching_schema( $data, $schema, '' );
    2503         if ( ! is_wp_error( $matching_schema ) ) {
    2504             if ( ! isset( $schema['type'] ) ) {
    2505                 $schema['type'] = $matching_schema['type'];
    2506             }
    2507 
    2508             $data = rest_filter_response_by_context( $data, $matching_schema, $context );
    2509         }
    2510     }
    2511 
    2512     if ( isset( $schema['oneOf'] ) ) {
    2513         $matching_schema = rest_find_one_matching_schema( $data, $schema, '', true );
    2514         if ( ! is_wp_error( $matching_schema ) ) {
    2515             if ( ! isset( $schema['type'] ) ) {
    2516                 $schema['type'] = $matching_schema['type'];
    2517             }
    2518 
    2519             $data = rest_filter_response_by_context( $data, $matching_schema, $context );
    2520         }
    2521     }
    2522 
    2523     if ( ! is_array( $data ) && ! is_object( $data ) ) {
    2524         return $data;
    2525     }
    2526 
    2527     if ( isset( $schema['type'] ) ) {
    2528         $type = $schema['type'];
    2529     } elseif ( isset( $schema['properties'] ) ) {
    2530         $type = 'object'; // Back compat if a developer accidentally omitted the type.
    2531     } else {
    2532         return $data;
    2533     }
    2534 
    2535     $is_array_type  = 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) );
    2536     $is_object_type = 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) );
    2537 
    2538     if ( $is_array_type && $is_object_type ) {
    2539         if ( rest_is_array( $data ) ) {
    2540             $is_object_type = false;
    2541         } else {
    2542             $is_array_type = false;
    2543         }
    2544     }
    2545 
    2546     $has_additional_properties = $is_object_type && isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] );
    2547 
    2548     foreach ( $data as $key => $value ) {
    2549         $check = array();
    2550 
    2551         if ( $is_array_type ) {
    2552             $check = isset( $schema['items'] ) ? $schema['items'] : array();
    2553         } elseif ( $is_object_type ) {
    2554             if ( isset( $schema['properties'][ $key ] ) ) {
    2555                 $check = $schema['properties'][ $key ];
    2556             } else {
    2557                 $pattern_property_schema = rest_find_matching_pattern_property_schema( $key, $schema );
    2558                 if ( null !== $pattern_property_schema ) {
    2559                     $check = $pattern_property_schema;
    2560                 } elseif ( $has_additional_properties ) {
    2561                     $check = $schema['additionalProperties'];
    2562                 }
    2563             }
    2564         }
    2565 
    2566         if ( ! isset( $check['context'] ) ) {
    2567             continue;
    2568         }
    2569 
    2570         if ( ! in_array( $context, $check['context'], true ) ) {
    2571             if ( $is_array_type ) {
    2572                 // All array items share schema, so there's no need to check each one.
    2573                 $data = array();
    2574                 break;
    2575             }
    2576 
    2577             if ( is_object( $data ) ) {
    2578                 unset( $data->$key );
    2579             } else {
    2580                 unset( $data[ $key ] );
    2581             }
    2582         } elseif ( is_array( $value ) || is_object( $value ) ) {
    2583             $new_value = rest_filter_response_by_context( $value, $check, $context );
    2584 
    2585             if ( is_object( $data ) ) {
    2586                 $data->$key = $new_value;
    2587             } else {
    2588                 $data[ $key ] = $new_value;
    2589             }
    2590         }
    2591     }
    2592 
    2593     return $data;
    2594 }
    2595 
    2596 /**
    2597  * Sets the "additionalProperties" to false by default for all object definitions in the schema.
    2598  *
    2599  * @since 5.5.0
    2600  * @since 5.6.0 Support the "patternProperties" keyword.
    2601  *
    2602  * @param array $schema The schema to modify.
    2603  * @return array The modified schema.
    2604  */
    2605 function rest_default_additional_properties_to_false( $schema ) {
    2606     $type = (array) $schema['type'];
    2607 
    2608     if ( in_array( 'object', $type, true ) ) {
    2609         if ( isset( $schema['properties'] ) ) {
    2610             foreach ( $schema['properties'] as $key => $child_schema ) {
    2611                 $schema['properties'][ $key ] = rest_default_additional_properties_to_false( $child_schema );
    2612             }
    2613         }
    2614 
    2615         if ( isset( $schema['patternProperties'] ) ) {
    2616             foreach ( $schema['patternProperties'] as $key => $child_schema ) {
    2617                 $schema['patternProperties'][ $key ] = rest_default_additional_properties_to_false( $child_schema );
    2618             }
    2619         }
    2620 
    2621         if ( ! isset( $schema['additionalProperties'] ) ) {
    2622             $schema['additionalProperties'] = false;
    2623         }
    2624     }
    2625 
    2626     if ( in_array( 'array', $type, true ) ) {
    2627         if ( isset( $schema['items'] ) ) {
    2628             $schema['items'] = rest_default_additional_properties_to_false( $schema['items'] );
    2629         }
    2630     }
    2631 
    2632     return $schema;
    2633 }
    2634 
    2635 /**
    2636  * Gets the REST API route for a post.
    2637  *
    2638  * @since 5.5.0
    2639  *
    2640  * @param int|WP_Post $post Post ID or post object.
    2641  * @return string The route path with a leading slash for the given post, or an empty string if there is not a route.
    2642  */
    2643 function rest_get_route_for_post( $post ) {
    2644     $post = get_post( $post );
    2645 
    2646     if ( ! $post instanceof WP_Post ) {
    2647         return '';
    2648     }
    2649 
    2650     $post_type = get_post_type_object( $post->post_type );
    2651     if ( ! $post_type ) {
    2652         return '';
    2653     }
    2654 
    2655     $controller = $post_type->get_rest_controller();
    2656     if ( ! $controller ) {
    2657         return '';
    2658     }
    2659 
    2660     $route = '';
    2661 
    2662     // The only two controllers that we can detect are the Attachments and Posts controllers.
    2663     if ( in_array( get_class( $controller ), array( 'WP_REST_Attachments_Controller', 'WP_REST_Posts_Controller' ), true ) ) {
    2664         $namespace = 'wp/v2';
    2665         $rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name;
    2666         $route     = sprintf( '/%s/%s/%d', $namespace, $rest_base, $post->ID );
    2667     }
    2668 
    2669     /**
    2670      * Filters the REST API route for a post.
    2671      *
    2672      * @since 5.5.0
    2673      *
    2674      * @param string  $route The route path.
    2675      * @param WP_Post $post  The post object.
    2676      */
    2677     return apply_filters( 'rest_route_for_post', $route, $post );
    2678 }
    2679 
    2680 /**
    2681  * Gets the REST API route for a term.
    2682  *
    2683  * @since 5.5.0
    2684  *
    2685  * @param int|WP_Term $term Term ID or term object.
    2686  * @return string The route path with a leading slash for the given term, or an empty string if there is not a route.
    2687  */
    2688 function rest_get_route_for_term( $term ) {
    2689     $term = get_term( $term );
    2690 
    2691     if ( ! $term instanceof WP_Term ) {
    2692         return '';
    2693     }
    2694 
    2695     $taxonomy = get_taxonomy( $term->taxonomy );
    2696     if ( ! $taxonomy ) {
    2697         return '';
    2698     }
    2699 
    2700     $controller = $taxonomy->get_rest_controller();
    2701     if ( ! $controller ) {
    2702         return '';
    2703     }
    2704 
    2705     $route = '';
    2706 
    2707     // The only controller that works is the Terms controller.
    2708     if ( $controller instanceof WP_REST_Terms_Controller ) {
    2709         $namespace = 'wp/v2';
    2710         $rest_base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
    2711         $route     = sprintf( '/%s/%s/%d', $namespace, $rest_base, $term->term_id );
    2712     }
    2713 
    2714     /**
    2715      * Filters the REST API route for a term.
    2716      *
    2717      * @since 5.5.0
    2718      *
    2719      * @param string  $route The route path.
    2720      * @param WP_Term $term  The term object.
    2721      */
    2722     return apply_filters( 'rest_route_for_term', $route, $term );
    2723 }
    2724 
    2725 /**
    2726  * Gets the REST route for the currently queried object.
    2727  *
    2728  * @since 5.5.0
    2729  *
    2730  * @return string The REST route of the resource, or an empty string if no resource identified.
    2731  */
    2732 function rest_get_queried_resource_route() {
    2733     if ( is_singular() ) {
    2734         $route = rest_get_route_for_post( get_queried_object() );
    2735     } elseif ( is_category() || is_tag() || is_tax() ) {
    2736         $route = rest_get_route_for_term( get_queried_object() );
    2737     } elseif ( is_author() ) {
    2738         $route = '/wp/v2/users/' . get_queried_object_id();
    2739     } else {
    2740         $route = '';
    2741     }
    2742 
    2743     /**
    2744      * Filters the REST route for the currently queried object.
    2745      *
    2746      * @since 5.5.0
    2747      *
    2748      * @param string $link The route with a leading slash, or an empty string.
    2749      */
    2750     return apply_filters( 'rest_queried_resource_route', $route );
    2751 }
    2752 
    2753 /**
    2754  * Retrieves an array of endpoint arguments from the item schema and endpoint method.
     1878 * Get all valid JSON schema properties.
    27551879 *
    27561880 * @since 5.6.0
    27571881 *
    2758  * @param array  $schema The full JSON schema for the endpoint.
    2759  * @param string $method Optional. HTTP method of the endpoint. The arguments for `CREATABLE` endpoints are
    2760  *                       checked for required values and may fall-back to a given default, this is not done
    2761  *                       on `EDITABLE` endpoints. Default WP_REST_Server::CREATABLE.
    2762  * @return array The endpoint arguments.
    2763  */
    2764 function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::CREATABLE ) {
    2765 
    2766     $schema_properties       = ! empty( $schema['properties'] ) ? $schema['properties'] : array();
    2767     $endpoint_args           = array();
    2768     $valid_schema_properties = array(
     1882 * @return string[] All valid JSON schema properties.
     1883 */
     1884function rest_get_allowed_schema_keywords() {
     1885    return array(
     1886        'title',
     1887        'description',
     1888        'default',
    27691889        'type',
    27701890        'format',
     
    27901910        'oneOf',
    27911911    );
     1912}
     1913
     1914/**
     1915 * Validate a value based on a schema.
     1916 *
     1917 * @since 4.7.0
     1918 * @since 4.9.0 Support the "object" type.
     1919 * @since 5.2.0 Support validating "additionalProperties" against a schema.
     1920 * @since 5.3.0 Support multiple types.
     1921 * @since 5.4.0 Convert an empty string to an empty object.
     1922 * @since 5.5.0 Add the "uuid" and "hex-color" formats.
     1923 *              Support the "minLength", "maxLength" and "pattern" keywords for strings.
     1924 *              Support the "minItems", "maxItems" and "uniqueItems" keywords for arrays.
     1925 *              Validate required properties.
     1926 * @since 5.6.0 Support the "minProperties" and "maxProperties" keywords for objects.
     1927 *              Support the "multipleOf" keyword for numbers and integers.
     1928 *              Support the "patternProperties" keyword for objects.
     1929 *              Support the "anyOf" and "oneOf" keywords.
     1930 *
     1931 * @param mixed  $value The value to validate.
     1932 * @param array  $args  Schema array to use for validation.
     1933 * @param string $param The parameter name, used in error messages.
     1934 * @return true|WP_Error
     1935 */
     1936function rest_validate_value_from_schema( $value, $args, $param = '' ) {
     1937    if ( isset( $args['anyOf'] ) ) {
     1938        $matching_schema = rest_find_any_matching_schema( $value, $args, $param );
     1939        if ( is_wp_error( $matching_schema ) ) {
     1940            return $matching_schema;
     1941        }
     1942
     1943        if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) {
     1944            $args['type'] = $matching_schema['type'];
     1945        }
     1946    }
     1947
     1948    if ( isset( $args['oneOf'] ) ) {
     1949        $matching_schema = rest_find_one_matching_schema( $value, $args, $param );
     1950        if ( is_wp_error( $matching_schema ) ) {
     1951            return $matching_schema;
     1952        }
     1953
     1954        if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) {
     1955            $args['type'] = $matching_schema['type'];
     1956        }
     1957    }
     1958
     1959    $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
     1960
     1961    if ( ! isset( $args['type'] ) ) {
     1962        /* translators: %s: Parameter. */
     1963        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' );
     1964    }
     1965
     1966    if ( is_array( $args['type'] ) ) {
     1967        $best_type = rest_handle_multi_type_schema( $value, $args, $param );
     1968
     1969        if ( ! $best_type ) {
     1970            return new WP_Error(
     1971                'rest_invalid_type',
     1972                /* translators: 1: Parameter, 2: List of types. */
     1973                sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ),
     1974                array( 'param' => $param )
     1975            );
     1976        }
     1977
     1978        $args['type'] = $best_type;
     1979    }
     1980
     1981    if ( ! in_array( $args['type'], $allowed_types, true ) ) {
     1982        _doing_it_wrong(
     1983            __FUNCTION__,
     1984            /* translators: 1: Parameter, 2: The list of allowed types. */
     1985            wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ),
     1986            '5.5.0'
     1987        );
     1988    }
     1989
     1990    if ( 'array' === $args['type'] ) {
     1991        if ( ! rest_is_array( $value ) ) {
     1992            return new WP_Error(
     1993                'rest_invalid_type',
     1994                /* translators: 1: Parameter, 2: Type name. */
     1995                sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ),
     1996                array( 'param' => $param )
     1997            );
     1998        }
     1999
     2000        $value = rest_sanitize_array( $value );
     2001
     2002        if ( isset( $args['items'] ) ) {
     2003            foreach ( $value as $index => $v ) {
     2004                $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
     2005                if ( is_wp_error( $is_valid ) ) {
     2006                    return $is_valid;
     2007                }
     2008            }
     2009        }
     2010
     2011        if ( isset( $args['minItems'] ) && count( $value ) < $args['minItems'] ) {
     2012            /* translators: 1: Parameter, 2: Number. */
     2013            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at least %2$s items.' ), $param, number_format_i18n( $args['minItems'] ) ) );
     2014        }
     2015
     2016        if ( isset( $args['maxItems'] ) && count( $value ) > $args['maxItems'] ) {
     2017            /* translators: 1: Parameter, 2: Number. */
     2018            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
     2019        }
     2020
     2021        if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
     2022            /* translators: 1: Parameter. */
     2023            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
     2024        }
     2025    }
     2026
     2027    if ( 'object' === $args['type'] ) {
     2028        if ( ! rest_is_object( $value ) ) {
     2029            return new WP_Error(
     2030                'rest_invalid_type',
     2031                /* translators: 1: Parameter, 2: Type name. */
     2032                sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ),
     2033                array( 'param' => $param )
     2034            );
     2035        }
     2036
     2037        $value = rest_sanitize_object( $value );
     2038
     2039        if ( isset( $args['required'] ) && is_array( $args['required'] ) ) { // schema version 4
     2040            foreach ( $args['required'] as $name ) {
     2041                if ( ! array_key_exists( $name, $value ) ) {
     2042                    /* translators: 1: Property of an object, 2: Parameter. */
     2043                    return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) );
     2044                }
     2045            }
     2046        } elseif ( isset( $args['properties'] ) ) { // schema version 3
     2047            foreach ( $args['properties'] as $name => $property ) {
     2048                if ( isset( $property['required'] ) && true === $property['required'] && ! array_key_exists( $name, $value ) ) {
     2049                    /* translators: 1: Property of an object, 2: Parameter. */
     2050                    return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) );
     2051                }
     2052            }
     2053        }
     2054
     2055        foreach ( $value as $property => $v ) {
     2056            if ( isset( $args['properties'][ $property ] ) ) {
     2057                $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );
     2058                if ( is_wp_error( $is_valid ) ) {
     2059                    return $is_valid;
     2060                }
     2061                continue;
     2062            }
     2063
     2064            $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
     2065            if ( null !== $pattern_property_schema ) {
     2066                $is_valid = rest_validate_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
     2067                if ( is_wp_error( $is_valid ) ) {
     2068                    return $is_valid;
     2069                }
     2070                continue;
     2071            }
     2072
     2073            if ( isset( $args['additionalProperties'] ) ) {
     2074                if ( false === $args['additionalProperties'] ) {
     2075                    /* translators: %s: Property of an object. */
     2076                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) );
     2077                }
     2078
     2079                if ( is_array( $args['additionalProperties'] ) ) {
     2080                    $is_valid = rest_validate_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' );
     2081                    if ( is_wp_error( $is_valid ) ) {
     2082                        return $is_valid;
     2083                    }
     2084                }
     2085            }
     2086        }
     2087
     2088        if ( isset( $args['minProperties'] ) && count( $value ) < $args['minProperties'] ) {
     2089            /* translators: 1: Parameter, 2: Number. */
     2090            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at least %2$s properties.' ), $param, number_format_i18n( $args['minProperties'] ) ) );
     2091        }
     2092
     2093        if ( isset( $args['maxProperties'] ) && count( $value ) > $args['maxProperties'] ) {
     2094            /* translators: 1: Parameter, 2: Number. */
     2095            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s properties.' ), $param, number_format_i18n( $args['maxProperties'] ) ) );
     2096        }
     2097    }
     2098
     2099    if ( 'null' === $args['type'] ) {
     2100        if ( null !== $value ) {
     2101            return new WP_Error(
     2102                'rest_invalid_type',
     2103                /* translators: 1: Parameter, 2: Type name. */
     2104                sprintf( __( '%1$s is not of type %2$s.' ), $param, 'null' ),
     2105                array( 'param' => $param )
     2106            );
     2107        }
     2108
     2109        return true;
     2110    }
     2111
     2112    if ( ! empty( $args['enum'] ) ) {
     2113        if ( ! in_array( $value, $args['enum'], true ) ) {
     2114            /* translators: 1: Parameter, 2: List of valid values. */
     2115            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), $param, implode( ', ', $args['enum'] ) ) );
     2116        }
     2117    }
     2118
     2119    if ( in_array( $args['type'], array( 'integer', 'number' ), true ) ) {
     2120        if ( ! is_numeric( $value ) ) {
     2121            return new WP_Error(
     2122                'rest_invalid_type',
     2123                /* translators: 1: Parameter, 2: Type name. */
     2124                sprintf( __( '%1$s is not of type %2$s.' ), $param, $args['type'] ),
     2125                array( 'param' => $param )
     2126            );
     2127        }
     2128
     2129        if ( isset( $args['multipleOf'] ) && fmod( $value, $args['multipleOf'] ) !== 0.0 ) {
     2130            /* translators: 1: Parameter, 2: Multiplier. */
     2131            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be a multiple of %2$s.' ), $param, $args['multipleOf'] ) );
     2132        }
     2133    }
     2134
     2135    if ( 'integer' === $args['type'] && ! rest_is_integer( $value ) ) {
     2136        return new WP_Error(
     2137            'rest_invalid_type',
     2138            /* translators: 1: Parameter, 2: Type name. */
     2139            sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ),
     2140            array( 'param' => $param )
     2141        );
     2142    }
     2143
     2144    if ( 'boolean' === $args['type'] && ! rest_is_boolean( $value ) ) {
     2145        return new WP_Error(
     2146            'rest_invalid_type',
     2147            /* translators: 1: Parameter, 2: Type name. */
     2148            sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ),
     2149            array( 'param' => $param )
     2150        );
     2151    }
     2152
     2153    if ( 'string' === $args['type'] ) {
     2154        if ( ! is_string( $value ) ) {
     2155            return new WP_Error(
     2156                'rest_invalid_type',
     2157                /* translators: 1: Parameter, 2: Type name. */
     2158                sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ),
     2159                array( 'param' => $param )
     2160            );
     2161        }
     2162
     2163        if ( isset( $args['minLength'] ) && mb_strlen( $value ) < $args['minLength'] ) {
     2164            return new WP_Error(
     2165                'rest_invalid_param',
     2166                sprintf(
     2167                    /* translators: 1: Parameter, 2: Number of characters. */
     2168                    _n( '%1$s must be at least %2$s character long.', '%1$s must be at least %2$s characters long.', $args['minLength'] ),
     2169                    $param,
     2170                    number_format_i18n( $args['minLength'] )
     2171                )
     2172            );
     2173        }
     2174
     2175        if ( isset( $args['maxLength'] ) && mb_strlen( $value ) > $args['maxLength'] ) {
     2176            return new WP_Error(
     2177                'rest_invalid_param',
     2178                sprintf(
     2179                    /* translators: 1: Parameter, 2: Number of characters. */
     2180                    _n( '%1$s must be at most %2$s character long.', '%1$s must be at most %2$s characters long.', $args['maxLength'] ),
     2181                    $param,
     2182                    number_format_i18n( $args['maxLength'] )
     2183                )
     2184            );
     2185        }
     2186
     2187        if ( isset( $args['pattern'] ) && ! rest_validate_json_schema_pattern( $args['pattern'], $value ) ) {
     2188            /* translators: 1: Parameter, 2: Pattern. */
     2189            return new WP_Error( 'rest_invalid_pattern', sprintf( __( '%1$s does not match pattern %2$s.' ), $param, $args['pattern'] ) );
     2190        }
     2191    }
     2192
     2193    // The "format" keyword should only be applied to strings. However, for backward compatibility,
     2194    // we allow the "format" keyword if the type keyword was not specified, or was set to an invalid value.
     2195    if ( isset( $args['format'] )
     2196        && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) )
     2197    ) {
     2198        switch ( $args['format'] ) {
     2199            case 'hex-color':
     2200                if ( ! rest_parse_hex_color( $value ) ) {
     2201                    return new WP_Error( 'rest_invalid_hex_color', __( 'Invalid hex color.' ) );
     2202                }
     2203                break;
     2204
     2205            case 'date-time':
     2206                if ( ! rest_parse_date( $value ) ) {
     2207                    return new WP_Error( 'rest_invalid_date', __( 'Invalid date.' ) );
     2208                }
     2209                break;
     2210
     2211            case 'email':
     2212                if ( ! is_email( $value ) ) {
     2213                    return new WP_Error( 'rest_invalid_email', __( 'Invalid email address.' ) );
     2214                }
     2215                break;
     2216            case 'ip':
     2217                if ( ! rest_is_ip_address( $value ) ) {
     2218                    /* translators: %s: IP address. */
     2219                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IP address.' ), $param ) );
     2220                }
     2221                break;
     2222            case 'uuid':
     2223                if ( ! wp_is_uuid( $value ) ) {
     2224                    /* translators: %s: The name of a JSON field expecting a valid UUID. */
     2225                    return new WP_Error( 'rest_invalid_uuid', sprintf( __( '%s is not a valid UUID.' ), $param ) );
     2226                }
     2227                break;
     2228        }
     2229    }
     2230
     2231    if ( in_array( $args['type'], array( 'number', 'integer' ), true ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) {
     2232        if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) {
     2233            if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) {
     2234                /* translators: 1: Parameter, 2: Minimum number. */
     2235                return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than %2$d' ), $param, $args['minimum'] ) );
     2236            } elseif ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) {
     2237                /* translators: 1: Parameter, 2: Minimum number. */
     2238                return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than or equal to %2$d' ), $param, $args['minimum'] ) );
     2239            }
     2240        } elseif ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) {
     2241            if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) {
     2242                /* translators: 1: Parameter, 2: Maximum number. */
     2243                return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than %2$d' ), $param, $args['maximum'] ) );
     2244            } elseif ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) {
     2245                /* translators: 1: Parameter, 2: Maximum number. */
     2246                return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than or equal to %2$d' ), $param, $args['maximum'] ) );
     2247            }
     2248        } elseif ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) {
     2249            if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) {
     2250                if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) {
     2251                    /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
     2252                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
     2253                }
     2254            } elseif ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) {
     2255                if ( $value >= $args['maximum'] || $value < $args['minimum'] ) {
     2256                    /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
     2257                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
     2258                }
     2259            } elseif ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) {
     2260                if ( $value > $args['maximum'] || $value <= $args['minimum'] ) {
     2261                    /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
     2262                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
     2263                }
     2264            } elseif ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) {
     2265                if ( $value > $args['maximum'] || $value < $args['minimum'] ) {
     2266                    /* translators: 1: Parameter, 2: Minimum number, 3: Maximum number. */
     2267                    return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) );
     2268                }
     2269            }
     2270        }
     2271    }
     2272
     2273    return true;
     2274}
     2275
     2276/**
     2277 * Sanitize a value based on a schema.
     2278 *
     2279 * @since 4.7.0
     2280 * @since 5.5.0 Added the `$param` parameter.
     2281 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords.
     2282 *
     2283 * @param mixed  $value The value to sanitize.
     2284 * @param array  $args  Schema array to use for sanitization.
     2285 * @param string $param The parameter name, used in error messages.
     2286 * @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
     2287 */
     2288function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
     2289    if ( isset( $args['anyOf'] ) ) {
     2290        $matching_schema = rest_find_any_matching_schema( $value, $args, $param );
     2291        if ( is_wp_error( $matching_schema ) ) {
     2292            return $matching_schema;
     2293        }
     2294
     2295        if ( ! isset( $args['type'] ) ) {
     2296            $args['type'] = $matching_schema['type'];
     2297        }
     2298
     2299        $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param );
     2300    }
     2301
     2302    if ( isset( $args['oneOf'] ) ) {
     2303        $matching_schema = rest_find_one_matching_schema( $value, $args, $param );
     2304        if ( is_wp_error( $matching_schema ) ) {
     2305            return $matching_schema;
     2306        }
     2307
     2308        if ( ! isset( $args['type'] ) ) {
     2309            $args['type'] = $matching_schema['type'];
     2310        }
     2311
     2312        $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param );
     2313    }
     2314
     2315    $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
     2316
     2317    if ( ! isset( $args['type'] ) ) {
     2318        /* translators: %s: Parameter. */
     2319        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' );
     2320    }
     2321
     2322    if ( is_array( $args['type'] ) ) {
     2323        $best_type = rest_handle_multi_type_schema( $value, $args, $param );
     2324
     2325        if ( ! $best_type ) {
     2326            return null;
     2327        }
     2328
     2329        $args['type'] = $best_type;
     2330    }
     2331
     2332    if ( ! in_array( $args['type'], $allowed_types, true ) ) {
     2333        _doing_it_wrong(
     2334            __FUNCTION__,
     2335            /* translators: 1: Parameter, 2: The list of allowed types. */
     2336            wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ),
     2337            '5.5.0'
     2338        );
     2339    }
     2340
     2341    if ( 'array' === $args['type'] ) {
     2342        $value = rest_sanitize_array( $value );
     2343
     2344        if ( ! empty( $args['items'] ) ) {
     2345            foreach ( $value as $index => $v ) {
     2346                $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
     2347            }
     2348        }
     2349
     2350        if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
     2351            /* translators: 1: Parameter. */
     2352            return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
     2353        }
     2354
     2355        return $value;
     2356    }
     2357
     2358    if ( 'object' === $args['type'] ) {
     2359        $value = rest_sanitize_object( $value );
     2360
     2361        foreach ( $value as $property => $v ) {
     2362            if ( isset( $args['properties'][ $property ] ) ) {
     2363                $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );
     2364                continue;
     2365            }
     2366
     2367            $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args );
     2368            if ( null !== $pattern_property_schema ) {
     2369                $value[ $property ] = rest_sanitize_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' );
     2370                continue;
     2371            }
     2372
     2373            if ( isset( $args['additionalProperties'] ) ) {
     2374                if ( false === $args['additionalProperties'] ) {
     2375                    unset( $value[ $property ] );
     2376                } elseif ( is_array( $args['additionalProperties'] ) ) {
     2377                    $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' );
     2378                }
     2379            }
     2380        }
     2381
     2382        return $value;
     2383    }
     2384
     2385    if ( 'null' === $args['type'] ) {
     2386        return null;
     2387    }
     2388
     2389    if ( 'integer' === $args['type'] ) {
     2390        return (int) $value;
     2391    }
     2392
     2393    if ( 'number' === $args['type'] ) {
     2394        return (float) $value;
     2395    }
     2396
     2397    if ( 'boolean' === $args['type'] ) {
     2398        return rest_sanitize_boolean( $value );
     2399    }
     2400
     2401    // This behavior matches rest_validate_value_from_schema().
     2402    if ( isset( $args['format'] )
     2403        && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) )
     2404    ) {
     2405        switch ( $args['format'] ) {
     2406            case 'hex-color':
     2407                return (string) sanitize_hex_color( $value );
     2408
     2409            case 'date-time':
     2410                return sanitize_text_field( $value );
     2411
     2412            case 'email':
     2413                // sanitize_email() validates, which would be unexpected.
     2414                return sanitize_text_field( $value );
     2415
     2416            case 'uri':
     2417                return esc_url_raw( $value );
     2418
     2419            case 'ip':
     2420                return sanitize_text_field( $value );
     2421
     2422            case 'uuid':
     2423                return sanitize_text_field( $value );
     2424        }
     2425    }
     2426
     2427    if ( 'string' === $args['type'] ) {
     2428        return (string) $value;
     2429    }
     2430
     2431    return $value;
     2432}
     2433
     2434/**
     2435 * Append result of internal request to REST API for purpose of preloading data to be attached to a page.
     2436 * Expected to be called in the context of `array_reduce`.
     2437 *
     2438 * @since 5.0.0
     2439 *
     2440 * @param array  $memo Reduce accumulator.
     2441 * @param string $path REST API path to preload.
     2442 * @return array Modified reduce accumulator.
     2443 */
     2444function rest_preload_api_request( $memo, $path ) {
     2445    // array_reduce() doesn't support passing an array in PHP 5.2,
     2446    // so we need to make sure we start with one.
     2447    if ( ! is_array( $memo ) ) {
     2448        $memo = array();
     2449    }
     2450
     2451    if ( empty( $path ) ) {
     2452        return $memo;
     2453    }
     2454
     2455    $method = 'GET';
     2456    if ( is_array( $path ) && 2 === count( $path ) ) {
     2457        $method = end( $path );
     2458        $path   = reset( $path );
     2459
     2460        if ( ! in_array( $method, array( 'GET', 'OPTIONS' ), true ) ) {
     2461            $method = 'GET';
     2462        }
     2463    }
     2464
     2465    $path_parts = parse_url( $path );
     2466    if ( false === $path_parts ) {
     2467        return $memo;
     2468    }
     2469
     2470    $request = new WP_REST_Request( $method, $path_parts['path'] );
     2471    if ( ! empty( $path_parts['query'] ) ) {
     2472        parse_str( $path_parts['query'], $query_params );
     2473        $request->set_query_params( $query_params );
     2474    }
     2475
     2476    $response = rest_do_request( $request );
     2477    if ( 200 === $response->status ) {
     2478        $server = rest_get_server();
     2479        $data   = (array) $response->get_data();
     2480        $links  = $server::get_compact_response_links( $response );
     2481        if ( ! empty( $links ) ) {
     2482            $data['_links'] = $links;
     2483        }
     2484
     2485        if ( 'OPTIONS' === $method ) {
     2486            $response = rest_send_allow_header( $response, $server, $request );
     2487
     2488            $memo[ $method ][ $path ] = array(
     2489                'body'    => $data,
     2490                'headers' => $response->headers,
     2491            );
     2492        } else {
     2493            $memo[ $path ] = array(
     2494                'body'    => $data,
     2495                'headers' => $response->headers,
     2496            );
     2497        }
     2498    }
     2499
     2500    return $memo;
     2501}
     2502
     2503/**
     2504 * Parses the "_embed" parameter into the list of resources to embed.
     2505 *
     2506 * @since 5.4.0
     2507 *
     2508 * @param string|array $embed Raw "_embed" parameter value.
     2509 * @return true|string[] Either true to embed all embeds, or a list of relations to embed.
     2510 */
     2511function rest_parse_embed_param( $embed ) {
     2512    if ( ! $embed || 'true' === $embed || '1' === $embed ) {
     2513        return true;
     2514    }
     2515
     2516    $rels = wp_parse_list( $embed );
     2517
     2518    if ( ! $rels ) {
     2519        return true;
     2520    }
     2521
     2522    return $rels;
     2523}
     2524
     2525/**
     2526 * Filters the response to remove any fields not available in the given context.
     2527 *
     2528 * @since 5.5.0
     2529 * @since 5.6.0 Support the "patternProperties" keyword for objects.
     2530 *              Support the "anyOf" and "oneOf" keywords.
     2531 *
     2532 * @param array|object $data    The response data to modify.
     2533 * @param array        $schema  The schema for the endpoint used to filter the response.
     2534 * @param string       $context The requested context.
     2535 * @return array|object The filtered response data.
     2536 */
     2537function rest_filter_response_by_context( $data, $schema, $context ) {
     2538    if ( isset( $schema['anyOf'] ) ) {
     2539        $matching_schema = rest_find_any_matching_schema( $data, $schema, '' );
     2540        if ( ! is_wp_error( $matching_schema ) ) {
     2541            if ( ! isset( $schema['type'] ) ) {
     2542                $schema['type'] = $matching_schema['type'];
     2543            }
     2544
     2545            $data = rest_filter_response_by_context( $data, $matching_schema, $context );
     2546        }
     2547    }
     2548
     2549    if ( isset( $schema['oneOf'] ) ) {
     2550        $matching_schema = rest_find_one_matching_schema( $data, $schema, '', true );
     2551        if ( ! is_wp_error( $matching_schema ) ) {
     2552            if ( ! isset( $schema['type'] ) ) {
     2553                $schema['type'] = $matching_schema['type'];
     2554            }
     2555
     2556            $data = rest_filter_response_by_context( $data, $matching_schema, $context );
     2557        }
     2558    }
     2559
     2560    if ( ! is_array( $data ) && ! is_object( $data ) ) {
     2561        return $data;
     2562    }
     2563
     2564    if ( isset( $schema['type'] ) ) {
     2565        $type = $schema['type'];
     2566    } elseif ( isset( $schema['properties'] ) ) {
     2567        $type = 'object'; // Back compat if a developer accidentally omitted the type.
     2568    } else {
     2569        return $data;
     2570    }
     2571
     2572    $is_array_type  = 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) );
     2573    $is_object_type = 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) );
     2574
     2575    if ( $is_array_type && $is_object_type ) {
     2576        if ( rest_is_array( $data ) ) {
     2577            $is_object_type = false;
     2578        } else {
     2579            $is_array_type = false;
     2580        }
     2581    }
     2582
     2583    $has_additional_properties = $is_object_type && isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] );
     2584
     2585    foreach ( $data as $key => $value ) {
     2586        $check = array();
     2587
     2588        if ( $is_array_type ) {
     2589            $check = isset( $schema['items'] ) ? $schema['items'] : array();
     2590        } elseif ( $is_object_type ) {
     2591            if ( isset( $schema['properties'][ $key ] ) ) {
     2592                $check = $schema['properties'][ $key ];
     2593            } else {
     2594                $pattern_property_schema = rest_find_matching_pattern_property_schema( $key, $schema );
     2595                if ( null !== $pattern_property_schema ) {
     2596                    $check = $pattern_property_schema;
     2597                } elseif ( $has_additional_properties ) {
     2598                    $check = $schema['additionalProperties'];
     2599                }
     2600            }
     2601        }
     2602
     2603        if ( ! isset( $check['context'] ) ) {
     2604            continue;
     2605        }
     2606
     2607        if ( ! in_array( $context, $check['context'], true ) ) {
     2608            if ( $is_array_type ) {
     2609                // All array items share schema, so there's no need to check each one.
     2610                $data = array();
     2611                break;
     2612            }
     2613
     2614            if ( is_object( $data ) ) {
     2615                unset( $data->$key );
     2616            } else {
     2617                unset( $data[ $key ] );
     2618            }
     2619        } elseif ( is_array( $value ) || is_object( $value ) ) {
     2620            $new_value = rest_filter_response_by_context( $value, $check, $context );
     2621
     2622            if ( is_object( $data ) ) {
     2623                $data->$key = $new_value;
     2624            } else {
     2625                $data[ $key ] = $new_value;
     2626            }
     2627        }
     2628    }
     2629
     2630    return $data;
     2631}
     2632
     2633/**
     2634 * Sets the "additionalProperties" to false by default for all object definitions in the schema.
     2635 *
     2636 * @since 5.5.0
     2637 * @since 5.6.0 Support the "patternProperties" keyword.
     2638 *
     2639 * @param array $schema The schema to modify.
     2640 * @return array The modified schema.
     2641 */
     2642function rest_default_additional_properties_to_false( $schema ) {
     2643    $type = (array) $schema['type'];
     2644
     2645    if ( in_array( 'object', $type, true ) ) {
     2646        if ( isset( $schema['properties'] ) ) {
     2647            foreach ( $schema['properties'] as $key => $child_schema ) {
     2648                $schema['properties'][ $key ] = rest_default_additional_properties_to_false( $child_schema );
     2649            }
     2650        }
     2651
     2652        if ( isset( $schema['patternProperties'] ) ) {
     2653            foreach ( $schema['patternProperties'] as $key => $child_schema ) {
     2654                $schema['patternProperties'][ $key ] = rest_default_additional_properties_to_false( $child_schema );
     2655            }
     2656        }
     2657
     2658        if ( ! isset( $schema['additionalProperties'] ) ) {
     2659            $schema['additionalProperties'] = false;
     2660        }
     2661    }
     2662
     2663    if ( in_array( 'array', $type, true ) ) {
     2664        if ( isset( $schema['items'] ) ) {
     2665            $schema['items'] = rest_default_additional_properties_to_false( $schema['items'] );
     2666        }
     2667    }
     2668
     2669    return $schema;
     2670}
     2671
     2672/**
     2673 * Gets the REST API route for a post.
     2674 *
     2675 * @since 5.5.0
     2676 *
     2677 * @param int|WP_Post $post Post ID or post object.
     2678 * @return string The route path with a leading slash for the given post, or an empty string if there is not a route.
     2679 */
     2680function rest_get_route_for_post( $post ) {
     2681    $post = get_post( $post );
     2682
     2683    if ( ! $post instanceof WP_Post ) {
     2684        return '';
     2685    }
     2686
     2687    $post_type = get_post_type_object( $post->post_type );
     2688    if ( ! $post_type ) {
     2689        return '';
     2690    }
     2691
     2692    $controller = $post_type->get_rest_controller();
     2693    if ( ! $controller ) {
     2694        return '';
     2695    }
     2696
     2697    $route = '';
     2698
     2699    // The only two controllers that we can detect are the Attachments and Posts controllers.
     2700    if ( in_array( get_class( $controller ), array( 'WP_REST_Attachments_Controller', 'WP_REST_Posts_Controller' ), true ) ) {
     2701        $namespace = 'wp/v2';
     2702        $rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name;
     2703        $route     = sprintf( '/%s/%s/%d', $namespace, $rest_base, $post->ID );
     2704    }
     2705
     2706    /**
     2707     * Filters the REST API route for a post.
     2708     *
     2709     * @since 5.5.0
     2710     *
     2711     * @param string  $route The route path.
     2712     * @param WP_Post $post  The post object.
     2713     */
     2714    return apply_filters( 'rest_route_for_post', $route, $post );
     2715}
     2716
     2717/**
     2718 * Gets the REST API route for a term.
     2719 *
     2720 * @since 5.5.0
     2721 *
     2722 * @param int|WP_Term $term Term ID or term object.
     2723 * @return string The route path with a leading slash for the given term, or an empty string if there is not a route.
     2724 */
     2725function rest_get_route_for_term( $term ) {
     2726    $term = get_term( $term );
     2727
     2728    if ( ! $term instanceof WP_Term ) {
     2729        return '';
     2730    }
     2731
     2732    $taxonomy = get_taxonomy( $term->taxonomy );
     2733    if ( ! $taxonomy ) {
     2734        return '';
     2735    }
     2736
     2737    $controller = $taxonomy->get_rest_controller();
     2738    if ( ! $controller ) {
     2739        return '';
     2740    }
     2741
     2742    $route = '';
     2743
     2744    // The only controller that works is the Terms controller.
     2745    if ( $controller instanceof WP_REST_Terms_Controller ) {
     2746        $namespace = 'wp/v2';
     2747        $rest_base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     2748        $route     = sprintf( '/%s/%s/%d', $namespace, $rest_base, $term->term_id );
     2749    }
     2750
     2751    /**
     2752     * Filters the REST API route for a term.
     2753     *
     2754     * @since 5.5.0
     2755     *
     2756     * @param string  $route The route path.
     2757     * @param WP_Term $term  The term object.
     2758     */
     2759    return apply_filters( 'rest_route_for_term', $route, $term );
     2760}
     2761
     2762/**
     2763 * Gets the REST route for the currently queried object.
     2764 *
     2765 * @since 5.5.0
     2766 *
     2767 * @return string The REST route of the resource, or an empty string if no resource identified.
     2768 */
     2769function rest_get_queried_resource_route() {
     2770    if ( is_singular() ) {
     2771        $route = rest_get_route_for_post( get_queried_object() );
     2772    } elseif ( is_category() || is_tag() || is_tax() ) {
     2773        $route = rest_get_route_for_term( get_queried_object() );
     2774    } elseif ( is_author() ) {
     2775        $route = '/wp/v2/users/' . get_queried_object_id();
     2776    } else {
     2777        $route = '';
     2778    }
     2779
     2780    /**
     2781     * Filters the REST route for the currently queried object.
     2782     *
     2783     * @since 5.5.0
     2784     *
     2785     * @param string $link The route with a leading slash, or an empty string.
     2786     */
     2787    return apply_filters( 'rest_queried_resource_route', $route );
     2788}
     2789
     2790/**
     2791 * Retrieves an array of endpoint arguments from the item schema and endpoint method.
     2792 *
     2793 * @since 5.6.0
     2794 *
     2795 * @param array  $schema The full JSON schema for the endpoint.
     2796 * @param string $method Optional. HTTP method of the endpoint. The arguments for `CREATABLE` endpoints are
     2797 *                       checked for required values and may fall-back to a given default, this is not done
     2798 *                       on `EDITABLE` endpoints. Default WP_REST_Server::CREATABLE.
     2799 * @return array The endpoint arguments.
     2800 */
     2801function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::CREATABLE ) {
     2802
     2803    $schema_properties       = ! empty( $schema['properties'] ) ? $schema['properties'] : array();
     2804    $endpoint_args           = array();
     2805    $valid_schema_properties = rest_get_allowed_schema_keywords();
     2806    $valid_schema_properties = array_diff( $valid_schema_properties, array( 'default', 'required' ) );
    27922807
    27932808    foreach ( $schema_properties as $field_id => $params ) {
     
    28022817            'sanitize_callback' => 'rest_sanitize_request_arg',
    28032818        );
    2804 
    2805         if ( isset( $params['description'] ) ) {
    2806             $endpoint_args[ $field_id ]['description'] = $params['description'];
    2807         }
    28082819
    28092820        if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) {
  • trunk/src/wp-includes/rest-api/class-wp-rest-server.php

    r49252 r49257  
    13811381        }
    13821382
     1383        $allowed_schema_keywords = array_flip( rest_get_allowed_schema_keywords() );
     1384
    13831385        $route = preg_replace( '#\(\?P<(\w+?)>.*?\)#', '{$1}', $route );
    13841386
     
    13981400
    13991401                foreach ( $callback['args'] as $key => $opts ) {
    1400                     $arg_data = array(
    1401                         'required' => ! empty( $opts['required'] ),
    1402                     );
    1403                     if ( isset( $opts['default'] ) ) {
    1404                         $arg_data['default'] = $opts['default'];
    1405                     }
    1406                     if ( isset( $opts['enum'] ) ) {
    1407                         $arg_data['enum'] = $opts['enum'];
    1408                     }
    1409                     if ( isset( $opts['description'] ) ) {
    1410                         $arg_data['description'] = $opts['description'];
    1411                     }
    1412                     if ( isset( $opts['type'] ) ) {
    1413                         $arg_data['type'] = $opts['type'];
    1414                     }
    1415                     if ( isset( $opts['items'] ) ) {
    1416                         $arg_data['items'] = $opts['items'];
    1417                     }
     1402                    $arg_data             = array_intersect_key( $opts, $allowed_schema_keywords );
     1403                    $arg_data['required'] = ! empty( $opts['required'] );
     1404
    14181405                    $endpoint_data['args'][ $key ] = $arg_data;
    14191406                }
  • trunk/tests/phpunit/tests/rest-api/rest-server.php

    r49252 r49257  
    19321932    }
    19331933
     1934    /**
     1935     * @ticket 51020
     1936     */
     1937    public function test_get_data_for_route_includes_permitted_schema_keywords() {
     1938        $keywords = array(
     1939            'title'                => 'Hi',
     1940            'description'          => 'World',
     1941            'type'                 => 'string',
     1942            'default'              => 0,
     1943            'format'               => 'uri',
     1944            'enum'                 => array( 'https://example.org' ),
     1945            'items'                => array( 'type' => 'string' ),
     1946            'properties'           => array( 'a' => array( 'type' => 'string' ) ),
     1947            'additionalProperties' => false,
     1948            'patternProperties'    => array( '\d' => array( 'type' => 'string' ) ),
     1949            'minProperties'        => 1,
     1950            'maxProperties'        => 5,
     1951            'minimum'              => 1,
     1952            'maximum'              => 5,
     1953            'exclusiveMinimum'     => true,
     1954            'exclusiveMaximum'     => false,
     1955            'multipleOf'           => 2,
     1956            'minLength'            => 1,
     1957            'maxLength'            => 5,
     1958            'pattern'              => '\d',
     1959            'minItems'             => 1,
     1960            'maxItems'             => 5,
     1961            'uniqueItems'          => true,
     1962            'anyOf'                => array(
     1963                array( 'type' => 'string' ),
     1964                array( 'type' => 'integer' ),
     1965            ),
     1966            'oneOf'                => array(
     1967                array( 'type' => 'string' ),
     1968                array( 'type' => 'integer' ),
     1969            ),
     1970        );
     1971
     1972        $param            = $keywords;
     1973        $param['invalid'] = true;
     1974
     1975        $expected             = $keywords;
     1976        $expected['required'] = false;
     1977
     1978        register_rest_route(
     1979            'test-ns/v1',
     1980            '/test',
     1981            array(
     1982                'methods'             => 'POST',
     1983                'callback'            => static function () {
     1984                    return new WP_REST_Response( 'test' );
     1985                },
     1986                'permission_callback' => '__return_true',
     1987                'args'                => array(
     1988                    'param' => $param,
     1989                ),
     1990            )
     1991        );
     1992
     1993        $response = rest_do_request( new WP_REST_Request( 'OPTIONS', '/test-ns/v1/test' ) );
     1994        $args     = $response->get_data()['endpoints'][0]['args'];
     1995
     1996        $this->assertSameSetsWithIndex( $expected, $args['param'] );
     1997    }
     1998
    19341999    public function _validate_as_integer_123( $value, $request, $key ) {
    19352000        if ( ! is_int( $value ) ) {
  • trunk/tests/qunit/fixtures/wp-api-generated.js

    r49252 r49257  
    3232                    "args": {
    3333                        "context": {
    34                             "required": false,
    35                             "default": "view"
     34                            "default": "view",
     35                            "required": false
    3636                        }
    3737                    }
     
    5454                    "args": {
    5555                        "validation": {
    56                             "required": false,
    57                             "default": "normal",
     56                            "type": "string",
    5857                            "enum": [
    5958                                "require-all-validate",
    6059                                "normal"
    6160                            ],
    62                             "type": "string"
     61                            "default": "normal",
     62                            "required": false
    6363                        },
    6464                        "requests": {
    65                             "required": true,
    6665                            "type": "array",
     66                            "maxItems": 25,
    6767                            "items": {
    6868                                "type": "object",
     
    101101                                    }
    102102                                }
    103                             }
     103                            },
     104                            "required": true
    104105                        }
    105106                    }
     
    126127                    "args": {
    127128                        "namespace": {
    128                             "required": false,
    129                             "default": "oembed/1.0"
     129                            "default": "oembed/1.0",
     130                            "required": false
    130131                        },
    131132                        "context": {
    132                             "required": false,
    133                             "default": "view"
     133                            "default": "view",
     134                            "required": false
    134135                        }
    135136                    }
     
    152153                    "args": {
    153154                        "url": {
    154                             "required": true,
    155155                            "description": "The URL of the resource for which to fetch oEmbed data.",
    156                             "type": "string"
     156                            "type": "string",
     157                            "format": "uri",
     158                            "required": true
    157159                        },
    158160                        "format": {
    159                             "required": false,
    160                             "default": "json"
     161                            "default": "json",
     162                            "required": false
    161163                        },
    162164                        "maxwidth": {
    163                             "required": false,
    164                             "default": 600
     165                            "default": 600,
     166                            "required": false
    165167                        }
    166168                    }
     
    183185                    "args": {
    184186                        "url": {
    185                             "required": true,
    186187                            "description": "The URL of the resource for which to fetch oEmbed data.",
    187                             "type": "string"
     188                            "type": "string",
     189                            "format": "uri",
     190                            "required": true
    188191                        },
    189192                        "format": {
    190                             "required": false,
     193                            "description": "The oEmbed format to use.",
     194                            "type": "string",
    191195                            "default": "json",
    192196                            "enum": [
     
    194198                                "xml"
    195199                            ],
    196                             "description": "The oEmbed format to use.",
    197                             "type": "string"
     200                            "required": false
    198201                        },
    199202                        "maxwidth": {
    200                             "required": false,
     203                            "description": "The maximum width of the embed frame in pixels.",
     204                            "type": "integer",
    201205                            "default": 600,
    202                             "description": "The maximum width of the embed frame in pixels.",
    203                             "type": "integer"
     206                            "required": false
    204207                        },
    205208                        "maxheight": {
    206                             "required": false,
    207209                            "description": "The maximum height of the embed frame in pixels.",
    208                             "type": "integer"
     210                            "type": "integer",
     211                            "required": false
    209212                        },
    210213                        "discover": {
    211                             "required": false,
     214                            "description": "Whether to perform an oEmbed discovery request for unsanctioned providers.",
     215                            "type": "boolean",
    212216                            "default": true,
    213                             "description": "Whether to perform an oEmbed discovery request for unsanctioned providers.",
    214                             "type": "boolean"
     217                            "required": false
    215218                        }
    216219                    }
     
    233236                    "args": {
    234237                        "namespace": {
    235                             "required": false,
    236                             "default": "wp/v2"
     238                            "default": "wp/v2",
     239                            "required": false
    237240                        },
    238241                        "context": {
    239                             "required": false,
    240                             "default": "view"
     242                            "default": "view",
     243                            "required": false
    241244                        }
    242245                    }
     
    260263                    "args": {
    261264                        "context": {
    262                             "required": false,
    263                             "default": "view",
     265                            "description": "Scope under which the request is made; determines fields present in response.",
     266                            "type": "string",
    264267                            "enum": [
    265268                                "view",
     
    267270                                "edit"
    268271                            ],
    269                             "description": "Scope under which the request is made; determines fields present in response.",
    270                             "type": "string"
     272                            "default": "view",
     273                            "required": false
    271274                        },
    272275                        "page": {
    273                             "required": false,
     276                            "description": "Current page of the collection.",
     277                            "type": "integer",
    274278                            "default": 1,
    275                             "description": "Current page of the collection.",
    276                             "type": "integer"
     279                            "minimum": 1,
     280                            "required": false
    277281                        },
    278282                        "per_page": {
    279                             "required": false,
     283                            "description": "Maximum number of items to be returned in result set.",
     284                            "type": "integer",
    280285                            "default": 10,
    281                             "description": "Maximum number of items to be returned in result set.",
    282                             "type": "integer"
     286                            "minimum": 1,
     287                            "maximum": 100,
     288                            "required": false
    283289                        },
    284290                        "search": {
    285                             "required": false,
    286291                            "description": "Limit results to those matching a string.",
    287                             "type": "string"
     292                            "type": "string",
     293                            "required": false
    288294                        },
    289295                        "after": {
    290                             "required": false,
    291296                            "description": "Limit response to posts published after a given ISO8601 compliant date.",
    292                             "type": "string"
     297                            "type": "string",
     298                            "format": "date-time",
     299                            "required": false
    293300                        },
    294301                        "author": {
    295                             "required": false,
    296                             "default": [],
    297302                            "description": "Limit result set to posts assigned to specific authors.",
    298303                            "type": "array",
    299304                            "items": {
    300305                                "type": "integer"
    301                             }
     306                            },
     307                            "default": [],
     308                            "required": false
    302309                        },
    303310                        "author_exclude": {
    304                             "required": false,
    305                             "default": [],
    306311                            "description": "Ensure result set excludes posts assigned to specific authors.",
    307312                            "type": "array",
    308313                            "items": {
    309314                                "type": "integer"
    310                             }
     315                            },
     316                            "default": [],
     317                            "required": false
    311318                        },
    312319                        "before": {
    313                             "required": false,
    314320                            "description": "Limit response to posts published before a given ISO8601 compliant date.",
    315                             "type": "string"
     321                            "type": "string",
     322                            "format": "date-time",
     323                            "required": false
    316324                        },
    317325                        "exclude": {
    318                             "required": false,
    319                             "default": [],
    320326                            "description": "Ensure result set excludes specific IDs.",
    321327                            "type": "array",
    322328                            "items": {
    323329                                "type": "integer"
    324                             }
     330                            },
     331                            "default": [],
     332                            "required": false
    325333                        },
    326334                        "include": {
    327                             "required": false,
    328                             "default": [],
    329335                            "description": "Limit result set to specific IDs.",
    330336                            "type": "array",
    331337                            "items": {
    332338                                "type": "integer"
    333                             }
     339                            },
     340                            "default": [],
     341                            "required": false
    334342                        },
    335343                        "offset": {
    336                             "required": false,
    337344                            "description": "Offset the result set by a specific number of items.",
    338                             "type": "integer"
     345                            "type": "integer",
     346                            "required": false
    339347                        },
    340348                        "order": {
    341                             "required": false,
     349                            "description": "Order sort attribute ascending or descending.",
     350                            "type": "string",
    342351                            "default": "desc",
    343352                            "enum": [
     
    345354                                "desc"
    346355                            ],
    347                             "description": "Order sort attribute ascending or descending.",
    348                             "type": "string"
     356                            "required": false
    349357                        },
    350358                        "orderby": {
    351                             "required": false,
     359                            "description": "Sort collection by object attribute.",
     360                            "type": "string",
    352361                            "default": "date",
    353362                            "enum": [
     
    363372                                "title"
    364373                            ],
    365                             "description": "Sort collection by object attribute.",
    366                             "type": "string"
     374                            "required": false
    367375                        },
    368376                        "slug": {
    369                             "required": false,
    370377                            "description": "Limit result set to posts with one or more specific slugs.",
    371378                            "type": "array",
    372379                            "items": {
    373380                                "type": "string"
    374                             }
     381                            },
     382                            "required": false
    375383                        },
    376384                        "status": {
    377                             "required": false,
    378385                            "default": "publish",
    379386                            "description": "Limit result set to posts assigned one or more statuses.",
     
    396403                                ],
    397404                                "type": "string"
    398                             }
     405                            },
     406                            "required": false
    399407                        },
    400408                        "tax_relation": {
    401                             "required": false,
     409                            "description": "Limit result set based on relationship between multiple taxonomies.",
     410                            "type": "string",
    402411                            "enum": [
    403412                                "AND",
    404413                                "OR"
    405414                            ],
    406                             "description": "Limit result set based on relationship between multiple taxonomies.",
    407                             "type": "string"
     415                            "required": false
    408416                        },
    409417                        "categories": {
    410                             "required": false,
    411                             "default": [],
    412418                            "description": "Limit result set to all items that have the specified term assigned in the categories taxonomy.",
    413419                            "type": "array",
    414420                            "items": {
    415421                                "type": "integer"
    416                             }
     422                            },
     423                            "default": [],
     424                            "required": false
    417425                        },
    418426                        "categories_exclude": {
    419                             "required": false,
    420                             "default": [],
    421427                            "description": "Limit result set to all items except those that have the specified term assigned in the categories taxonomy.",
    422428                            "type": "array",
    423429                            "items": {
    424430                                "type": "integer"
    425                             }
     431                            },
     432                            "default": [],
     433                            "required": false
    426434                        },
    427435                        "tags": {
    428                             "required": false,
    429                             "default": [],
    430436                            "description": "Limit result set to all items that have the specified term assigned in the tags taxonomy.",
    431437                            "type": "array",
    432438                            "items": {
    433439                                "type": "integer"
    434                             }
     440                            },
     441                            "default": [],
     442                            "required": false
    435443                        },
    436444                        "tags_exclude": {
    437                             "required": false,
    438                             "default": [],
    439445                            "description": "Limit result set to all items except those that have the specified term assigned in the tags taxonomy.",
    440446                            "type": "array",
    441447                            "items": {
    442448                                "type": "integer"
    443                             }
     449                            },
     450                            "default": [],
     451                            "required": false
    444452                        },
    445453                        "sticky": {
    446                             "required": false,
    447454                            "description": "Limit result set to items that are sticky.",
    448                             "type": "boolean"
     455                            "type": "boolean",
     456                            "required": false
    449457                        }
    450458                    }
     
    456464                    "args": {
    457465                        "date": {
    458                             "required": false,
    459466                            "description": "The date the object was published, in the site's timezone.",
    460467                            "type": [
    461468                                "string",
    462469                                "null"
    463                             ]
     470                            ],
     471                            "format": "date-time",
     472                            "required": false
    464473                        },
    465474                        "date_gmt": {
    466                             "required": false,
    467475                            "description": "The date the object was published, as GMT.",
    468476                            "type": [
    469477                                "string",
    470478                                "null"
    471                             ]
     479                            ],
     480                            "format": "date-time",
     481                            "required": false
    472482                        },
    473483                        "slug": {
    474                             "required": false,
    475484                            "description": "An alphanumeric identifier for the object unique to its type.",
    476                             "type": "string"
     485                            "type": "string",
     486                            "required": false
    477487                        },
    478488                        "status": {
    479                             "required": false,
     489                            "description": "A named status for the object.",
     490                            "type": "string",
    480491                            "enum": [
    481492                                "publish",
     
    485496                                "private"
    486497                            ],
    487                             "description": "A named status for the object.",
    488                             "type": "string"
     498                            "required": false
    489499                        },
    490500                        "password": {
    491                             "required": false,
    492501                            "description": "A password to protect access to the content and excerpt.",
    493                             "type": "string"
     502                            "type": "string",
     503                            "required": false
    494504                        },
    495505                        "title": {
    496                             "required": false,
    497506                            "description": "The title for the object.",
    498                             "type": "object"
     507                            "type": "object",
     508                            "properties": {
     509                                "raw": {
     510                                    "description": "Title for the object, as it exists in the database.",
     511                                    "type": "string",
     512                                    "context": [
     513                                        "edit"
     514                                    ]
     515                                },
     516                                "rendered": {
     517                                    "description": "HTML title for the object, transformed for display.",
     518                                    "type": "string",
     519                                    "context": [
     520                                        "view",
     521                                        "edit",
     522                                        "embed"
     523                                    ],
     524                                    "readonly": true
     525                                }
     526                            },
     527                            "required": false
    499528                        },
    500529                        "content": {
    501                             "required": false,
    502530                            "description": "The content for the object.",
    503                             "type": "object"
     531                            "type": "object",
     532                            "properties": {
     533                                "raw": {
     534                                    "description": "Content for the object, as it exists in the database.",
     535                                    "type": "string",
     536                                    "context": [
     537                                        "edit"
     538                                    ]
     539                                },
     540                                "rendered": {
     541                                    "description": "HTML content for the object, transformed for display.",
     542                                    "type": "string",
     543                                    "context": [
     544                                        "view",
     545                                        "edit"
     546                                    ],
     547                                    "readonly": true
     548                                },
     549                                "block_version": {
     550                                    "description": "Version of the content block format used by the object.",
     551                                    "type": "integer",
     552                                    "context": [
     553                                        "edit"
     554                                    ],
     555                                    "readonly": true
     556                                },
     557                                "protected": {
     558                                    "description": "Whether the content is protected with a password.",
     559                                    "type": "boolean",
     560                                    "context": [
     561                                        "view",
     562                                        "edit",
     563                                        "embed"
     564                                    ],
     565                                    "readonly": true
     566                                }
     567                            },
     568                            "required": false
    504569                        },
    505570                        "author": {
    506                             "required": false,
    507571                            "description": "The ID for the author of the object.",
    508                             "type": "integer"
     572                            "type": "integer",
     573                            "required": false
    509574                        },
    510575                        "excerpt": {
    511                             "required": false,
    512576                            "description": "The excerpt for the object.",
    513                             "type": "object"
     577                            "type": "object",
     578                            "properties": {
     579                                "raw": {
     580                                    "description": "Excerpt for the object, as it exists in the database.",
     581                                    "type": "string",
     582                                    "context": [
     583                                        "edit"
     584                                    ]
     585                                },
     586                                "rendered": {
     587                                    "description": "HTML excerpt for the object, transformed for display.",
     588                                    "type": "string",
     589                                    "context": [
     590                                        "view",
     591                                        "edit",
     592                                        "embed"
     593                                    ],
     594                                    "readonly": true
     595                                },
     596                                "protected": {
     597                                    "description": "Whether the excerpt is protected with a password.",
     598                                    "type": "boolean",
     599                                    "context": [
     600                                        "view",
     601                                        "edit",
     602                                        "embed"
     603                                    ],
     604                                    "readonly": true
     605                                }
     606                            },
     607                            "required": false
    514608                        },
    515609                        "featured_media": {
    516                             "required": false,
    517610                            "description": "The ID of the featured media for the object.",
    518                             "type": "integer"
     611                            "type": "integer",
     612                            "required": false
    519613                        },
    520614                        "comment_status": {
    521                             "required": false,
     615                            "description": "Whether or not comments are open on the object.",
     616                            "type": "string",
    522617                            "enum": [
    523618                                "open",
    524619                                "closed"
    525620                            ],
    526                             "description": "Whether or not comments are open on the object.",
    527                             "type": "string"
     621                            "required": false
    528622                        },
    529623                        "ping_status": {
    530                             "required": false,
     624                            "description": "Whether or not the object can be pinged.",
     625                            "type": "string",
    531626                            "enum": [
    532627                                "open",
    533628                                "closed"
    534629                            ],
    535                             "description": "Whether or not the object can be pinged.",
    536                             "type": "string"
     630                            "required": false
    537631                        },
    538632                        "format": {
    539                             "required": false,
     633                            "description": "The format for the object.",
     634                            "type": "string",
    540635                            "enum": [
    541636                                "standard",
     
    550645                                "audio"
    551646                            ],
    552                             "description": "The format for the object.",
    553                             "type": "string"
     647                            "required": false
    554648                        },
    555649                        "meta": {
    556                             "required": false,
    557650                            "description": "Meta fields.",
    558                             "type": "object"
     651                            "type": "object",
     652                            "properties": [],
     653                            "required": false
    559654                        },
    560655                        "sticky": {
    561                             "required": false,
    562656                            "description": "Whether or not the object should be treated as sticky.",
    563                             "type": "boolean"
     657                            "type": "boolean",
     658                            "required": false
    564659                        },
    565660                        "template": {
    566                             "required": false,
    567661                            "description": "The theme file to use to display the object.",
    568                             "type": "string"
     662                            "type": "string",
     663                            "required": false
    569664                        },
    570665                        "categories": {
    571                             "required": false,
    572666                            "description": "The terms assigned to the object in the category taxonomy.",
    573667                            "type": "array",
    574668                            "items": {
    575669                                "type": "integer"
    576                             }
     670                            },
     671                            "required": false
    577672                        },
    578673                        "tags": {
    579                             "required": false,
    580674                            "description": "The terms assigned to the object in the post_tag taxonomy.",
    581675                            "type": "array",
    582676                            "items": {
    583677                                "type": "integer"
    584                             }
     678                            },
     679                            "required": false
    585680                        }
    586681                    }
     
    607702                    "args": {
    608703                        "id": {
    609                             "required": false,
    610704                            "description": "Unique identifier for the object.",
    611                             "type": "integer"
     705                            "type": "integer",
     706                            "required": false
    612707                        },
    613708                        "context": {
    614                             "required": false,
    615                             "default": "view",
     709                            "description": "Scope under which the request is made; determines fields present in response.",
     710                            "type": "string",
    616711                            "enum": [
    617712                                "view",
     
    619714                                "edit"
    620715                            ],
    621                             "description": "Scope under which the request is made; determines fields present in response.",
    622                             "type": "string"
     716                            "default": "view",
     717                            "required": false
    623718                        },
    624719                        "password": {
    625                             "required": false,
    626720                            "description": "The password for the post if it is password protected.",
    627                             "type": "string"
     721                            "type": "string",
     722                            "required": false
    628723                        }
    629724                    }
     
    637732                    "args": {
    638733                        "id": {
    639                             "required": false,
    640734                            "description": "Unique identifier for the object.",
    641                             "type": "integer"
     735                            "type": "integer",
     736                            "required": false
    642737                        },
    643738                        "date": {
    644                             "required": false,
    645739                            "description": "The date the object was published, in the site's timezone.",
    646740                            "type": [
    647741                                "string",
    648742                                "null"
    649                             ]
     743                            ],
     744                            "format": "date-time",
     745                            "required": false
    650746                        },
    651747                        "date_gmt": {
    652                             "required": false,
    653748                            "description": "The date the object was published, as GMT.",
    654749                            "type": [
    655750                                "string",
    656751                                "null"
    657                             ]
     752                            ],
     753                            "format": "date-time",
     754                            "required": false
    658755                        },
    659756                        "slug": {
    660                             "required": false,
    661757                            "description": "An alphanumeric identifier for the object unique to its type.",
    662                             "type": "string"
     758                            "type": "string",
     759                            "required": false
    663760                        },
    664761                        "status": {
    665                             "required": false,
     762                            "description": "A named status for the object.",
     763                            "type": "string",
    666764                            "enum": [
    667765                                "publish",
     
    671769                                "private"
    672770                            ],
    673                             "description": "A named status for the object.",
    674                             "type": "string"
     771                            "required": false
    675772                        },
    676773                        "password": {
    677                             "required": false,
    678774                            "description": "A password to protect access to the content and excerpt.",
    679                             "type": "string"
     775                            "type": "string",
     776                            "required": false
    680777                        },
    681778                        "title": {
    682                             "required": false,
    683779                            "description": "The title for the object.",
    684                             "type": "object"
     780                            "type": "object",
     781                            "properties": {
     782                                "raw": {
     783                                    "description": "Title for the object, as it exists in the database.",
     784                                    "type": "string",
     785                                    "context": [
     786                                        "edit"
     787                                    ]
     788                                },
     789                                "rendered": {
     790                                    "description": "HTML title for the object, transformed for display.",
     791                                    "type": "string",
     792                                    "context": [
     793                                        "view",
     794                                        "edit",
     795                                        "embed"
     796                                    ],
     797                                    "readonly": true
     798                                }
     799                            },
     800                            "required": false
    685801                        },
    686802                        "content": {
    687                             "required": false,
    688803                            "description": "The content for the object.",
    689                             "type": "object"
     804                            "type": "object",
     805                            "properties": {
     806                                "raw": {
     807                                    "description": "Content for the object, as it exists in the database.",
     808                                    "type": "string",
     809                                    "context": [
     810                                        "edit"
     811                                    ]
     812                                },
     813                                "rendered": {
     814                                    "description": "HTML content for the object, transformed for display.",
     815                                    "type": "string",
     816                                    "context": [
     817                                        "view",
     818                                        "edit"
     819                                    ],
     820                                    "readonly": true
     821                                },
     822                                "block_version": {
     823                                    "description": "Version of the content block format used by the object.",
     824                                    "type": "integer",
     825                                    "context": [
     826                                        "edit"
     827                                    ],
     828                                    "readonly": true
     829                                },
     830                                "protected": {
     831                                    "description": "Whether the content is protected with a password.",
     832                                    "type": "boolean",
     833                                    "context": [
     834                                        "view",
     835                                        "edit",
     836                                        "embed"
     837                                    ],
     838                                    "readonly": true
     839                                }
     840                            },
     841                            "required": false
    690842                        },
    691843                        "author": {
    692                             "required": false,
    693844                            "description": "The ID for the author of the object.",
    694                             "type": "integer"
     845                            "type": "integer",
     846                            "required": false
    695847                        },
    696848                        "excerpt": {
    697                             "required": false,
    698849                            "description": "The excerpt for the object.",
    699                             "type": "object"
     850                            "type": "object",
     851                            "properties": {
     852                                "raw": {
     853                                    "description": "Excerpt for the object, as it exists in the database.",
     854                                    "type": "string",
     855                                    "context": [
     856                                        "edit"
     857                                    ]
     858                                },
     859                                "rendered": {
     860                                    "description": "HTML excerpt for the object, transformed for display.",
     861                                    "type": "string",
     862                                    "context": [
     863                                        "view",
     864                                        "edit",
     865                                        "embed"
     866                                    ],
     867                                    "readonly": true
     868                                },
     869                                "protected": {
     870                                    "description": "Whether the excerpt is protected with a password.",
     871                                    "type": "boolean",
     872                                    "context": [
     873                                        "view",
     874                                        "edit",
     875                                        "embed"
     876                                    ],
     877                                    "readonly": true
     878                                }
     879                            },
     880                            "required": false
    700881                        },
    701882                        "featured_media": {
    702                             "required": false,
    703883                            "description": "The ID of the featured media for the object.",
    704                             "type": "integer"
     884                            "type": "integer",
     885                            "required": false
    705886                        },
    706887                        "comment_status": {
    707                             "required": false,
     888                            "description": "Whether or not comments are open on the object.",
     889                            "type": "string",
    708890                            "enum": [
    709891                                "open",
    710892                                "closed"
    711893                            ],
    712                             "description": "Whether or not comments are open on the object.",
    713                             "type": "string"
     894                            "required": false
    714895                        },
    715896                        "ping_status": {
    716                             "required": false,
     897                            "description": "Whether or not the object can be pinged.",
     898                            "type": "string",
    717899                            "enum": [
    718900                                "open",
    719901                                "closed"
    720902                            ],
    721                             "description": "Whether or not the object can be pinged.",
    722                             "type": "string"
     903                            "required": false
    723904                        },
    724905                        "format": {
    725                             "required": false,
     906                            "description": "The format for the object.",
     907                            "type": "string",
    726908                            "enum": [
    727909                                "standard",
     
    736918                                "audio"
    737919                            ],
    738                             "description": "The format for the object.",
    739                             "type": "string"
     920                            "required": false
    740921                        },
    741922                        "meta": {
    742                             "required": false,
    743923                            "description": "Meta fields.",
    744                             "type": "object"
     924                            "type": "object",
     925                            "properties": [],
     926                            "required": false
    745927                        },
    746928                        "sticky": {
    747                             "required": false,
    748929                            "description": "Whether or not the object should be treated as sticky.",
    749                             "type": "boolean"
     930                            "type": "boolean",
     931                            "required": false
    750932                        },
    751933                        "template": {
    752                             "required": false,
    753934                            "description": "The theme file to use to display the object.",
    754                             "type": "string"
     935                            "type": "string",
     936                            "required": false
    755937                        },
    756938                        "categories": {
    757                             "required": false,
    758939                            "description": "The terms assigned to the object in the category taxonomy.",
    759940                            "type": "array",
    760941                            "items": {
    761942                                "type": "integer"
    762                             }
     943                            },
     944                            "required": false
    763945                        },
    764946                        "tags": {
    765                             "required": false,
    766947                            "description": "The terms assigned to the object in the post_tag taxonomy.",
    767948                            "type": "array",
    768949                            "items": {
    769950                                "type": "integer"
    770                             }
     951                            },
     952                            "required": false
    771953                        }
    772954                    }
     
    778960                    "args": {
    779961                        "id": {
    780                             "required": false,
    781962                            "description": "Unique identifier for the object.",
    782                             "type": "integer"
     963                            "type": "integer",
     964                            "required": false
    783965                        },
    784966                        "force": {
    785                             "required": false,
     967                            "type": "boolean",
    786968                            "default": false,
    787969                            "description": "Whether to bypass Trash and force deletion.",
    788                             "type": "boolean"
     970                            "required": false
    789971                        }
    790972                    }
     
    804986                    "args": {
    805987                        "parent": {
    806                             "required": false,
    807988                            "description": "The ID for the parent of the object.",
    808                             "type": "integer"
     989                            "type": "integer",
     990                            "required": false
    809991                        },
    810992                        "context": {
    811                             "required": false,
    812                             "default": "view",
     993                            "description": "Scope under which the request is made; determines fields present in response.",
     994                            "type": "string",
    813995                            "enum": [
    814996                                "view",
     
    816998                                "edit"
    817999                            ],
    818                             "description": "Scope under which the request is made; determines fields present in response.",
    819                             "type": "string"
     1000                            "default": "view",
     1001                            "required": false
    8201002                        },
    8211003                        "page": {
    822                             "required": false,
     1004                            "description": "Current page of the collection.",
     1005                            "type": "integer",
    8231006                            "default": 1,
    824                             "description": "Current page of the collection.",
    825                             "type": "integer"
     1007                            "minimum": 1,
     1008                            "required": false
    8261009                        },
    8271010                        "per_page": {
    828                             "required": false,
    8291011                            "description": "Maximum number of items to be returned in result set.",
    830                             "type": "integer"
     1012                            "type": "integer",
     1013                            "minimum": 1,
     1014                            "maximum": 100,
     1015                            "required": false
    8311016                        },
    8321017                        "search": {
    833                             "required": false,
    8341018                            "description": "Limit results to those matching a string.",
    835                             "type": "string"
     1019                            "type": "string",
     1020                            "required": false
    8361021                        },
    8371022                        "exclude": {
    838                             "required": false,
    839                             "default": [],
    8401023                            "description": "Ensure result set excludes specific IDs.",
    8411024                            "type": "array",
    8421025                            "items": {
    8431026                                "type": "integer"
    844                             }
     1027                            },
     1028                            "default": [],
     1029                            "required": false
    8451030                        },
    8461031                        "include": {
    847                             "required": false,
    848                             "default": [],
    8491032                            "description": "Limit result set to specific IDs.",
    8501033                            "type": "array",
    8511034                            "items": {
    8521035                                "type": "integer"
    853                             }
     1036                            },
     1037                            "default": [],
     1038                            "required": false
    8541039                        },
    8551040                        "offset": {
    856                             "required": false,
    8571041                            "description": "Offset the result set by a specific number of items.",
    858                             "type": "integer"
     1042                            "type": "integer",
     1043                            "required": false
    8591044                        },
    8601045                        "order": {
    861                             "required": false,
     1046                            "description": "Order sort attribute ascending or descending.",
     1047                            "type": "string",
    8621048                            "default": "desc",
    8631049                            "enum": [
     
    8651051                                "desc"
    8661052                            ],
    867                             "description": "Order sort attribute ascending or descending.",
    868                             "type": "string"
     1053                            "required": false
    8691054                        },
    8701055                        "orderby": {
    871                             "required": false,
     1056                            "description": "Sort collection by object attribute.",
     1057                            "type": "string",
    8721058                            "default": "date",
    8731059                            "enum": [
     
    8801066                                "title"
    8811067                            ],
    882                             "description": "Sort collection by object attribute.",
    883                             "type": "string"
     1068                            "required": false
    8841069                        }
    8851070                    }
     
    9001085                    "args": {
    9011086                        "parent": {
    902                             "required": false,
    9031087                            "description": "The ID for the parent of the object.",
    904                             "type": "integer"
     1088                            "type": "integer",
     1089                            "required": false
    9051090                        },
    9061091                        "id": {
    907                             "required": false,
    9081092                            "description": "Unique identifier for the object.",
    909                             "type": "integer"
     1093                            "type": "integer",
     1094                            "required": false
    9101095                        },
    9111096                        "context": {
    912                             "required": false,
    913                             "default": "view",
     1097                            "description": "Scope under which the request is made; determines fields present in response.",
     1098                            "type": "string",
    9141099                            "enum": [
    9151100                                "view",
     
    9171102                                "edit"
    9181103                            ],
    919                             "description": "Scope under which the request is made; determines fields present in response.",
    920                             "type": "string"
     1104                            "default": "view",
     1105                            "required": false
    9211106                        }
    9221107                    }
     
    9281113                    "args": {
    9291114                        "parent": {
    930                             "required": false,
    9311115                            "description": "The ID for the parent of the object.",
    932                             "type": "integer"
     1116                            "type": "integer",
     1117                            "required": false
    9331118                        },
    9341119                        "id": {
    935                             "required": false,
    9361120                            "description": "Unique identifier for the object.",
    937                             "type": "integer"
     1121                            "type": "integer",
     1122                            "required": false
    9381123                        },
    9391124                        "force": {
    940                             "required": false,
     1125                            "type": "boolean",
    9411126                            "default": false,
    9421127                            "description": "Required to be true, as revisions do not support trashing.",
    943                             "type": "boolean"
     1128                            "required": false
    9441129                        }
    9451130                    }
     
    9601145                    "args": {
    9611146                        "parent": {
    962                             "required": false,
    9631147                            "description": "The ID for the parent of the object.",
    964                             "type": "integer"
     1148                            "type": "integer",
     1149                            "required": false
    9651150                        },
    9661151                        "context": {
    967                             "required": false,
    968                             "default": "view",
     1152                            "description": "Scope under which the request is made; determines fields present in response.",
     1153                            "type": "string",
    9691154                            "enum": [
    9701155                                "view",
     
    9721157                                "edit"
    9731158                            ],
    974                             "description": "Scope under which the request is made; determines fields present in response.",
    975                             "type": "string"
     1159                            "default": "view",
     1160                            "required": false
    9761161                        }
    9771162                    }
     
    9831168                    "args": {
    9841169                        "parent": {
    985                             "required": false,
    9861170                            "description": "The ID for the parent of the object.",
    987                             "type": "integer"
     1171                            "type": "integer",
     1172                            "required": false
    9881173                        },
    9891174                        "date": {
    990                             "required": false,
    9911175                            "description": "The date the object was published, in the site's timezone.",
    9921176                            "type": [
    9931177                                "string",
    9941178                                "null"
    995                             ]
     1179                            ],
     1180                            "format": "date-time",
     1181                            "required": false
    9961182                        },
    9971183                        "date_gmt": {
    998                             "required": false,
    9991184                            "description": "The date the object was published, as GMT.",
    10001185                            "type": [
    10011186                                "string",
    10021187                                "null"
    1003                             ]
     1188                            ],
     1189                            "format": "date-time",
     1190                            "required": false
    10041191                        },
    10051192                        "slug": {
    1006                             "required": false,
    10071193                            "description": "An alphanumeric identifier for the object unique to its type.",
    1008                             "type": "string"
     1194                            "type": "string",
     1195                            "required": false
    10091196                        },
    10101197                        "status": {
    1011                             "required": false,
     1198                            "description": "A named status for the object.",
     1199                            "type": "string",
    10121200                            "enum": [
    10131201                                "publish",
     
    10171205                                "private"
    10181206                            ],
    1019                             "description": "A named status for the object.",
    1020                             "type": "string"
     1207                            "required": false
    10211208                        },
    10221209                        "password": {
    1023                             "required": false,
    10241210                            "description": "A password to protect access to the content and excerpt.",
    1025                             "type": "string"
     1211                            "type": "string",
     1212                            "required": false
    10261213                        },
    10271214                        "title": {
    1028                             "required": false,
    10291215                            "description": "The title for the object.",
    1030                             "type": "object"
     1216                            "type": "object",
     1217                            "properties": {
     1218                                "raw": {
     1219                                    "description": "Title for the object, as it exists in the database.",
     1220                                    "type": "string",
     1221                                    "context": [
     1222                                        "edit"
     1223                                    ]
     1224                                },
     1225                                "rendered": {
     1226                                    "description": "HTML title for the object, transformed for display.",
     1227                                    "type": "string",
     1228                                    "context": [
     1229                                        "view",
     1230                                        "edit",
     1231                                        "embed"
     1232                                    ],
     1233                                    "readonly": true
     1234                                }
     1235                            },
     1236                            "required": false
    10311237                        },
    10321238                        "content": {
    1033                             "required": false,
    10341239                            "description": "The content for the object.",
    1035                             "type": "object"
     1240                            "type": "object",
     1241                            "properties": {
     1242                                "raw": {
     1243                                    "description": "Content for the object, as it exists in the database.",
     1244                                    "type": "string",
     1245                                    "context": [
     1246                                        "edit"
     1247                                    ]
     1248                                },
     1249                                "rendered": {
     1250                                    "description": "HTML content for the object, transformed for display.",
     1251                                    "type": "string",
     1252                                    "context": [
     1253                                        "view",
     1254                                        "edit"
     1255                                    ],
     1256                                    "readonly": true
     1257                                },
     1258                                "block_version": {
     1259                                    "description": "Version of the content block format used by the object.",
     1260                                    "type": "integer",
     1261                                    "context": [
     1262                                        "edit"
     1263                                    ],
     1264                                    "readonly": true
     1265                                },
     1266                                "protected": {
     1267                                    "description": "Whether the content is protected with a password.",
     1268                                    "type": "boolean",
     1269                                    "context": [
     1270                                        "view",
     1271                                        "edit",
     1272                                        "embed"
     1273                                    ],
     1274                                    "readonly": true
     1275                                }
     1276                            },
     1277                            "required": false
    10361278                        },
    10371279                        "author": {
    1038                             "required": false,
    10391280                            "description": "The ID for the author of the object.",
    1040                             "type": "integer"
     1281                            "type": "integer",
     1282                            "required": false
    10411283                        },
    10421284                        "excerpt": {
    1043                             "required": false,
    10441285                            "description": "The excerpt for the object.",
    1045                             "type": "object"
     1286                            "type": "object",
     1287                            "properties": {
     1288                                "raw": {
     1289                                    "description": "Excerpt for the object, as it exists in the database.",
     1290                                    "type": "string",
     1291                                    "context": [
     1292                                        "edit"
     1293                                    ]
     1294                                },
     1295                                "rendered": {
     1296                                    "description": "HTML excerpt for the object, transformed for display.",
     1297                                    "type": "string",
     1298                                    "context": [
     1299                                        "view",
     1300                                        "edit",
     1301                                        "embed"
     1302                                    ],
     1303                                    "readonly": true
     1304                                },
     1305                                "protected": {
     1306                                    "description": "Whether the excerpt is protected with a password.",
     1307                                    "type": "boolean",
     1308                                    "context": [
     1309                                        "view",
     1310                                        "edit",
     1311                                        "embed"
     1312                                    ],
     1313                                    "readonly": true
     1314                                }
     1315                            },
     1316                            "required": false
    10461317                        },
    10471318                        "featured_media": {
    1048                             "required": false,
    10491319                            "description": "The ID of the featured media for the object.",
    1050                             "type": "integer"
     1320                            "type": "integer",
     1321                            "required": false
    10511322                        },
    10521323                        "comment_status": {
    1053                             "required": false,
     1324                            "description": "Whether or not comments are open on the object.",
     1325                            "type": "string",
    10541326                            "enum": [
    10551327                                "open",
    10561328                                "closed"
    10571329                            ],
    1058                             "description": "Whether or not comments are open on the object.",
    1059                             "type": "string"
     1330                            "required": false
    10601331                        },
    10611332                        "ping_status": {
    1062                             "required": false,
     1333                            "description": "Whether or not the object can be pinged.",
     1334                            "type": "string",
    10631335                            "enum": [
    10641336                                "open",
    10651337                                "closed"
    10661338                            ],
    1067                             "description": "Whether or not the object can be pinged.",
    1068                             "type": "string"
     1339                            "required": false
    10691340                        },
    10701341                        "format": {
    1071                             "required": false,
     1342                            "description": "The format for the object.",
     1343                            "type": "string",
    10721344                            "enum": [
    10731345                                "standard",
     
    10821354                                "audio"
    10831355                            ],
    1084                             "description": "The format for the object.",
    1085                             "type": "string"
     1356                            "required": false
    10861357                        },
    10871358                        "meta": {
    1088                             "required": false,
    10891359                            "description": "Meta fields.",
    1090                             "type": "object"
     1360                            "type": "object",
     1361                            "properties": [],
     1362                            "required": false
    10911363                        },
    10921364                        "sticky": {
    1093                             "required": false,
    10941365                            "description": "Whether or not the object should be treated as sticky.",
    1095                             "type": "boolean"
     1366                            "type": "boolean",
     1367                            "required": false
    10961368                        },
    10971369                        "template": {
    1098                             "required": false,
    10991370                            "description": "The theme file to use to display the object.",
    1100                             "type": "string"
     1371                            "type": "string",
     1372                            "required": false
    11011373                        },
    11021374                        "categories": {
    1103                             "required": false,
    11041375                            "description": "The terms assigned to the object in the category taxonomy.",
    11051376                            "type": "array",
    11061377                            "items": {
    11071378                                "type": "integer"
    1108                             }
     1379                            },
     1380                            "required": false
    11091381                        },
    11101382                        "tags": {
    1111                             "required": false,
    11121383                            "description": "The terms assigned to the object in the post_tag taxonomy.",
    11131384                            "type": "array",
    11141385                            "items": {
    11151386                                "type": "integer"
    1116                             }
     1387                            },
     1388                            "required": false
    11171389                        }
    11181390                    }
     
    11321404                    "args": {
    11331405                        "parent": {
    1134                             "required": false,
    11351406                            "description": "The ID for the parent of the object.",
    1136                             "type": "integer"
     1407                            "type": "integer",
     1408                            "required": false
    11371409                        },
    11381410                        "id": {
    1139                             "required": false,
    11401411                            "description": "The ID for the object.",
    1141                             "type": "integer"
     1412                            "type": "integer",
     1413                            "required": false
    11421414                        },
    11431415                        "context": {
    1144                             "required": false,
    1145                             "default": "view",
     1416                            "description": "Scope under which the request is made; determines fields present in response.",
     1417                            "type": "string",
    11461418                            "enum": [
    11471419                                "view",
     
    11491421                                "edit"
    11501422                            ],
    1151                             "description": "Scope under which the request is made; determines fields present in response.",
    1152                             "type": "string"
     1423                            "default": "view",
     1424                            "required": false
    11531425                        }
    11541426                    }
     
    11691441                    "args": {
    11701442                        "context": {
    1171                             "required": false,
    1172                             "default": "view",
     1443                            "description": "Scope under which the request is made; determines fields present in response.",
     1444                            "type": "string",
    11731445                            "enum": [
    11741446                                "view",
     
    11761448                                "edit"
    11771449                            ],
    1178                             "description": "Scope under which the request is made; determines fields present in response.",
    1179                             "type": "string"
     1450                            "default": "view",
     1451                            "required": false
    11801452                        },
    11811453                        "page": {
    1182                             "required": false,
     1454                            "description": "Current page of the collection.",
     1455                            "type": "integer",
    11831456                            "default": 1,
    1184                             "description": "Current page of the collection.",
    1185                             "type": "integer"
     1457                            "minimum": 1,
     1458                            "required": false
    11861459                        },
    11871460                        "per_page": {
    1188                             "required": false,
     1461                            "description": "Maximum number of items to be returned in result set.",
     1462                            "type": "integer",
    11891463                            "default": 10,
    1190                             "description": "Maximum number of items to be returned in result set.",
    1191                             "type": "integer"
     1464                            "minimum": 1,
     1465                            "maximum": 100,
     1466                            "required": false
    11921467                        },
    11931468                        "search": {
    1194                             "required": false,
    11951469                            "description": "Limit results to those matching a string.",
    1196                             "type": "string"
     1470                            "type": "string",
     1471                            "required": false
    11971472                        },
    11981473                        "after": {
    1199                             "required": false,
    12001474                            "description": "Limit response to posts published after a given ISO8601 compliant date.",
    1201                             "type": "string"
     1475                            "type": "string",
     1476                            "format": "date-time",
     1477                            "required": false
    12021478                        },
    12031479                        "author": {
    1204                             "required": false,
    1205                             "default": [],
    12061480                            "description": "Limit result set to posts assigned to specific authors.",
    12071481                            "type": "array",
    12081482                            "items": {
    12091483                                "type": "integer"
    1210                             }
     1484                            },
     1485                            "default": [],
     1486                            "required": false
    12111487                        },
    12121488                        "author_exclude": {
    1213                             "required": false,
    1214                             "default": [],
    12151489                            "description": "Ensure result set excludes posts assigned to specific authors.",
    12161490                            "type": "array",
    12171491                            "items": {
    12181492                                "type": "integer"
    1219                             }
     1493                            },
     1494                            "default": [],
     1495                            "required": false
    12201496                        },
    12211497                        "before": {
    1222                             "required": false,
    12231498                            "description": "Limit response to posts published before a given ISO8601 compliant date.",
    1224                             "type": "string"
     1499                            "type": "string",
     1500                            "format": "date-time",
     1501                            "required": false
    12251502                        },
    12261503                        "exclude": {
    1227                             "required": false,
    1228                             "default": [],
    12291504                            "description": "Ensure result set excludes specific IDs.",
    12301505                            "type": "array",
    12311506                            "items": {
    12321507                                "type": "integer"
    1233                             }
     1508                            },
     1509                            "default": [],
     1510                            "required": false
    12341511                        },
    12351512                        "include": {
    1236                             "required": false,
    1237                             "default": [],
    12381513                            "description": "Limit result set to specific IDs.",
    12391514                            "type": "array",
    12401515                            "items": {
    12411516                                "type": "integer"
    1242                             }
     1517                            },
     1518                            "default": [],
     1519                            "required": false
    12431520                        },
    12441521                        "menu_order": {
    1245                             "required": false,
    12461522                            "description": "Limit result set to posts with a specific menu_order value.",
    1247                             "type": "integer"
     1523                            "type": "integer",
     1524                            "required": false
    12481525                        },
    12491526                        "offset": {
    1250                             "required": false,
    12511527                            "description": "Offset the result set by a specific number of items.",
    1252                             "type": "integer"
     1528                            "type": "integer",
     1529                            "required": false
    12531530                        },
    12541531                        "order": {
    1255                             "required": false,
     1532                            "description": "Order sort attribute ascending or descending.",
     1533                            "type": "string",
    12561534                            "default": "desc",
    12571535                            "enum": [
     
    12591537                                "desc"
    12601538                            ],
    1261                             "description": "Order sort attribute ascending or descending.",
    1262                             "type": "string"
     1539                            "required": false
    12631540                        },
    12641541                        "orderby": {
    1265                             "required": false,
     1542                            "description": "Sort collection by object attribute.",
     1543                            "type": "string",
    12661544                            "default": "date",
    12671545                            "enum": [
     
    12781556                                "menu_order"
    12791557                            ],
    1280                             "description": "Sort collection by object attribute.",
    1281                             "type": "string"
     1558                            "required": false
    12821559                        },
    12831560                        "parent": {
    1284                             "required": false,
    1285                             "default": [],
    12861561                            "description": "Limit result set to items with particular parent IDs.",
    12871562                            "type": "array",
    12881563                            "items": {
    12891564                                "type": "integer"
    1290                             }
     1565                            },
     1566                            "default": [],
     1567                            "required": false
    12911568                        },
    12921569                        "parent_exclude": {
    1293                             "required": false,
    1294                             "default": [],
    12951570                            "description": "Limit result set to all items except those of a particular parent ID.",
    12961571                            "type": "array",
    12971572                            "items": {
    12981573                                "type": "integer"
    1299                             }
     1574                            },
     1575                            "default": [],
     1576                            "required": false
    13001577                        },
    13011578                        "slug": {
    1302                             "required": false,
    13031579                            "description": "Limit result set to posts with one or more specific slugs.",
    13041580                            "type": "array",
    13051581                            "items": {
    13061582                                "type": "string"
    1307                             }
     1583                            },
     1584                            "required": false
    13081585                        },
    13091586                        "status": {
    1310                             "required": false,
    13111587                            "default": "publish",
    13121588                            "description": "Limit result set to posts assigned one or more statuses.",
     
    13291605                                ],
    13301606                                "type": "string"
    1331                             }
     1607                            },
     1608                            "required": false
    13321609                        }
    13331610                    }
     
    13391616                    "args": {
    13401617                        "date": {
    1341                             "required": false,
    13421618                            "description": "The date the object was published, in the site's timezone.",
    13431619                            "type": [
    13441620                                "string",
    13451621                                "null"
    1346                             ]
     1622                            ],
     1623                            "format": "date-time",
     1624                            "required": false
    13471625                        },
    13481626                        "date_gmt": {
    1349                             "required": false,
    13501627                            "description": "The date the object was published, as GMT.",
    13511628                            "type": [
    13521629                                "string",
    13531630                                "null"
    1354                             ]
     1631                            ],
     1632                            "format": "date-time",
     1633                            "required": false
    13551634                        },
    13561635                        "slug": {
    1357                             "required": false,
    13581636                            "description": "An alphanumeric identifier for the object unique to its type.",
    1359                             "type": "string"
     1637                            "type": "string",
     1638                            "required": false
    13601639                        },
    13611640                        "status": {
    1362                             "required": false,
     1641                            "description": "A named status for the object.",
     1642                            "type": "string",
    13631643                            "enum": [
    13641644                                "publish",
     
    13681648                                "private"
    13691649                            ],
    1370                             "description": "A named status for the object.",
    1371                             "type": "string"
     1650                            "required": false
    13721651                        },
    13731652                        "password": {
    1374                             "required": false,
    13751653                            "description": "A password to protect access to the content and excerpt.",
    1376                             "type": "string"
     1654                            "type": "string",
     1655                            "required": false
    13771656                        },
    13781657                        "parent": {
    1379                             "required": false,
    13801658                            "description": "The ID for the parent of the object.",
    1381                             "type": "integer"
     1659                            "type": "integer",
     1660                            "required": false
    13821661                        },
    13831662                        "title": {
    1384                             "required": false,
    13851663                            "description": "The title for the object.",
    1386                             "type": "object"
     1664                            "type": "object",
     1665                            "properties": {
     1666                                "raw": {
     1667                                    "description": "Title for the object, as it exists in the database.",
     1668                                    "type": "string",
     1669                                    "context": [
     1670                                        "edit"
     1671                                    ]
     1672                                },
     1673                                "rendered": {
     1674                                    "description": "HTML title for the object, transformed for display.",
     1675                                    "type": "string",
     1676                                    "context": [
     1677                                        "view",
     1678                                        "edit",
     1679                                        "embed"
     1680                                    ],
     1681                                    "readonly": true
     1682                                }
     1683                            },
     1684                            "required": false
    13871685                        },
    13881686                        "content": {
    1389                             "required": false,
    13901687                            "description": "The content for the object.",
    1391                             "type": "object"
     1688                            "type": "object",
     1689                            "properties": {
     1690                                "raw": {
     1691                                    "description": "Content for the object, as it exists in the database.",
     1692                                    "type": "string",
     1693                                    "context": [
     1694                                        "edit"
     1695                                    ]
     1696                                },
     1697                                "rendered": {
     1698                                    "description": "HTML content for the object, transformed for display.",
     1699                                    "type": "string",
     1700                                    "context": [
     1701                                        "view",
     1702                                        "edit"
     1703                                    ],
     1704                                    "readonly": true
     1705                                },
     1706                                "block_version": {
     1707                                    "description": "Version of the content block format used by the object.",
     1708                                    "type": "integer",
     1709                                    "context": [
     1710                                        "edit"
     1711                                    ],
     1712                                    "readonly": true
     1713                                },
     1714                                "protected": {
     1715                                    "description": "Whether the content is protected with a password.",
     1716                                    "type": "boolean",
     1717                                    "context": [
     1718                                        "view",
     1719                                        "edit",
     1720                                        "embed"
     1721                                    ],
     1722                                    "readonly": true
     1723                                }
     1724                            },
     1725                            "required": false
    13921726                        },
    13931727                        "author": {
    1394                             "required": false,
    13951728                            "description": "The ID for the author of the object.",
    1396                             "type": "integer"
     1729                            "type": "integer",
     1730                            "required": false
    13971731                        },
    13981732                        "excerpt": {
    1399                             "required": false,
    14001733                            "description": "The excerpt for the object.",
    1401                             "type": "object"
     1734                            "type": "object",
     1735                            "properties": {
     1736                                "raw": {
     1737                                    "description": "Excerpt for the object, as it exists in the database.",
     1738                                    "type": "string",
     1739                                    "context": [
     1740                                        "edit"
     1741                                    ]
     1742                                },
     1743                                "rendered": {
     1744                                    "description": "HTML excerpt for the object, transformed for display.",
     1745                                    "type": "string",
     1746                                    "context": [
     1747                                        "view",
     1748                                        "edit",
     1749                                        "embed"
     1750                                    ],
     1751                                    "readonly": true
     1752                                },
     1753                                "protected": {
     1754                                    "description": "Whether the excerpt is protected with a password.",
     1755                                    "type": "boolean",
     1756                                    "context": [
     1757                                        "view",
     1758                                        "edit",
     1759                                        "embed"
     1760                                    ],
     1761                                    "readonly": true
     1762                                }
     1763                            },
     1764                            "required": false
    14021765                        },
    14031766                        "featured_media": {
    1404                             "required": false,
    14051767                            "description": "The ID of the featured media for the object.",
    1406                             "type": "integer"
     1768                            "type": "integer",
     1769                            "required": false
    14071770                        },
    14081771                        "comment_status": {
    1409                             "required": false,
     1772                            "description": "Whether or not comments are open on the object.",
     1773                            "type": "string",
    14101774                            "enum": [
    14111775                                "open",
    14121776                                "closed"
    14131777                            ],
    1414                             "description": "Whether or not comments are open on the object.",
    1415                             "type": "string"
     1778                            "required": false
    14161779                        },
    14171780                        "ping_status": {
    1418                             "required": false,
     1781                            "description": "Whether or not the object can be pinged.",
     1782                            "type": "string",
    14191783                            "enum": [
    14201784                                "open",
    14211785                                "closed"
    14221786                            ],
    1423                             "description": "Whether or not the object can be pinged.",
    1424                             "type": "string"
     1787                            "required": false
    14251788                        },
    14261789                        "menu_order": {
    1427                             "required": false,
    14281790                            "description": "The order of the object in relation to other object of its type.",
    1429                             "type": "integer"
     1791                            "type": "integer",
     1792                            "required": false
    14301793                        },
    14311794                        "meta": {
    1432                             "required": false,
    14331795                            "description": "Meta fields.",
    1434                             "type": "object"
     1796                            "type": "object",
     1797                            "properties": [],
     1798                            "required": false
    14351799                        },
    14361800                        "template": {
    1437                             "required": false,
    14381801                            "description": "The theme file to use to display the object.",
    1439                             "type": "string"
     1802                            "type": "string",
     1803                            "required": false
    14401804                        }
    14411805                    }
     
    14621826                    "args": {
    14631827                        "id": {
    1464                             "required": false,
    14651828                            "description": "Unique identifier for the object.",
    1466                             "type": "integer"
     1829                            "type": "integer",
     1830                            "required": false
    14671831                        },
    14681832                        "context": {
    1469                             "required": false,
    1470                             "default": "view",
     1833                            "description": "Scope under which the request is made; determines fields present in response.",
     1834                            "type": "string",
    14711835                            "enum": [
    14721836                                "view",
     
    14741838                                "edit"
    14751839                            ],
    1476                             "description": "Scope under which the request is made; determines fields present in response.",
    1477                             "type": "string"
     1840                            "default": "view",
     1841                            "required": false
    14781842                        },
    14791843                        "password": {
    1480                             "required": false,
    14811844                            "description": "The password for the post if it is password protected.",
    1482                             "type": "string"
     1845                            "type": "string",
     1846                            "required": false
    14831847                        }
    14841848                    }
     
    14921856                    "args": {
    14931857                        "id": {
    1494                             "required": false,
    14951858                            "description": "Unique identifier for the object.",
    1496                             "type": "integer"
     1859                            "type": "integer",
     1860                            "required": false
    14971861                        },
    14981862                        "date": {
    1499                             "required": false,
    15001863                            "description": "The date the object was published, in the site's timezone.",
    15011864                            "type": [
    15021865                                "string",
    15031866                                "null"
    1504                             ]
     1867                            ],
     1868                            "format": "date-time",
     1869                            "required": false
    15051870                        },
    15061871                        "date_gmt": {
    1507                             "required": false,
    15081872                            "description": "The date the object was published, as GMT.",
    15091873                            "type": [
    15101874                                "string",
    15111875                                "null"
    1512                             ]
     1876                            ],
     1877                            "format": "date-time",
     1878                            "required": false
    15131879                        },
    15141880                        "slug": {
    1515                             "required": false,
    15161881                            "description": "An alphanumeric identifier for the object unique to its type.",
    1517                             "type": "string"
     1882                            "type": "string",
     1883                            "required": false
    15181884                        },
    15191885                        "status": {
    1520                             "required": false,
     1886                            "description": "A named status for the object.",
     1887                            "type": "string",
    15211888                            "enum": [
    15221889                                "publish",
     
    15261893                                "private"
    15271894                            ],
    1528                             "description": "A named status for the object.",
    1529                             "type": "string"
     1895                            "required": false
    15301896                        },
    15311897                        "password": {
    1532                             "required": false,
    15331898                            "description": "A password to protect access to the content and excerpt.",
    1534                             "type": "string"
     1899                            "type": "string",
     1900                            "required": false
    15351901                        },
    15361902                        "parent": {
    1537                             "required": false,
    15381903                            "description": "The ID for the parent of the object.",
    1539                             "type": "integer"
     1904                            "type": "integer",
     1905                            "required": false
    15401906                        },
    15411907                        "title": {
    1542                             "required": false,
    15431908                            "description": "The title for the object.",
    1544                             "type": "object"
     1909                            "type": "object",
     1910                            "properties": {
     1911                                "raw": {
     1912                                    "description": "Title for the object, as it exists in the database.",
     1913                                    "type": "string",
     1914                                    "context": [
     1915                                        "edit"
     1916                                    ]
     1917                                },
     1918                                "rendered": {
     1919                                    "description": "HTML title for the object, transformed for display.",
     1920                                    "type": "string",
     1921                                    "context": [
     1922                                        "view",
     1923                                        "edit",
     1924                                        "embed"
     1925                                    ],
     1926                                    "readonly": true
     1927                                }
     1928                            },
     1929                            "required": false
    15451930                        },
    15461931                        "content": {
    1547                             "required": false,
    15481932                            "description": "The content for the object.",
    1549                             "type": "object"
     1933                            "type": "object",
     1934                            "properties": {
     1935                                "raw": {
     1936                                    "description": "Content for the object, as it exists in the database.",
     1937                                    "type": "string",
     1938                                    "context": [
     1939                                        "edit"
     1940                                    ]
     1941                                },
     1942                                "rendered": {
     1943                                    "description": "HTML content for the object, transformed for display.",
     1944                                    "type": "string",
     1945                                    "context": [
     1946                                        "view",
     1947                                        "edit"
     1948                                    ],
     1949                                    "readonly": true
     1950                                },
     1951                                "block_version": {
     1952                                    "description": "Version of the content block format used by the object.",
     1953                                    "type": "integer",
     1954                                    "context": [
     1955                                        "edit"
     1956                                    ],
     1957                                    "readonly": true
     1958                                },
     1959                                "protected": {
     1960                                    "description": "Whether the content is protected with a password.",
     1961                                    "type": "boolean",
     1962                                    "context": [
     1963                                        "view",
     1964                                        "edit",
     1965                                        "embed"
     1966                                    ],
     1967                                    "readonly": true
     1968                                }
     1969                            },
     1970                            "required": false
    15501971                        },
    15511972                        "author": {
    1552                             "required": false,
    15531973                            "description": "The ID for the author of the object.",
    1554                             "type": "integer"
     1974                            "type": "integer",
     1975                            "required": false
    15551976                        },
    15561977                        "excerpt": {
    1557                             "required": false,
    15581978                            "description": "The excerpt for the object.",
    1559                             "type": "object"
     1979                            "type": "object",
     1980                            "properties": {
     1981                                "raw": {
     1982                                    "description": "Excerpt for the object, as it exists in the database.",
     1983                                    "type": "string",
     1984                                    "context": [
     1985                                        "edit"
     1986                                    ]
     1987                                },
     1988                                "rendered": {
     1989                                    "description": "HTML excerpt for the object, transformed for display.",
     1990                                    "type": "string",
     1991                                    "context": [
     1992                                        "view",
     1993                                        "edit",
     1994                                        "embed"
     1995                                    ],
     1996                                    "readonly": true
     1997                                },
     1998                                "protected": {
     1999                                    "description": "Whether the excerpt is protected with a password.",
     2000                                    "type": "boolean",
     2001                                    "context": [
     2002                                        "view",
     2003                                        "edit",
     2004                                        "embed"
     2005                                    ],
     2006                                    "readonly": true
     2007                                }
     2008                            },
     2009                            "required": false
    15602010                        },
    15612011                        "featured_media": {
    1562                             "required": false,
    15632012                            "description": "The ID of the featured media for the object.",
    1564                             "type": "integer"
     2013                            "type": "integer",
     2014                            "required": false
    15652015                        },
    15662016                        "comment_status": {
    1567                             "required": false,
     2017                            "description": "Whether or not comments are open on the object.",
     2018                            "type": "string",
    15682019                            "enum": [
    15692020                                "open",
    15702021                                "closed"
    15712022                            ],
    1572                             "description": "Whether or not comments are open on the object.",
    1573                             "type": "string"
     2023                            "required": false
    15742024                        },
    15752025                        "ping_status": {
    1576                             "required": false,
     2026                            "description": "Whether or not the object can be pinged.",
     2027                            "type": "string",
    15772028                            "enum": [
    15782029                                "open",
    15792030                                "closed"
    15802031                            ],
    1581                             "description": "Whether or not the object can be pinged.",
    1582                             "type": "string"
     2032                            "required": false
    15832033                        },
    15842034                        "menu_order": {
    1585                             "required": false,
    15862035                            "description": "The order of the object in relation to other object of its type.",
    1587                             "type": "integer"
     2036                            "type": "integer",
     2037                            "required": false
    15882038                        },
    15892039                        "meta": {
    1590                             "required": false,
    15912040                            "description": "Meta fields.",
    1592                             "type": "object"
     2041                            "type": "object",
     2042                            "properties": [],
     2043                            "required": false
    15932044                        },
    15942045                        "template": {
    1595                             "required": false,
    15962046                            "description": "The theme file to use to display the object.",
    1597                             "type": "string"
     2047                            "type": "string",
     2048                            "required": false
    15982049                        }
    15992050                    }
     
    16052056                    "args": {
    16062057                        "id": {
    1607                             "required": false,
    16082058                            "description": "Unique identifier for the object.",
    1609                             "type": "integer"
     2059                            "type": "integer",
     2060                            "required": false
    16102061                        },
    16112062                        "force": {
    1612                             "required": false,
     2063                            "type": "boolean",
    16132064                            "default": false,
    16142065                            "description": "Whether to bypass Trash and force deletion.",
    1615                             "type": "boolean"
     2066                            "required": false
    16162067                        }
    16172068                    }
     
    16312082                    "args": {
    16322083                        "parent": {
    1633                             "required": false,
    16342084                            "description": "The ID for the parent of the object.",
    1635                             "type": "integer"
     2085                            "type": "integer",
     2086                            "required": false
    16362087                        },
    16372088                        "context": {
    1638                             "required": false,
    1639                             "default": "view",
     2089                            "description": "Scope under which the request is made; determines fields present in response.",
     2090                            "type": "string",
    16402091                            "enum": [
    16412092                                "view",
     
    16432094                                "edit"
    16442095                            ],
    1645                             "description": "Scope under which the request is made; determines fields present in response.",
    1646                             "type": "string"
     2096                            "default": "view",
     2097                            "required": false
    16472098                        },
    16482099                        "page": {
    1649                             "required": false,
     2100                            "description": "Current page of the collection.",
     2101                            "type": "integer",
    16502102                            "default": 1,
    1651                             "description": "Current page of the collection.",
    1652                             "type": "integer"
     2103                            "minimum": 1,
     2104                            "required": false
    16532105                        },
    16542106                        "per_page": {
    1655                             "required": false,
    16562107                            "description": "Maximum number of items to be returned in result set.",
    1657                             "type": "integer"
     2108                            "type": "integer",
     2109                            "minimum": 1,
     2110                            "maximum": 100,
     2111                            "required": false
    16582112                        },
    16592113                        "search": {
    1660                             "required": false,
    16612114                            "description": "Limit results to those matching a string.",
    1662                             "type": "string"
     2115                            "type": "string",
     2116                            "required": false
    16632117                        },
    16642118                        "exclude": {
    1665                             "required": false,
    1666                             "default": [],
    16672119                            "description": "Ensure result set excludes specific IDs.",
    16682120                            "type": "array",
    16692121                            "items": {
    16702122                                "type": "integer"
    1671                             }
     2123                            },
     2124                            "default": [],
     2125                            "required": false
    16722126                        },
    16732127                        "include": {
    1674                             "required": false,
    1675                             "default": [],
    16762128                            "description": "Limit result set to specific IDs.",
    16772129                            "type": "array",
    16782130                            "items": {
    16792131                                "type": "integer"
    1680                             }
     2132                            },
     2133                            "default": [],
     2134                            "required": false
    16812135                        },
    16822136                        "offset": {
    1683                             "required": false,
    16842137                            "description": "Offset the result set by a specific number of items.",
    1685                             "type": "integer"
     2138                            "type": "integer",
     2139                            "required": false
    16862140                        },
    16872141                        "order": {
    1688                             "required": false,
     2142                            "description": "Order sort attribute ascending or descending.",
     2143                            "type": "string",
    16892144                            "default": "desc",
    16902145                            "enum": [
     
    16922147                                "desc"
    16932148                            ],
    1694                             "description": "Order sort attribute ascending or descending.",
    1695                             "type": "string"
     2149                            "required": false
    16962150                        },
    16972151                        "orderby": {
    1698                             "required": false,
     2152                            "description": "Sort collection by object attribute.",
     2153                            "type": "string",
    16992154                            "default": "date",
    17002155                            "enum": [
     
    17072162                                "title"
    17082163                            ],
    1709                             "description": "Sort collection by object attribute.",
    1710                             "type": "string"
     2164                            "required": false
    17112165                        }
    17122166                    }
     
    17272181                    "args": {
    17282182                        "parent": {
    1729                             "required": false,
    17302183                            "description": "The ID for the parent of the object.",
    1731                             "type": "integer"
     2184                            "type": "integer",
     2185                            "required": false
    17322186                        },
    17332187                        "id": {
    1734                             "required": false,
    17352188                            "description": "Unique identifier for the object.",
    1736                             "type": "integer"
     2189                            "type": "integer",
     2190                            "required": false
    17372191                        },
    17382192                        "context": {
    1739                             "required": false,
    1740                             "default": "view",
     2193                            "description": "Scope under which the request is made; determines fields present in response.",
     2194                            "type": "string",
    17412195                            "enum": [
    17422196                                "view",
     
    17442198                                "edit"
    17452199                            ],
    1746                             "description": "Scope under which the request is made; determines fields present in response.",
    1747                             "type": "string"
     2200                            "default": "view",
     2201                            "required": false
    17482202                        }
    17492203                    }
     
    17552209                    "args": {
    17562210                        "parent": {
    1757                             "required": false,
    17582211                            "description": "The ID for the parent of the object.",
    1759                             "type": "integer"
     2212                            "type": "integer",
     2213                            "required": false
    17602214                        },
    17612215                        "id": {
    1762                             "required": false,
    17632216                            "description": "Unique identifier for the object.",
    1764                             "type": "integer"
     2217                            "type": "integer",
     2218                            "required": false
    17652219                        },
    17662220                        "force": {
    1767                             "required": false,
     2221                            "type": "boolean",
    17682222                            "default": false,
    17692223                            "description": "Required to be true, as revisions do not support trashing.",
    1770                             "type": "boolean"
     2224                            "required": false
    17712225                        }
    17722226                    }
     
    17872241                    "args": {
    17882242                        "parent": {
    1789                             "required": false,
    17902243                            "description": "The ID for the parent of the object.",
    1791                             "type": "integer"
     2244                            "type": "integer",
     2245                            "required": false
    17922246                        },
    17932247                        "context": {
    1794                             "required": false,
    1795                             "default": "view",
     2248                            "description": "Scope under which the request is made; determines fields present in response.",
     2249                            "type": "string",
    17962250                            "enum": [
    17972251                                "view",
     
    17992253                                "edit"
    18002254                            ],
    1801                             "description": "Scope under which the request is made; determines fields present in response.",
    1802                             "type": "string"
     2255                            "default": "view",
     2256                            "required": false
    18032257                        }
    18042258                    }
     
    18102264                    "args": {
    18112265                        "parent": {
    1812                             "required": false,
    18132266                            "description": "The ID for the parent of the object.",
    1814                             "type": "integer"
     2267                            "type": "integer",
     2268                            "required": false
    18152269                        },
    18162270                        "date": {
    1817                             "required": false,
    18182271                            "description": "The date the object was published, in the site's timezone.",
    18192272                            "type": [
    18202273                                "string",
    18212274                                "null"
    1822                             ]
     2275                            ],
     2276                            "format": "date-time",
     2277                            "required": false
    18232278                        },
    18242279                        "date_gmt": {
    1825                             "required": false,
    18262280                            "description": "The date the object was published, as GMT.",
    18272281                            "type": [
    18282282                                "string",
    18292283                                "null"
    1830                             ]
     2284                            ],
     2285                            "format": "date-time",
     2286                            "required": false
    18312287                        },
    18322288                        "slug": {
    1833                             "required": false,
    18342289                            "description": "An alphanumeric identifier for the object unique to its type.",
    1835                             "type": "string"
     2290                            "type": "string",
     2291                            "required": false
    18362292                        },
    18372293                        "status": {
    1838                             "required": false,
     2294                            "description": "A named status for the object.",
     2295                            "type": "string",
    18392296                            "enum": [
    18402297                                "publish",
     
    18442301                                "private"
    18452302                            ],
    1846                             "description": "A named status for the object.",
    1847                   &nbs