diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php index 076d06c0ce04d..1b9c427946003 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php @@ -505,6 +505,35 @@ protected function get_object_type() { return $schema['title']; } + /** + * Gets an array of fields to be included on the response. + * + * Included fields are based on item schema and `_fields=` request argument. + * + * @since 4.9.6 + * + * @param WP_REST_Request $request Full details about the request. + * @return array Fields to be included in the response. + */ + public function get_fields_for_response( $request ) { + $schema = $this->get_item_schema(); + $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array(); + if ( ! isset( $request['_fields'] ) ) { + return $fields; + } + $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] ); + if ( 0 === count( $requested_fields ) ) { + return $fields; + } + // Trim off outside whitespace from the comma delimited list. + $requested_fields = array_map( 'trim', $requested_fields ); + // Always persist 'id', because it can be needed for add_additional_fields_to_object(). + if ( in_array( 'id', $fields, true ) ) { + $requested_fields[] = 'id'; + } + return array_intersect( $fields, $requested_fields ); + } + /** * Retrieves an array of endpoint arguments from the item schema for the controller. * diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php index 78062617fdf44..c452b304727d8 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php @@ -846,78 +846,78 @@ function delete_current_item( $request ) { public function prepare_item_for_response( $user, $request ) { $data = array(); - $schema = $this->get_item_schema(); + $fields = $this->get_fields_for_response( $request ); - if ( ! empty( $schema['properties']['id'] ) ) { + if ( in_array( 'id', $fields, true ) ) { $data['id'] = $user->ID; } - if ( ! empty( $schema['properties']['username'] ) ) { + if ( in_array( 'username', $fields, true ) ) { $data['username'] = $user->user_login; } - if ( ! empty( $schema['properties']['name'] ) ) { + if ( in_array( 'name', $fields, true ) ) { $data['name'] = $user->display_name; } - if ( ! empty( $schema['properties']['first_name'] ) ) { + if ( in_array( 'first_name', $fields, true ) ) { $data['first_name'] = $user->first_name; } - if ( ! empty( $schema['properties']['last_name'] ) ) { + if ( in_array( 'last_name', $fields, true ) ) { $data['last_name'] = $user->last_name; } - if ( ! empty( $schema['properties']['email'] ) ) { + if ( in_array( 'email', $fields, true ) ) { $data['email'] = $user->user_email; } - if ( ! empty( $schema['properties']['url'] ) ) { + if ( in_array( 'url', $fields, true ) ) { $data['url'] = $user->user_url; } - if ( ! empty( $schema['properties']['description'] ) ) { + if ( in_array( 'description', $fields, true ) ) { $data['description'] = $user->description; } - if ( ! empty( $schema['properties']['link'] ) ) { + if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename ); } - if ( ! empty( $schema['properties']['locale'] ) ) { + if ( in_array( 'locale', $fields, true ) ) { $data['locale'] = get_user_locale( $user ); } - if ( ! empty( $schema['properties']['nickname'] ) ) { + if ( in_array( 'nickname', $fields, true ) ) { $data['nickname'] = $user->nickname; } - if ( ! empty( $schema['properties']['slug'] ) ) { + if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $user->user_nicename; } - if ( ! empty( $schema['properties']['roles'] ) ) { + if ( in_array( 'roles', $fields, true ) ) { // Defensively call array_values() to ensure an array is returned. $data['roles'] = array_values( $user->roles ); } - if ( ! empty( $schema['properties']['registered_date'] ) ) { + if ( in_array( 'registered_date', $fields, true ) ) { $data['registered_date'] = date( 'c', strtotime( $user->user_registered ) ); } - if ( ! empty( $schema['properties']['capabilities'] ) ) { + if ( in_array( 'capabilities', $fields, true ) ) { $data['capabilities'] = (object) $user->allcaps; } - if ( ! empty( $schema['properties']['extra_capabilities'] ) ) { + if ( in_array( 'extra_capabilities', $fields, true ) ) { $data['extra_capabilities'] = (object) $user->caps; } - if ( ! empty( $schema['properties']['avatar_urls'] ) ) { + if ( in_array( 'avatar_urls', $fields, true ) ) { $data['avatar_urls'] = rest_get_avatar_urls( $user->user_email ); } - if ( ! empty( $schema['properties']['meta'] ) ) { + if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $user->ID, $request ); } diff --git a/tests/phpunit/tests/rest-api/rest-controller.php b/tests/phpunit/tests/rest-api/rest-controller.php index 4d73d0fa389de..e4dc15fede7bf 100644 --- a/tests/phpunit/tests/rest-api/rest-controller.php +++ b/tests/phpunit/tests/rest-api/rest-controller.php @@ -200,4 +200,27 @@ public function test_get_endpoint_args_for_item_schema_default_value() { $this->assertEquals( 'a', $args['somedefault']['default'] ); } + + public function test_get_fields_for_response() { + $controller = new WP_REST_Test_Controller(); + $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' ); + $fields = $controller->get_fields_for_response( $request ); + $this->assertEquals( array( + 'somestring', + 'someinteger', + 'someboolean', + 'someurl', + 'somedate', + 'someemail', + 'someenum', + 'someargoptions', + 'somedefault', + ), $fields ); + $request->set_param( '_fields', 'somestring,someinteger' ); + $fields = $controller->get_fields_for_response( $request ); + $this->assertEquals( array( + 'somestring', + 'someinteger', + ), $fields ); + } } diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php index 77b4474cf7171..0d3960b1c0e4f 100644 --- a/tests/phpunit/tests/rest-api/rest-users-controller.php +++ b/tests/phpunit/tests/rest-api/rest-users-controller.php @@ -849,6 +849,19 @@ public function test_prepare_item() { $this->check_get_user_response( $data, 'edit' ); } + public function test_prepare_item_limit_fields() { + wp_set_current_user( self::$user ); + $request = new WP_REST_Request; + $request->set_param( 'context', 'edit' ); + $request->set_param( '_fields', 'id,name' ); + $user = get_user_by( 'id', get_current_user_id() ); + $response = $this->endpoint->prepare_item_for_response( $user, $request ); + $this->assertEquals( array( + 'id', + 'name', + ), array_keys( $response->get_data() ) ); + } + public function test_get_user_avatar_urls() { wp_set_current_user( self::$user );