Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}

Expand Down
23 changes: 23 additions & 0 deletions tests/phpunit/tests/rest-api/rest-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
}
13 changes: 13 additions & 0 deletions tests/phpunit/tests/rest-api/rest-users-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down