Changeset 38832 for trunk/src/wp-includes/rest-api.php
- Timestamp:
- 10/20/2016 02:54:12 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r38806 r38832 72 72 73 73 /** 74 * Registers a new field on an existing WordPress object type. 75 * 76 * @since 4.7.0 77 * 78 * @global array $wp_rest_additional_fields Holds registered fields, organized 79 * by object type. 80 * 81 * @param string|array $object_type Object(s) the field is being registered 82 * to, "post"|"term"|"comment" etc. 83 * @param string $attribute The attribute name. 84 * @param array $args { 85 * Optional. An array of arguments used to handle the registered field. 86 * 87 * @type string|array|null $get_callback Optional. The callback function used to retrieve the field 88 * value. Default is 'null', the field will not be returned in 89 * the response. 90 * @type string|array|null $update_callback Optional. The callback function used to set and update the 91 * field value. Default is 'null', the value cannot be set or 92 * updated. 93 * @type string|array|null $schema Optional. The callback function used to create the schema for 94 * this field. Default is 'null', no schema entry will be returned. 95 * } 96 */ 97 function register_rest_field( $object_type, $attribute, $args = array() ) { 98 $defaults = array( 99 'get_callback' => null, 100 'update_callback' => null, 101 'schema' => null, 102 ); 103 104 $args = wp_parse_args( $args, $defaults ); 105 106 global $wp_rest_additional_fields; 107 108 $object_types = (array) $object_type; 109 110 foreach ( $object_types as $object_type ) { 111 $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; 112 } 113 } 114 115 /** 74 116 * Registers rewrite rules for the API. 75 117 * … … 123 165 124 166 add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 ); 167 } 168 169 /** 170 * Registers default REST API routes. 171 * 172 * @since 4.7.0 173 */ 174 function create_initial_rest_routes() { 175 foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { 176 $class = ! empty( $post_type->rest_controller_class ) ? $post_type->rest_controller_class : 'WP_REST_Posts_Controller'; 177 178 if ( ! class_exists( $class ) ) { 179 continue; 180 } 181 $controller = new $class( $post_type->name ); 182 if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) { 183 continue; 184 } 185 186 $controller->register_routes(); 187 188 if ( post_type_supports( $post_type->name, 'revisions' ) ) { 189 $revisions_controller = new WP_REST_Revisions_Controller( $post_type->name ); 190 $revisions_controller->register_routes(); 191 } 192 } 193 194 // Post types. 195 $controller = new WP_REST_Post_Types_Controller; 196 $controller->register_routes(); 197 198 // Post statuses. 199 $controller = new WP_REST_Post_Statuses_Controller; 200 $controller->register_routes(); 201 202 // Taxonomies. 203 $controller = new WP_REST_Taxonomies_Controller; 204 $controller->register_routes(); 205 206 // Terms. 207 foreach ( get_taxonomies( array( 'show_in_rest' => true ), 'object' ) as $taxonomy ) { 208 $class = ! empty( $taxonomy->rest_controller_class ) ? $taxonomy->rest_controller_class : 'WP_REST_Terms_Controller'; 209 210 if ( ! class_exists( $class ) ) { 211 continue; 212 } 213 $controller = new $class( $taxonomy->name ); 214 if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) { 215 continue; 216 } 217 218 $controller->register_routes(); 219 } 220 221 // Users. 222 $controller = new WP_REST_Users_Controller; 223 $controller->register_routes(); 224 225 // Comments. 226 $controller = new WP_REST_Comments_Controller; 227 $controller->register_routes(); 228 229 // Settings. 230 $controller = new WP_REST_Settings_Controller; 231 $controller->register_routes(); 125 232 } 126 233 … … 684 791 return array( $local, $utc ); 685 792 } 793 794 /** 795 * Returns a contextual HTTP error code for authorization failure. 796 * 797 * @since 4.7.0 798 * 799 * @return integer 401 if the user is not logged in, 403 if the user is logged in. 800 */ 801 function rest_authorization_required_code() { 802 return is_user_logged_in() ? 403 : 401; 803 } 804 805 /** 806 * Validate a request argument based on details registered to the route. 807 * 808 * @since 4.7.0 809 * 810 * @param mixed $value 811 * @param WP_REST_Request $request 812 * @param string $param 813 * @return WP_Error|boolean 814 */ 815 function rest_validate_request_arg( $value, $request, $param ) { 816 $attributes = $request->get_attributes(); 817 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { 818 return true; 819 } 820 $args = $attributes['args'][ $param ]; 821 822 if ( ! empty( $args['enum'] ) ) { 823 if ( ! in_array( $value, $args['enum'], true ) ) { 824 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: list of valid values */ __( '%1$s is not one of %2$s.' ), $param, implode( ', ', $args['enum'] ) ) ); 825 } 826 } 827 828 if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) { 829 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $param, 'integer' ) ); 830 } 831 832 if ( 'boolean' === $args['type'] && ! rest_is_boolean( $value ) ) { 833 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $value, 'boolean' ) ); 834 } 835 836 if ( 'string' === $args['type'] && ! is_string( $value ) ) { 837 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $param, 'string' ) ); 838 } 839 840 if ( isset( $args['format'] ) ) { 841 switch ( $args['format'] ) { 842 case 'date-time' : 843 if ( ! rest_parse_date( $value ) ) { 844 return new WP_Error( 'rest_invalid_date', __( 'The date you provided is invalid.' ) ); 845 } 846 break; 847 848 case 'email' : 849 if ( ! is_email( $value ) ) { 850 return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) ); 851 } 852 break; 853 case 'ipv4' : 854 if ( ! rest_is_ip_address( $value ) ) { 855 return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IP address.' ), $value ) ); 856 } 857 break; 858 } 859 } 860 861 if ( in_array( $args['type'], array( 'numeric', 'integer' ), true ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) { 862 if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { 863 if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { 864 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than %2$d (exclusive)' ), $param, $args['minimum'] ) ); 865 } elseif ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { 866 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be greater than %2$d (inclusive)' ), $param, $args['minimum'] ) ); 867 } 868 } elseif ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { 869 if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { 870 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than %2$d (exclusive)' ), $param, $args['maximum'] ) ); 871 } elseif ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { 872 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must be less than %2$d (inclusive)' ), $param, $args['maximum'] ) ); 873 } 874 } elseif ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) { 875 if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { 876 if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { 877 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: minimum number, 3: maximum number */ __( '%1$s must be between %2$d (exclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); 878 } 879 } elseif ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { 880 if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { 881 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: minimum number, 3: maximum number */ __( '%1$s must be between %2$d (inclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); 882 } 883 } elseif ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { 884 if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { 885 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: minimum number, 3: maximum number */ __( '%1$s must be between %2$d (exclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); 886 } 887 } elseif ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { 888 if ( $value > $args['maximum'] || $value < $args['minimum'] ) { 889 return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: minimum number, 3: maximum number */ __( '%1$s must be between %2$d (inclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); 890 } 891 } 892 } 893 } 894 895 return true; 896 } 897 898 /** 899 * Sanitize a request argument based on details registered to the route. 900 * 901 * @since 4.7.0 902 * 903 * @param mixed $value 904 * @param WP_REST_Request $request 905 * @param string $param 906 * @return mixed 907 */ 908 function rest_sanitize_request_arg( $value, $request, $param ) { 909 $attributes = $request->get_attributes(); 910 if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { 911 return $value; 912 } 913 $args = $attributes['args'][ $param ]; 914 915 if ( 'integer' === $args['type'] ) { 916 return (int) $value; 917 } 918 919 if ( 'boolean' === $args['type'] ) { 920 return rest_sanitize_boolean( $value ); 921 } 922 923 if ( isset( $args['format'] ) ) { 924 switch ( $args['format'] ) { 925 case 'date-time' : 926 return sanitize_text_field( $value ); 927 928 case 'email' : 929 /* 930 * sanitize_email() validates, which would be unexpected 931 */ 932 return sanitize_text_field( $value ); 933 934 case 'uri' : 935 return esc_url_raw( $value ); 936 937 case 'ipv4' : 938 return sanitize_text_field( $value ); 939 } 940 } 941 942 return $value; 943 } 944 945 /** 946 * Parse a request argument based on details registered to the route. 947 * 948 * Runs a validation check and sanitizes the value, primarily to be used via 949 * the `sanitize_callback` arguments in the endpoint args registration. 950 * 951 * @since 4.7.0 952 * 953 * @param mixed $value 954 * @param WP_REST_Request $request 955 * @param string $param 956 * @return mixed 957 */ 958 function rest_parse_request_arg( $value, $request, $param ) { 959 $is_valid = rest_validate_request_arg( $value, $request, $param ); 960 961 if ( is_wp_error( $is_valid ) ) { 962 return $is_valid; 963 } 964 965 $value = rest_sanitize_request_arg( $value, $request, $param ); 966 967 return $value; 968 } 969 970 /** 971 * Determines if a IPv4 address is valid. 972 * 973 * Does not handle IPv6 addresses. 974 * 975 * @since 4.7.0 976 * 977 * @param string $ipv4 IP 32-bit address. 978 * @return string|false The valid IPv4 address, otherwise false. 979 */ 980 function rest_is_ip_address( $ipv4 ) { 981 $pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/'; 982 983 if ( ! preg_match( $pattern, $ipv4 ) ) { 984 return false; 985 } 986 987 return $ipv4; 988 } 989 990 /** 991 * Changes a boolean-like value into the proper boolean value. 992 * 993 * @since 4.7.0 994 * 995 * @param bool|string|int $value The value being evaluated. 996 * @return boolean Returns the proper associated boolean value. 997 */ 998 function rest_sanitize_boolean( $value ) { 999 // String values are translated to `true`; make sure 'false' is false. 1000 if ( is_string( $value ) ) { 1001 $value = strtolower( $value ); 1002 if ( in_array( $value, array( 'false', '0' ), true ) ) { 1003 $value = false; 1004 } 1005 } 1006 1007 // Everything else will map nicely to boolean. 1008 return (boolean) $value; 1009 } 1010 1011 /** 1012 * Determines if a given value is boolean-like. 1013 * 1014 * @since 4.7.0 1015 * 1016 * @param bool|string $maybe_bool The value being evaluated. 1017 * @return boolean True if a boolean, otherwise false. 1018 */ 1019 function rest_is_boolean( $maybe_bool ) { 1020 if ( is_bool( $maybe_bool ) ) { 1021 return true; 1022 } 1023 1024 if ( is_string( $maybe_bool ) ) { 1025 $maybe_bool = strtolower( $maybe_bool ); 1026 1027 $valid_boolean_values = array( 1028 'false', 1029 'true', 1030 '0', 1031 '1', 1032 ); 1033 1034 return in_array( $maybe_bool, $valid_boolean_values, true ); 1035 } 1036 1037 if ( is_int( $maybe_bool ) ) { 1038 return in_array( $maybe_bool, array( 0, 1 ), true ); 1039 } 1040 1041 return false; 1042 } 1043 1044 /** 1045 * Retrieves the avatar urls in various sizes based on a given email address. 1046 * 1047 * @since 4.7.0 1048 * 1049 * @see get_avatar_url() 1050 * 1051 * @param string $email Email address. 1052 * @return array $urls Gravatar url for each size. 1053 */ 1054 function rest_get_avatar_urls( $email ) { 1055 $avatar_sizes = rest_get_avatar_sizes(); 1056 1057 $urls = array(); 1058 foreach ( $avatar_sizes as $size ) { 1059 $urls[ $size ] = get_avatar_url( $email, array( 'size' => $size ) ); 1060 } 1061 1062 return $urls; 1063 } 1064 1065 /** 1066 * Retrieves the pixel sizes for avatars. 1067 * 1068 * @since 4.7.0 1069 * 1070 * @return array List of pixel sizes for avatars. Default `[ 24, 48, 96 ]`. 1071 */ 1072 function rest_get_avatar_sizes() { 1073 /** 1074 * Filter the REST avatar sizes. 1075 * 1076 * Use this filter to adjust the array of sizes returned by the 1077 * `rest_get_avatar_sizes` function. 1078 * 1079 * @since 4.4.0 1080 * 1081 * @param array $sizes An array of int values that are the pixel sizes for avatars. 1082 * Default `[ 24, 48, 96 ]`. 1083 */ 1084 return apply_filters( 'rest_avatar_sizes', array( 24, 48, 96 ) ); 1085 }
Note: See TracChangeset
for help on using the changeset viewer.