Make WordPress Core

Changeset 43087


Ignore:
Timestamp:
05/02/2018 01:24:30 AM (8 years ago)
Author:
pento
Message:

REST API: Filter responses based on the _fields parameter, before data is processed.

Historically, the REST API would generate the entire response object, including running expensive filters, then it would apply the _fields parameter, discarding the fields that weren't specificed.

This change causes _fields to be applied earlier, so that only requested fields are processed.

Props danielbachhuber.
See #43874.

Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    r42449 r43087  
    285285        public function prepare_item_for_response( $post, $request ) {
    286286                $response = parent::prepare_item_for_response( $post, $request );
     287                $fields   = $this->get_fields_for_response( $request );
    287288                $data     = $response->get_data();
    288289
    289                 $data['description'] = array(
    290                         'raw'      => $post->post_content,
     290                if ( in_array( 'description', $fields, true ) ) {
     291                        $data['description'] = array(
     292                                'raw'      => $post->post_content,
     293                                /** This filter is documented in wp-includes/post-template.php */
     294                                'rendered' => apply_filters( 'the_content', $post->post_content ),
     295                        );
     296                }
     297
     298                if ( in_array( 'caption', $fields, true ) ) {
    291299                        /** This filter is documented in wp-includes/post-template.php */
    292                         'rendered' => apply_filters( 'the_content', $post->post_content ),
    293                 );
    294 
    295                 /** This filter is documented in wp-includes/post-template.php */
    296                 $caption         = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) );
    297                 $data['caption'] = array(
    298                         'raw'      => $post->post_excerpt,
    299                         'rendered' => $caption,
    300                 );
    301 
    302                 $data['alt_text']      = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
    303                 $data['media_type']    = wp_attachment_is_image( $post->ID ) ? 'image' : 'file';
    304                 $data['mime_type']     = $post->post_mime_type;
    305                 $data['media_details'] = wp_get_attachment_metadata( $post->ID );
    306                 $data['post']          = ! empty( $post->post_parent ) ? (int) $post->post_parent : null;
    307                 $data['source_url']    = wp_get_attachment_url( $post->ID );
    308 
    309                 // Ensure empty details is an empty object.
    310                 if ( empty( $data['media_details'] ) ) {
    311                         $data['media_details'] = new stdClass;
    312                 } elseif ( ! empty( $data['media_details']['sizes'] ) ) {
    313 
    314                         foreach ( $data['media_details']['sizes'] as $size => &$size_data ) {
    315 
    316                                 if ( isset( $size_data['mime-type'] ) ) {
    317                                         $size_data['mime_type'] = $size_data['mime-type'];
    318                                         unset( $size_data['mime-type'] );
     300                        $caption         = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) );
     301                        $data['caption'] = array(
     302                                'raw'      => $post->post_excerpt,
     303                                'rendered' => $caption,
     304                        );
     305                }
     306
     307                if ( in_array( 'alt_text', $fields, true ) ) {
     308                        $data['alt_text'] = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
     309                }
     310
     311                if ( in_array( 'media_type', $fields, true ) ) {
     312                        $data['media_type'] = wp_attachment_is_image( $post->ID ) ? 'image' : 'file';
     313                }
     314
     315                if ( in_array( 'mime_type', $fields, true ) ) {
     316                        $data['mime_type'] = $post->post_mime_type;
     317                }
     318
     319                if ( in_array( 'media_details', $fields, true ) ) {
     320                        $data['media_details'] = wp_get_attachment_metadata( $post->ID );
     321
     322                        // Ensure empty details is an empty object.
     323                        if ( empty( $data['media_details'] ) ) {
     324                                $data['media_details'] = new stdClass;
     325                        } elseif ( ! empty( $data['media_details']['sizes'] ) ) {
     326
     327                                foreach ( $data['media_details']['sizes'] as $size => &$size_data ) {
     328
     329                                        if ( isset( $size_data['mime-type'] ) ) {
     330                                                $size_data['mime_type'] = $size_data['mime-type'];
     331                                                unset( $size_data['mime-type'] );
     332                                        }
     333
     334                                        // Use the same method image_downsize() does.
     335                                        $image_src = wp_get_attachment_image_src( $post->ID, $size );
     336                                        if ( ! $image_src ) {
     337                                                continue;
     338                                        }
     339
     340                                        $size_data['source_url'] = $image_src[0];
    319341                                }
    320342
    321                                 // Use the same method image_downsize() does.
    322                                 $image_src = wp_get_attachment_image_src( $post->ID, $size );
    323                                 if ( ! $image_src ) {
    324                                         continue;
     343                                $full_src = wp_get_attachment_image_src( $post->ID, 'full' );
     344
     345                                if ( ! empty( $full_src ) ) {
     346                                        $data['media_details']['sizes']['full'] = array(
     347                                                'file'       => wp_basename( $full_src[0] ),
     348                                                'width'      => $full_src[1],
     349                                                'height'     => $full_src[2],
     350                                                'mime_type'  => $post->post_mime_type,
     351                                                'source_url' => $full_src[0],
     352                                        );
    325353                                }
    326 
    327                                 $size_data['source_url'] = $image_src[0];
    328                         }
    329 
    330                         $full_src = wp_get_attachment_image_src( $post->ID, 'full' );
    331 
    332                         if ( ! empty( $full_src ) ) {
    333                                 $data['media_details']['sizes']['full'] = array(
    334                                         'file'       => wp_basename( $full_src[0] ),
    335                                         'width'      => $full_src[1],
    336                                         'height'     => $full_src[2],
    337                                         'mime_type'  => $post->post_mime_type,
    338                                         'source_url' => $full_src[0],
    339                                 );
    340                         }
    341                 } else {
    342                         $data['media_details']['sizes'] = new stdClass;
     354                        } else {
     355                                $data['media_details']['sizes'] = new stdClass;
     356                        }
     357                }
     358
     359                if ( in_array( 'post', $fields, true ) ) {
     360                        $data['post'] = ! empty( $post->post_parent ) ? (int) $post->post_parent : null;
     361                }
     362
     363                if ( in_array( 'source_url', $fields, true ) ) {
     364                        $data['source_url'] = wp_get_attachment_url( $post->ID );
    343365                }
    344366
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php

    r42678 r43087  
    863863         */
    864864        public function prepare_item_for_response( $comment, $request ) {
    865                 $data = array(
    866                         'id'                => (int) $comment->comment_ID,
    867                         'post'              => (int) $comment->comment_post_ID,
    868                         'parent'            => (int) $comment->comment_parent,
    869                         'author'            => (int) $comment->user_id,
    870                         'author_name'       => $comment->comment_author,
    871                         'author_email'      => $comment->comment_author_email,
    872                         'author_url'        => $comment->comment_author_url,
    873                         'author_ip'         => $comment->comment_author_IP,
    874                         'author_user_agent' => $comment->comment_agent,
    875                         'date'              => mysql_to_rfc3339( $comment->comment_date ),
    876                         'date_gmt'          => mysql_to_rfc3339( $comment->comment_date_gmt ),
    877                         'content'           => array(
     865
     866                $fields = $this->get_fields_for_response( $request );
     867                $data   = array();
     868
     869                if ( in_array( 'id', $fields, true ) ) {
     870                        $data['id'] = (int) $comment->comment_ID;
     871                }
     872
     873                if ( in_array( 'post', $fields, true ) ) {
     874                        $data['post'] = (int) $comment->comment_post_ID;
     875                }
     876
     877                if ( in_array( 'parent', $fields, true ) ) {
     878                        $data['parent'] = (int) $comment->comment_parent;
     879                }
     880
     881                if ( in_array( 'author', $fields, true ) ) {
     882                        $data['author'] = (int) $comment->user_id;
     883                }
     884
     885                if ( in_array( 'author_name', $fields, true ) ) {
     886                        $data['author_name'] = $comment->comment_author;
     887                }
     888
     889                if ( in_array( 'author_email', $fields, true ) ) {
     890                        $data['author_email'] = $comment->comment_author_email;
     891                }
     892
     893                if ( in_array( 'author_url', $fields, true ) ) {
     894                        $data['author_url'] = $comment->comment_author_url;
     895                }
     896
     897                if ( in_array( 'author_ip', $fields, true ) ) {
     898                        $data['author_ip'] = $comment->comment_author_IP;
     899                }
     900
     901                if ( in_array( 'author_user_agent', $fields, true ) ) {
     902                        $data['author_user_agent'] = $comment->comment_agent;
     903                }
     904
     905                if ( in_array( 'date', $fields, true ) ) {
     906                        $data['date'] = mysql_to_rfc3339( $comment->comment_date );
     907                }
     908
     909                if ( in_array( 'date_gmt', $fields, true ) ) {
     910                        $data['date_gmt'] = mysql_to_rfc3339( $comment->comment_date_gmt );
     911                }
     912
     913                if ( in_array( 'content', $fields, true ) ) {
     914                        $data['content'] = array(
    878915                                /** This filter is documented in wp-includes/comment-template.php */
    879916                                'rendered' => apply_filters( 'comment_text', $comment->comment_content, $comment ),
    880917                                'raw'      => $comment->comment_content,
    881                         ),
    882                         'link'              => get_comment_link( $comment ),
    883                         'status'            => $this->prepare_status_response( $comment->comment_approved ),
    884                         'type'              => get_comment_type( $comment->comment_ID ),
    885                 );
    886 
    887                 $schema = $this->get_item_schema();
    888 
    889                 if ( ! empty( $schema['properties']['author_avatar_urls'] ) ) {
     918                        );
     919                }
     920
     921                if ( in_array( 'link', $fields, true ) ) {
     922                        $data['link'] = get_comment_link( $comment );
     923                }
     924
     925                if ( in_array( 'status', $fields, true ) ) {
     926                        $data['status'] = $this->prepare_status_response( $comment->comment_approved );
     927                }
     928
     929                if ( in_array( 'type', $fields, true ) ) {
     930                        $data['type'] = get_comment_type( $comment->comment_ID );
     931                }
     932
     933                if ( in_array( 'author_avatar_urls', $fields, true ) ) {
    890934                        $data['author_avatar_urls'] = rest_get_avatar_urls( $comment->comment_author_email );
    891935                }
    892936
    893                 if ( ! empty( $schema['properties']['meta'] ) ) {
     937                if ( in_array( 'meta', $fields, true ) ) {
    894938                        $data['meta'] = $this->meta->get_value( $comment->comment_ID, $request );
    895939                }
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php

    r42343 r43087  
    507507
    508508        /**
     509         * Gets an array of fields to be included on the response.
     510         *
     511         * Included fields are based on item schema and `_fields=` request argument.
     512         *
     513         * @since 4.9.6
     514         *
     515         * @param WP_REST_Request $request Full details about the request.
     516         * @return array Fields to be included in the response.
     517         */
     518        public function get_fields_for_response( $request ) {
     519                $schema = $this->get_item_schema();
     520                $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array();
     521                if ( ! isset( $request['_fields'] ) ) {
     522                        return $fields;
     523                }
     524                $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] );
     525                if ( 0 === count( $requested_fields ) ) {
     526                        return $fields;
     527                }
     528                // Trim off outside whitespace from the comma delimited list.
     529                $requested_fields = array_map( 'trim', $requested_fields );
     530                // Always persist 'id', because it can be needed for add_additional_fields_to_object().
     531                if ( in_array( 'id', $fields, true ) ) {
     532                        $requested_fields[] = 'id';
     533                }
     534                return array_intersect( $fields, $requested_fields );
     535        }
     536
     537        /**
    509538         * Retrieves an array of endpoint arguments from the item schema for the controller.
    510539         *
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-post-statuses-controller.php

    r42356 r43087  
    200200        public function prepare_item_for_response( $status, $request ) {
    201201
    202                 $data = array(
    203                         'name'         => $status->label,
    204                         'private'      => (bool) $status->private,
    205                         'protected'    => (bool) $status->protected,
    206                         'public'       => (bool) $status->public,
    207                         'queryable'    => (bool) $status->publicly_queryable,
    208                         'show_in_list' => (bool) $status->show_in_admin_all_list,
    209                         'slug'         => $status->name,
    210                 );
     202                $fields = $this->get_fields_for_response( $request );
     203                $data   = array();
     204
     205                if ( in_array( 'name', $fields, true ) ) {
     206                        $data['name'] = $status->label;
     207                }
     208
     209                if ( in_array( 'private', $fields, true ) ) {
     210                        $data['private'] = (bool) $status->private;
     211                }
     212
     213                if ( in_array( 'protected', $fields, true ) ) {
     214                        $data['protected'] = (bool) $status->protected;
     215                }
     216
     217                if ( in_array( 'public', $fields, true ) ) {
     218                        $data['public'] = (bool) $status->public;
     219                }
     220
     221                if ( in_array( 'queryable', $fields, true ) ) {
     222                        $data['queryable'] = (bool) $status->publicly_queryable;
     223                }
     224
     225                if ( in_array( 'show_in_list', $fields, true ) ) {
     226                        $data['show_in_list'] = (bool) $status->show_in_admin_all_list;
     227                }
     228
     229                if ( in_array( 'slug', $fields, true ) ) {
     230                        $data['slug'] = $status->name;
     231                }
    211232
    212233                $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php

    r43007 r43087  
    156156                $supports   = get_all_post_type_supports( $post_type->name );
    157157
    158                 $data    = array(
    159                         'capabilities' => $post_type->cap,
    160                         'description'  => $post_type->description,
    161                         'hierarchical' => $post_type->hierarchical,
    162                         'viewable'     => is_post_type_viewable( $post_type ),
    163                         'labels'       => $post_type->labels,
    164                         'name'         => $post_type->label,
    165                         'slug'         => $post_type->name,
    166                         'supports'     => $supports,
    167                         'taxonomies'   => array_values( $taxonomies ),
    168                         'rest_base'    => $base,
    169                 );
     158                $fields = $this->get_fields_for_response( $request );
     159                $data   = array();
     160
     161                if ( in_array( 'capabilities', $fields, true ) ) {
     162                        $data['capabilities'] = $post_type->cap;
     163                }
     164
     165                if ( in_array( 'description', $fields, true ) ) {
     166                        $data['description'] = $post_type->description;
     167                }
     168
     169                if ( in_array( 'hierarchical', $fields, true ) ) {
     170                        $data['hierarchical'] = $post_type->hierarchical;
     171                }
     172
     173                if ( in_array( 'viewable', $fields, true ) ) {
     174                        $data['viewable'] = is_post_type_viewable( $post_type );
     175                }
     176
     177                if ( in_array( 'labels', $fields, true ) ) {
     178                        $data['labels'] = $post_type->labels;
     179                }
     180
     181                if ( in_array( 'name', $fields, true ) ) {
     182                        $data['name'] = $post_type->label;
     183                }
     184
     185                if ( in_array( 'slug', $fields, true ) ) {
     186                        $data['slug'] = $post_type->name;
     187                }
     188
     189                if ( in_array( 'supports', $fields, true ) ) {
     190                        $data['supports'] = $supports;
     191                }
     192
     193                if ( in_array( 'taxonomies', $fields, true ) ) {
     194                        $data['taxonomies'] = array_values( $taxonomies );
     195                }
     196
     197                if ( in_array( 'rest_base', $fields, true ) ) {
     198                        $data['rest_base'] = $base;
     199                }
     200
    170201                $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
    171202                $data    = $this->add_additional_fields_to_object( $data, $request );
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r42678 r43087  
    14091409                setup_postdata( $post );
    14101410
    1411                 $schema = $this->get_item_schema();
     1411                $fields = $this->get_fields_for_response( $request );
    14121412
    14131413                // Base fields for every post.
    14141414                $data = array();
    14151415
    1416                 if ( ! empty( $schema['properties']['id'] ) ) {
     1416                if ( in_array( 'id', $fields, true ) ) {
    14171417                        $data['id'] = $post->ID;
    14181418                }
    14191419
    1420                 if ( ! empty( $schema['properties']['date'] ) ) {
     1420                if ( in_array( 'date', $fields, true ) ) {
    14211421                        $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date );
    14221422                }
    14231423
    1424                 if ( ! empty( $schema['properties']['date_gmt'] ) ) {
     1424                if ( in_array( 'date_gmt', $fields, true ) ) {
    14251425                        // For drafts, `post_date_gmt` may not be set, indicating that the
    14261426                        // date of the draft should be updated each time it is saved (see
     
    14351435                }
    14361436
    1437                 if ( ! empty( $schema['properties']['guid'] ) ) {
     1437                if ( in_array( 'guid', $fields, true ) ) {
    14381438                        $data['guid'] = array(
    14391439                                /** This filter is documented in wp-includes/post-template.php */
     
    14431443                }
    14441444
    1445                 if ( ! empty( $schema['properties']['modified'] ) ) {
     1445                if ( in_array( 'modified', $fields, true ) ) {
    14461446                        $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified );
    14471447                }
    14481448
    1449                 if ( ! empty( $schema['properties']['modified_gmt'] ) ) {
     1449                if ( in_array( 'modified_gmt', $fields, true ) ) {
    14501450                        // For drafts, `post_modified_gmt` may not be set (see
    14511451                        // `post_date_gmt` comments above).  In this case, shim the value
     
    14601460                }
    14611461
    1462                 if ( ! empty( $schema['properties']['password'] ) ) {
     1462                if ( in_array( 'password', $fields, true ) ) {
    14631463                        $data['password'] = $post->post_password;
    14641464                }
    14651465
    1466                 if ( ! empty( $schema['properties']['slug'] ) ) {
     1466                if ( in_array( 'slug', $fields, true ) ) {
    14671467                        $data['slug'] = $post->post_name;
    14681468                }
    14691469
    1470                 if ( ! empty( $schema['properties']['status'] ) ) {
     1470                if ( in_array( 'status', $fields, true ) ) {
    14711471                        $data['status'] = $post->post_status;
    14721472                }
    14731473
    1474                 if ( ! empty( $schema['properties']['type'] ) ) {
     1474                if ( in_array( 'type', $fields, true ) ) {
    14751475                        $data['type'] = $post->post_type;
    14761476                }
    14771477
    1478                 if ( ! empty( $schema['properties']['link'] ) ) {
     1478                if ( in_array( 'link', $fields, true ) ) {
    14791479                        $data['link'] = get_permalink( $post->ID );
    14801480                }
    14811481
    1482                 if ( ! empty( $schema['properties']['title'] ) ) {
     1482                if ( in_array( 'title', $fields, true ) ) {
    14831483                        add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
    14841484
     
    15001500                }
    15011501
    1502                 if ( ! empty( $schema['properties']['content'] ) ) {
     1502                if ( in_array( 'content', $fields, true ) ) {
    15031503                        $data['content'] = array(
    15041504                                'raw'       => $post->post_content,
     
    15091509                }
    15101510
    1511                 if ( ! empty( $schema['properties']['excerpt'] ) ) {
     1511                if ( in_array( 'excerpt', $fields, true ) ) {
    15121512                        /** This filter is documented in wp-includes/post-template.php */
    15131513                        $excerpt         = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) );
     
    15241524                }
    15251525
    1526                 if ( ! empty( $schema['properties']['author'] ) ) {
     1526                if ( in_array( 'author', $fields, true ) ) {
    15271527                        $data['author'] = (int) $post->post_author;
    15281528                }
    15291529
    1530                 if ( ! empty( $schema['properties']['featured_media'] ) ) {
     1530                if ( in_array( 'featured_media', $fields, true ) ) {
    15311531                        $data['featured_media'] = (int) get_post_thumbnail_id( $post->ID );
    15321532                }
    15331533
    1534                 if ( ! empty( $schema['properties']['parent'] ) ) {
     1534                if ( in_array( 'parent', $fields, true ) ) {
    15351535                        $data['parent'] = (int) $post->post_parent;
    15361536                }
    15371537
    1538                 if ( ! empty( $schema['properties']['menu_order'] ) ) {
     1538                if ( in_array( 'menu_order', $fields, true ) ) {
    15391539                        $data['menu_order'] = (int) $post->menu_order;
    15401540                }
    15411541
    1542                 if ( ! empty( $schema['properties']['comment_status'] ) ) {
     1542                if ( in_array( 'comment_status', $fields, true ) ) {
    15431543                        $data['comment_status'] = $post->comment_status;
    15441544                }
    15451545
    1546                 if ( ! empty( $schema['properties']['ping_status'] ) ) {
     1546                if ( in_array( 'ping_status', $fields, true ) ) {
    15471547                        $data['ping_status'] = $post->ping_status;
    15481548                }
    15491549
    1550                 if ( ! empty( $schema['properties']['sticky'] ) ) {
     1550                if ( in_array( 'sticky', $fields, true ) ) {
    15511551                        $data['sticky'] = is_sticky( $post->ID );
    15521552                }
    15531553
    1554                 if ( ! empty( $schema['properties']['template'] ) ) {
     1554                if ( in_array( 'template', $fields, true ) ) {
    15551555                        if ( $template = get_page_template_slug( $post->ID ) ) {
    15561556                                $data['template'] = $template;
     
    15601560                }
    15611561
    1562                 if ( ! empty( $schema['properties']['format'] ) ) {
     1562                if ( in_array( 'format', $fields, true ) ) {
    15631563                        $data['format'] = get_post_format( $post->ID );
    15641564
     
    15691569                }
    15701570
    1571                 if ( ! empty( $schema['properties']['meta'] ) ) {
     1571                if ( in_array( 'meta', $fields, true ) ) {
    15721572                        $data['meta'] = $this->meta->get_value( $post->ID, $request );
    15731573                }
     
    15781578                        $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
    15791579
    1580                         if ( ! empty( $schema['properties'][ $base ] ) ) {
     1580                        if ( in_array( $base, $fields, true ) ) {
    15811581                                $terms         = get_the_terms( $post, $taxonomy->name );
    15821582                                $data[ $base ] = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array();
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php

    r42343 r43087  
    341341                setup_postdata( $post );
    342342
    343                 $schema = $this->get_item_schema();
    344 
    345                 $data = array();
    346 
    347                 if ( ! empty( $schema['properties']['author'] ) ) {
     343                $fields = $this->get_fields_for_response( $request );
     344                $data   = array();
     345
     346                if ( in_array( 'author', $fields, true ) ) {
    348347                        $data['author'] = (int) $post->post_author;
    349348                }
    350349
    351                 if ( ! empty( $schema['properties']['date'] ) ) {
     350                if ( in_array( 'date', $fields, true ) ) {
    352351                        $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date );
    353352                }
    354353
    355                 if ( ! empty( $schema['properties']['date_gmt'] ) ) {
     354                if ( in_array( 'date_gmt', $fields, true ) ) {
    356355                        $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt );
    357356                }
    358357
    359                 if ( ! empty( $schema['properties']['id'] ) ) {
     358                if ( in_array( 'id', $fields, true ) ) {
    360359                        $data['id'] = $post->ID;
    361360                }
    362361
    363                 if ( ! empty( $schema['properties']['modified'] ) ) {
     362                if ( in_array( 'modified', $fields, true ) ) {
    364363                        $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified );
    365364                }
    366365
    367                 if ( ! empty( $schema['properties']['modified_gmt'] ) ) {
     366                if ( in_array( 'modified_gmt', $fields, true ) ) {
    368367                        $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt );
    369368                }
    370369
    371                 if ( ! empty( $schema['properties']['parent'] ) ) {
     370                if ( in_array( 'parent', $fields, true ) ) {
    372371                        $data['parent'] = (int) $post->post_parent;
    373372                }
    374373
    375                 if ( ! empty( $schema['properties']['slug'] ) ) {
     374                if ( in_array( 'slug', $fields, true ) ) {
    376375                        $data['slug'] = $post->post_name;
    377376                }
    378377
    379                 if ( ! empty( $schema['properties']['guid'] ) ) {
     378                if ( in_array( 'guid', $fields, true ) ) {
    380379                        $data['guid'] = array(
    381380                                /** This filter is documented in wp-includes/post-template.php */
     
    385384                }
    386385
    387                 if ( ! empty( $schema['properties']['title'] ) ) {
     386                if ( in_array( 'title', $fields, true ) ) {
    388387                        $data['title'] = array(
    389388                                'raw'      => $post->post_title,
     
    392391                }
    393392
    394                 if ( ! empty( $schema['properties']['content'] ) ) {
     393                if ( in_array( 'content', $fields, true ) ) {
    395394
    396395                        $data['content'] = array(
     
    401400                }
    402401
    403                 if ( ! empty( $schema['properties']['excerpt'] ) ) {
     402                if ( in_array( 'excerpt', $fields, true ) ) {
    404403                        $data['excerpt'] = array(
    405404                                'raw'      => $post->post_excerpt,
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php

    r42973 r43087  
    182182        public function prepare_item_for_response( $taxonomy, $request ) {
    183183                $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
    184                 $data = array(
    185                         'name'         => $taxonomy->label,
    186                         'slug'         => $taxonomy->name,
    187                         'capabilities' => $taxonomy->cap,
    188                         'description'  => $taxonomy->description,
    189                         'labels'       => $taxonomy->labels,
    190                         'types'        => $taxonomy->object_type,
    191                         'show_cloud'   => $taxonomy->show_tagcloud,
    192                         'hierarchical' => $taxonomy->hierarchical,
    193                         'rest_base'    => $base,
    194                         'visibility'   => array(
     184
     185                $fields = $this->get_fields_for_response( $request );
     186                $data   = array();
     187
     188                if ( in_array( 'name', $fields, true ) ) {
     189                        $data['name'] = $taxonomy->label;
     190                }
     191
     192                if ( in_array( 'slug', $fields, true ) ) {
     193                        $data['slug'] = $taxonomy->name;
     194                }
     195
     196                if ( in_array( 'capabilities', $fields, true ) ) {
     197                        $data['capabilities'] = $taxonomy->cap;
     198                }
     199
     200                if ( in_array( 'description', $fields, true ) ) {
     201                        $data['description'] = $taxonomy->description;
     202                }
     203
     204                if ( in_array( 'labels', $fields, true ) ) {
     205                        $data['labels'] = $taxonomy->labels;
     206                }
     207
     208                if ( in_array( 'types', $fields, true ) ) {
     209                        $data['types'] = $taxonomy->object_type;
     210                }
     211
     212                if ( in_array( 'show_cloud', $fields, true ) ) {
     213                        $data['show_cloud'] = $taxonomy->show_tagcloud;
     214                }
     215
     216                if ( in_array( 'hierarchical', $fields, true ) ) {
     217                        $data['hierarchical'] = $taxonomy->hierarchical;
     218                }
     219
     220                if ( in_array( 'rest_base', $fields, true ) ) {
     221                        $data['rest_base'] = $base;
     222                }
     223
     224                if ( in_array( 'visibility', $fields, true ) ) {
     225                        $data['visibility'] = array(
    195226                                'public'             => (bool) $taxonomy->public,
    196227                                'publicly_queryable' => (bool) $taxonomy->publicly_queryable,
     
    199230                                'show_in_quick_edit' => (bool) $taxonomy->show_in_quick_edit,
    200231                                'show_ui'            => (bool) $taxonomy->show_ui,
    201                         ),
    202                 );
     232                        );
     233                }
    203234
    204235                $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php

    r42354 r43087  
    692692        public function prepare_item_for_response( $item, $request ) {
    693693
    694                 $schema = $this->get_item_schema();
     694                $fields = $this->get_fields_for_response( $request );
    695695                $data   = array();
    696696
    697                 if ( ! empty( $schema['properties']['id'] ) ) {
     697                if ( in_array( 'id', $fields, true ) ) {
    698698                        $data['id'] = (int) $item->term_id;
    699699                }
    700700
    701                 if ( ! empty( $schema['properties']['count'] ) ) {
     701                if ( in_array( 'count', $fields, true ) ) {
    702702                        $data['count'] = (int) $item->count;
    703703                }
    704704
    705                 if ( ! empty( $schema['properties']['description'] ) ) {
     705                if ( in_array( 'description', $fields, true ) ) {
    706706                        $data['description'] = $item->description;
    707707                }
    708708
    709                 if ( ! empty( $schema['properties']['link'] ) ) {
     709                if ( in_array( 'link', $fields, true ) ) {
    710710                        $data['link'] = get_term_link( $item );
    711711                }
    712712
    713                 if ( ! empty( $schema['properties']['name'] ) ) {
     713                if ( in_array( 'name', $fields, true ) ) {
    714714                        $data['name'] = $item->name;
    715715                }
    716716
    717                 if ( ! empty( $schema['properties']['slug'] ) ) {
     717                if ( in_array( 'slug', $fields, true ) ) {
    718718                        $data['slug'] = $item->slug;
    719719                }
    720720
    721                 if ( ! empty( $schema['properties']['taxonomy'] ) ) {
     721                if ( in_array( 'taxonomy', $fields, true ) ) {
    722722                        $data['taxonomy'] = $item->taxonomy;
    723723                }
    724724
    725                 if ( ! empty( $schema['properties']['parent'] ) ) {
     725                if ( in_array( 'parent', $fields, true ) ) {
    726726                        $data['parent'] = (int) $item->parent;
    727727                }
    728728
    729                 if ( ! empty( $schema['properties']['meta'] ) ) {
     729                if ( in_array( 'meta', $fields, true ) ) {
    730730                        $data['meta'] = $this->meta->get_value( $item->term_id, $request );
    731731                }
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

    r43001 r43087  
    847847
    848848                $data   = array();
    849                 $schema = $this->get_item_schema();
    850 
    851                 if ( ! empty( $schema['properties']['id'] ) ) {
     849                $fields = $this->get_fields_for_response( $request );
     850
     851                if ( in_array( 'id', $fields, true ) ) {
    852852                        $data['id'] = $user->ID;
    853853                }
    854854
    855                 if ( ! empty( $schema['properties']['username'] ) ) {
     855                if ( in_array( 'username', $fields, true ) ) {
    856856                        $data['username'] = $user->user_login;
    857857                }
    858858
    859                 if ( ! empty( $schema['properties']['name'] ) ) {
     859                if ( in_array( 'name', $fields, true ) ) {
    860860                        $data['name'] = $user->display_name;
    861861                }
    862862
    863                 if ( ! empty( $schema['properties']['first_name'] ) ) {
     863                if ( in_array( 'first_name', $fields, true ) ) {
    864864                        $data['first_name'] = $user->first_name;
    865865                }
    866866
    867                 if ( ! empty( $schema['properties']['last_name'] ) ) {
     867                if ( in_array( 'last_name', $fields, true ) ) {
    868868                        $data['last_name'] = $user->last_name;
    869869                }
    870870
    871                 if ( ! empty( $schema['properties']['email'] ) ) {
     871                if ( in_array( 'email', $fields, true ) ) {
    872872                        $data['email'] = $user->user_email;
    873873                }
    874874
    875                 if ( ! empty( $schema['properties']['url'] ) ) {
     875                if ( in_array( 'url', $fields, true ) ) {
    876876                        $data['url'] = $user->user_url;
    877877                }
    878878
    879                 if ( ! empty( $schema['properties']['description'] ) ) {
     879                if ( in_array( 'description', $fields, true ) ) {
    880880                        $data['description'] = $user->description;
    881881                }
    882882
    883                 if ( ! empty( $schema['properties']['link'] ) ) {
     883                if ( in_array( 'link', $fields, true ) ) {
    884884                        $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename );
    885885                }
    886886
    887                 if ( ! empty( $schema['properties']['locale'] ) ) {
     887                if ( in_array( 'locale', $fields, true ) ) {
    888888                        $data['locale'] = get_user_locale( $user );
    889889                }
    890890
    891                 if ( ! empty( $schema['properties']['nickname'] ) ) {
     891                if ( in_array( 'nickname', $fields, true ) ) {
    892892                        $data['nickname'] = $user->nickname;
    893893                }
    894894
    895                 if ( ! empty( $schema['properties']['slug'] ) ) {
     895                if ( in_array( 'slug', $fields, true ) ) {
    896896                        $data['slug'] = $user->user_nicename;
    897897                }
    898898
    899                 if ( ! empty( $schema['properties']['roles'] ) ) {
     899                if ( in_array( 'roles', $fields, true ) ) {
    900900                        // Defensively call array_values() to ensure an array is returned.
    901901                        $data['roles'] = array_values( $user->roles );
    902902                }
    903903
    904                 if ( ! empty( $schema['properties']['registered_date'] ) ) {
     904                if ( in_array( 'registered_date', $fields, true ) ) {
    905905                        $data['registered_date'] = date( 'c', strtotime( $user->user_registered ) );
    906906                }
    907907
    908                 if ( ! empty( $schema['properties']['capabilities'] ) ) {
     908                if ( in_array( 'capabilities', $fields, true ) ) {
    909909                        $data['capabilities'] = (object) $user->allcaps;
    910910                }
    911911
    912                 if ( ! empty( $schema['properties']['extra_capabilities'] ) ) {
     912                if ( in_array( 'extra_capabilities', $fields, true ) ) {
    913913                        $data['extra_capabilities'] = (object) $user->caps;
    914914                }
    915915
    916                 if ( ! empty( $schema['properties']['avatar_urls'] ) ) {
     916                if ( in_array( 'avatar_urls', $fields, true ) ) {
    917917                        $data['avatar_urls'] = rest_get_avatar_urls( $user->user_email );
    918918                }
    919919
    920                 if ( ! empty( $schema['properties']['meta'] ) ) {
     920                if ( in_array( 'meta', $fields, true ) ) {
    921921                        $data['meta'] = $this->meta->get_value( $user->ID, $request );
    922922                }
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r42770 r43087  
    11771177                $this->check_post_data( $attachment, $data, 'view', $response->get_links() );
    11781178                $this->check_post_data( $attachment, $data, 'embed', $response->get_links() );
     1179        }
     1180
     1181        public function test_prepare_item_limit_fields() {
     1182                $attachment_id = $this->factory->attachment->create_object(
     1183                        $this->test_file, 0, array(
     1184                                'post_mime_type' => 'image/jpeg',
     1185                                'post_excerpt'   => 'A sample caption',
     1186                                'post_author'    => self::$editor_id,
     1187                        )
     1188                );
     1189                wp_set_current_user( self::$editor_id );
     1190                $endpoint = new WP_REST_Attachments_Controller( 'post' );
     1191                $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/media/%d', $attachment_id ) );
     1192                $request->set_param( 'context', 'edit' );
     1193                $request->set_param( '_fields', 'id,slug' );
     1194                $obj      = get_post( $attachment_id );
     1195                $response = $endpoint->prepare_item_for_response( $obj, $request );
     1196                $this->assertEquals( array(
     1197                        'id',
     1198                        'slug',
     1199                ), array_keys( $response->get_data() ) );
    11791200        }
    11801201
  • trunk/tests/phpunit/tests/rest-api/rest-categories-controller.php

    r42724 r43087  
    881881
    882882                $this->check_taxonomy_term( $term, $data, $response->get_links() );
     883        }
     884
     885        public function test_prepare_item_limit_fields() {
     886                $request  = new WP_REST_Request;
     887                $endpoint = new WP_REST_Terms_Controller( 'category' );
     888                $request->set_param( '_fields', 'id,name' );
     889                $term     = get_term( 1, 'category' );
     890                $response = $endpoint->prepare_item_for_response( $term, $request );
     891                $this->assertEquals( array(
     892                        'id',
     893                        'name',
     894                ), array_keys( $response->get_data() ) );
    883895        }
    884896
  • trunk/tests/phpunit/tests/rest-api/rest-comments-controller.php

    r42724 r43087  
    846846                $data = $response->get_data();
    847847                $this->check_comment_data( $data, 'edit', $response->get_links() );
     848        }
     849
     850        public function test_prepare_item_limit_fields() {
     851                wp_set_current_user( self::$admin_id );
     852                $endpoint = new WP_REST_Comments_Controller;
     853                $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', self::$approved_id ) );
     854                $request->set_param( 'context', 'edit' );
     855                $request->set_param( '_fields', 'id,status' );
     856                $obj      = get_comment( self::$approved_id );
     857                $response = $endpoint->prepare_item_for_response( $obj, $request );
     858                $this->assertEquals( array(
     859                        'id',
     860                        'status',
     861                ), array_keys( $response->get_data() ) );
    848862        }
    849863
  • trunk/tests/phpunit/tests/rest-api/rest-controller.php

    r42343 r43087  
    201201                $this->assertEquals( 'a', $args['somedefault']['default'] );
    202202        }
     203
     204        public function test_get_fields_for_response() {
     205                $controller = new WP_REST_Test_Controller();
     206                $request    = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
     207                $fields     = $controller->get_fields_for_response( $request );
     208                $this->assertEquals( array(
     209                        'somestring',
     210                        'someinteger',
     211                        'someboolean',
     212                        'someurl',
     213                        'somedate',
     214                        'someemail',
     215                        'someenum',
     216                        'someargoptions',
     217                        'somedefault',
     218                ), $fields );
     219                $request->set_param( '_fields', 'somestring,someinteger' );
     220                $fields = $controller->get_fields_for_response( $request );
     221                $this->assertEquals( array(
     222                        'somestring',
     223                        'someinteger',
     224                ), $fields );
     225        }
    203226}
  • trunk/tests/phpunit/tests/rest-api/rest-pages-controller.php

    r42724 r43087  
    450450        public function test_prepare_item() {
    451451
     452        }
     453
     454        public function test_prepare_item_limit_fields() {
     455                wp_set_current_user( self::$editor_id );
     456                $page_id  = $this->factory->post->create(
     457                        array(
     458                                'post_status' => 'publish',
     459                                'post_type'   => 'page',
     460                        )
     461                );
     462                $endpoint = new WP_REST_Posts_Controller( 'page' );
     463                $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/pages/%d', $page_id ) );
     464                $request->set_param( 'context', 'edit' );
     465                $request->set_param( '_fields', 'id,slug' );
     466                $obj      = get_post( $page_id );
     467                $response = $endpoint->prepare_item_for_response( $obj, $request );
     468                $this->assertEquals( array(
     469                        'id',
     470                        'slug',
     471                ), array_keys( $response->get_data() ) );
    452472        }
    453473
  • trunk/tests/phpunit/tests/rest-api/rest-post-statuses-controller.php

    r42724 r43087  
    130130                $data = $endpoint->prepare_item_for_response( $obj, $request );
    131131                $this->check_post_status_obj( $obj, $data->get_data(), $data->get_links() );
     132        }
     133
     134        public function test_prepare_item_limit_fields() {
     135                $obj      = get_post_status_object( 'publish' );
     136                $request  = new WP_REST_Request;
     137                $endpoint = new WP_REST_Post_Statuses_Controller;
     138                $request->set_param( 'context', 'edit' );
     139                $request->set_param( '_fields', 'id,name' );
     140                $response = $endpoint->prepare_item_for_response( $obj, $request );
     141                $this->assertEquals( array(
     142                        // 'id' doesn't exist in this context.
     143                        'name',
     144                ), array_keys( $response->get_data() ) );
    132145        }
    133146
  • trunk/tests/phpunit/tests/rest-api/rest-post-types-controller.php

    r43007 r43087  
    122122                $response = $endpoint->prepare_item_for_response( $obj, $request );
    123123                $this->check_post_type_obj( 'edit', $obj, $response->get_data(), $response->get_links() );
     124        }
     125
     126        public function test_prepare_item_limit_fields() {
     127                $obj      = get_post_type_object( 'post' );
     128                $request  = new WP_REST_Request;
     129                $endpoint = new WP_REST_Post_Types_Controller;
     130                $request->set_param( 'context', 'edit' );
     131                $request->set_param( '_fields', 'id,name' );
     132                $response = $endpoint->prepare_item_for_response( $obj, $request );
     133                $this->assertEquals( array(
     134                        // 'id' doesn't exist in this context.
     135                        'name',
     136                ), array_keys( $response->get_data() ) );
    124137        }
    125138
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r42972 r43087  
    14981498
    14991499                $this->check_get_post_response( $response, 'edit' );
     1500        }
     1501
     1502        public function test_prepare_item_limit_fields() {
     1503                wp_set_current_user( self::$editor_id );
     1504                $endpoint = new WP_REST_Posts_Controller( 'post' );
     1505                $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     1506                $request->set_param( 'context', 'edit' );
     1507                $request->set_param( '_fields', 'id,slug' );
     1508                $obj      = get_post( self::$post_id );
     1509                $response = $endpoint->prepare_item_for_response( $obj, $request );
     1510                $this->assertEquals( array(
     1511                        'id',
     1512                        'slug',
     1513                ), array_keys( $response->get_data() ) );
    15001514        }
    15011515
  • trunk/tests/phpunit/tests/rest-api/rest-revisions-controller.php

    r42724 r43087  
    236236                $this->assertEquals( 200, $response->get_status() );
    237237                $this->check_get_revision_response( $response, $this->revision_1 );
     238        }
     239
     240        public function test_prepare_item_limit_fields() {
     241                wp_set_current_user( self::$editor_id );
     242                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );
     243                $endpoint = new WP_REST_Revisions_Controller( 'post' );
     244                $request->set_param( 'context', 'edit' );
     245                $request->set_param( '_fields', 'id,slug' );
     246                $revision = get_post( $this->revision_id1 );
     247                $response = $endpoint->prepare_item_for_response( $revision, $request );
     248                $this->assertEquals( array(
     249                        'id',
     250                        'slug',
     251                ), array_keys( $response->get_data() ) );
    238252        }
    239253
  • trunk/tests/phpunit/tests/rest-api/rest-tags-controller.php

    r42724 r43087  
    969969        }
    970970
     971        public function test_prepare_item_limit_fields() {
     972                $request  = new WP_REST_Request;
     973                $endpoint = new WP_REST_Terms_Controller( 'post_tag' );
     974                $request->set_param( '_fields', 'id,name' );
     975                $term     = get_term_by( 'id', $this->factory->tag->create(), 'post_tag' );
     976                $response = $endpoint->prepare_item_for_response( $term, $request );
     977                $this->assertEquals( array(
     978                        'id',
     979                        'name',
     980                ), array_keys( $response->get_data() ) );
     981        }
     982
    971983        public function test_get_item_schema() {
    972984                $request    = new WP_REST_Request( 'OPTIONS', '/wp/v2/tags' );
  • trunk/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php

    r42729 r43087  
    161161                $response = $endpoint->prepare_item_for_response( $tax, $request );
    162162                $this->check_taxonomy_object( 'edit', $tax, $response->get_data(), $response->get_links() );
     163        }
     164
     165        public function test_prepare_item_limit_fields() {
     166                $tax      = get_taxonomy( 'category' );
     167                $request  = new WP_REST_Request;
     168                $endpoint = new WP_REST_Taxonomies_Controller;
     169                $request->set_param( 'context', 'edit' );
     170                $request->set_param( '_fields', 'id,name' );
     171                $response = $endpoint->prepare_item_for_response( $tax, $request );
     172                $this->assertEquals( array(
     173                        // 'id' doesn't exist in this context.
     174                        'name',
     175                ), array_keys( $response->get_data() ) );
    163176        }
    164177
  • trunk/tests/phpunit/tests/rest-api/rest-users-controller.php

    r43001 r43087  
    848848                $data = $this->endpoint->prepare_item_for_response( $user, $request );
    849849                $this->check_get_user_response( $data, 'edit' );
     850        }
     851
     852        public function test_prepare_item_limit_fields() {
     853                wp_set_current_user( self::$user );
     854                $request = new WP_REST_Request;
     855                $request->set_param( 'context', 'edit' );
     856                $request->set_param( '_fields', 'id,name' );
     857                $user     = get_user_by( 'id', get_current_user_id() );
     858                $response = $this->endpoint->prepare_item_for_response( $user, $request );
     859                $this->assertEquals( array(
     860                        'id',
     861                        'name',
     862                ), array_keys( $response->get_data() ) );
    850863        }
    851864
Note: See TracChangeset for help on using the changeset viewer.