WordPress.org

Make WordPress Core

Changeset 39026


Ignore:
Timestamp:
10/30/2016 05:36:15 PM (4 years ago)
Author:
DrewAPicture
Message:

Docs: Add much more complete and syntactically correct documentation throughout the WP_REST_Posts_Controller class.

Props Soean, mrahmadawais, flixos90, DrewAPicture.
See #38398.

File:
1 edited

Legend:

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

    r38968 r39026  
    11<?php
    2 
     2/**
     3 * REST API: WP_REST_Posts_Controller class
     4 *
     5 * @package WordPress
     6 * @subpackage REST_API
     7 * @since 4.7.0
     8 */
     9
     10/**
     11 * Core class to access posts via the REST API.
     12 *
     13 * @since 4.7.0
     14 *
     15 * @see WP_REST_Controller
     16 */
    317class WP_REST_Posts_Controller extends WP_REST_Controller {
    418
     
    620     * Post type.
    721     *
     22     * @since 4.7.0
    823     * @access protected
    924     * @var string
     
    1429     * Instance of a post meta fields object.
    1530     *
     31     * @since 4.7.0
    1632     * @access protected
    1733     * @var WP_REST_Post_Meta_Fields
     
    2137    /**
    2238     * Constructor.
     39     *
     40     * @since 4.7.0
     41     * @access public
    2342     *
    2443     * @param string $post_type Post type.
     
    3453
    3554    /**
    36      * Register the routes for the objects of the controller.
     55     * Registers the routes for the objects of the controller.
     56     *
     57     * @since 4.7.0
     58     * @access public
     59     *
     60     * @see register_rest_route()
    3761     */
    3862    public function register_routes() {
     
    4064        register_rest_route( $this->namespace, '/' . $this->rest_base, array(
    4165            array(
    42                 'methods'         => WP_REST_Server::READABLE,
    43                 'callback'        => array( $this, 'get_items' ),
     66                'methods'             => WP_REST_Server::READABLE,
     67                'callback'            => array( $this, 'get_items' ),
    4468                'permission_callback' => array( $this, 'get_items_permissions_check' ),
    45                 'args'            => $this->get_collection_params(),
     69                'args'                => $this->get_collection_params(),
    4670            ),
    4771            array(
    48                 'methods'         => WP_REST_Server::CREATABLE,
    49                 'callback'        => array( $this, 'create_item' ),
     72                'methods'             => WP_REST_Server::CREATABLE,
     73                'callback'            => array( $this, 'create_item' ),
    5074                'permission_callback' => array( $this, 'create_item_permissions_check' ),
    51                 'args'            => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
     75                'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
    5276            ),
    5377            'schema' => array( $this, 'get_public_item_schema' ),
    5478        ) );
     79
    5580        register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
    5681            array(
    57                 'methods'         => WP_REST_Server::READABLE,
    58                 'callback'        => array( $this, 'get_item' ),
     82                'methods'             => WP_REST_Server::READABLE,
     83                'callback'            => array( $this, 'get_item' ),
    5984                'permission_callback' => array( $this, 'get_item_permissions_check' ),
    60                 'args'            => array(
     85                'args'                => array(
    6186                    'context'  => $this->get_context_param( array( 'default' => 'view' ) ),
    6287                    'password' => array(
     
    6691            ),
    6792            array(
    68                 'methods'         => WP_REST_Server::EDITABLE,
    69                 'callback'        => array( $this, 'update_item' ),
     93                'methods'             => WP_REST_Server::EDITABLE,
     94                'callback'            => array( $this, 'update_item' ),
    7095                'permission_callback' => array( $this, 'update_item_permissions_check' ),
    71                 'args'            => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
     96                'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
    7297            ),
    7398            array(
    74                 'methods'  => WP_REST_Server::DELETABLE,
    75                 'callback' => array( $this, 'delete_item' ),
     99                'methods'             => WP_REST_Server::DELETABLE,
     100                'callback'            => array( $this, 'delete_item' ),
    76101                'permission_callback' => array( $this, 'delete_item_permissions_check' ),
    77                 'args'     => array(
    78                     'force'    => array(
    79                         'default'      => false,
    80                         'description'  => __( 'Whether to bypass trash and force deletion.' ),
     102                'args'                => array(
     103                    'force' => array(
     104                        'default'     => false,
     105                        'description' => __( 'Whether to bypass trash and force deletion.' ),
    81106                    ),
    82107                ),
     
    87112
    88113    /**
    89      * Check if a given request has access to read /posts.
     114     * Checks if a given request has access to read posts.
     115     *
     116     * @since 4.7.0
     117     * @access public
    90118     *
    91119     * @param  WP_REST_Request $request Full details about the request.
    92      * @return WP_Error|boolean
     120     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
    93121     */
    94122    public function get_items_permissions_check( $request ) {
     
    104132
    105133    /**
    106      * Get a collection of posts.
     134     * Retrieves a collection of posts.
     135     *
     136     * @since 4.7.0
     137     * @access public
    107138     *
    108139     * @param WP_REST_Request $request Full details about the request.
    109      * @return WP_Error|WP_REST_Response
     140     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    110141     */
    111142    public function get_items( $request ) {
    112143
    113         // Make sure a search string is set in case the orderby is set to 'relevance'.
     144        // Ensure a search string is set in case the orderby is set to 'relevance'.
    114145        if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) {
    115146            return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) );
     
    120151        $args = array();
    121152
    122         // This array defines mappings between public API query parameters whose
    123         // values are accepted as-passed, and their internal WP_Query parameter
    124         // name equivalents (some are the same). Only values which are also
    125         // present in $registered will be set.
     153        /*
     154         * This array defines mappings between public API query parameters whose
     155         * values are accepted as-passed, and their internal WP_Query parameter
     156         * name equivalents (some are the same). Only values which are also
     157         * present in $registered will be set.
     158         */
    126159        $parameter_mappings = array(
    127160            'author'         => 'author__in',
     
    141174        );
    142175
    143         // For each known parameter which is both registered and present in the request,
    144         // set the parameter's value on the query $args.
     176        /*
     177         * For each known parameter which is both registered and present in the request,
     178         * set the parameter's value on the query $args.
     179         */
    145180        foreach ( $parameter_mappings as $api_param => $wp_param ) {
    146181            if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) {
     
    150185
    151186        // Check for & assign any parameters which require special handling or setting.
    152 
    153187        $args['date_query'] = array();
     188
    154189        // Set before into date query. Date query must be specified as an array of an array.
    155190        if ( isset( $registered['before'], $request['before'] ) ) {
     
    170205            $sticky_posts = get_option( 'sticky_posts', array() );
    171206            if ( $sticky_posts && $request['sticky'] ) {
    172                 // As post__in will be used to only get sticky posts,
    173                 // we have to support the case where post__in was already
    174                 // specified.
     207                /*
     208                 * As post__in will be used to only get sticky posts,
     209                 * we have to support the case where post__in was already
     210                 * specified.
     211                 */
    175212                $args['post__in'] = $args['post__in'] ? array_intersect( $sticky_posts, $args['post__in'] ) : $sticky_posts;
    176213
    177                 // If we intersected, but there are no post ids in common,
    178                 // WP_Query won't return "no posts" for `post__in = array()`
    179                 // so we have to fake it a bit.
     214                /*
     215                 * If we intersected, but there are no post ids in common,
     216                 * WP_Query won't return "no posts" for post__in = array()
     217                 * so we have to fake it a bit.
     218                 */
    180219                if ( ! $args['post__in'] ) {
    181220                    $args['post__in'] = array( -1 );
    182221                }
    183222            } elseif ( $sticky_posts ) {
    184                 // As post___not_in will be used to only get posts that
    185                 // are not sticky, we have to support the case where post__not_in
    186                 // was already specified.
     223                /*
     224                 * As post___not_in will be used to only get posts that
     225                 * are not sticky, we have to support the case where post__not_in
     226                 * was already specified.
     227                 */
    187228                $args['post__not_in'] = array_merge( $args['post__not_in'], $sticky_posts );
    188229            }
     
    193234
    194235        /**
    195          * Filter the query arguments for a request.
    196          *
    197          * Enables adding extra arguments or setting defaults for a post
    198          * collection request.
    199          *
    200          * @see https://developer.wordpress.org/reference/classes/wp_query/
     236         * Filters the query arguments for a request.
     237         *
     238         * Enables adding extra arguments or setting defaults for a post collection request.
     239         *
     240         * @since 4.7.0
     241         *
     242         * @link https://developer.wordpress.org/reference/classes/wp_query/
    201243         *
    202244         * @param array           $args    Key value array of query var to query value.
     
    207249
    208250        $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     251
    209252        foreach ( $taxonomies as $taxonomy ) {
    210253            $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     
    231274        }
    232275
    233         $posts_query = new WP_Query();
     276        $posts_query  = new WP_Query();
    234277        $query_result = $posts_query->query( $query_args );
    235278
     
    240283
    241284        $posts = array();
     285
    242286        foreach ( $query_result as $post ) {
    243287            if ( ! $this->check_read_permission( $post ) ) {
     
    245289            }
    246290
    247             $data = $this->prepare_item_for_response( $post, $request );
     291            $data    = $this->prepare_item_for_response( $post, $request );
    248292            $posts[] = $this->prepare_response_for_collection( $data );
    249293        }
     
    260304            // Out-of-bounds, run the query again without LIMIT for total count.
    261305            unset( $query_args['paged'] );
     306
    262307            $count_query = new WP_Query();
    263308            $count_query->query( $query_args );
     
    266311
    267312        $max_pages = ceil( $total_posts / (int) $posts_query->query_vars['posts_per_page'] );
    268 
    269         $response = rest_ensure_response( $posts );
     313        $response  = rest_ensure_response( $posts );
     314
    270315        $response->header( 'X-WP-Total', (int) $total_posts );
    271316        $response->header( 'X-WP-TotalPages', (int) $max_pages );
     
    276321        if ( $page > 1 ) {
    277322            $prev_page = $page - 1;
     323
    278324            if ( $prev_page > $max_pages ) {
    279325                $prev_page = $max_pages;
    280326            }
     327
    281328            $prev_link = add_query_arg( 'page', $prev_page, $base );
    282329            $response->link_header( 'prev', $prev_link );
     
    285332            $next_page = $page + 1;
    286333            $next_link = add_query_arg( 'page', $next_page, $base );
     334
    287335            $response->link_header( 'next', $next_link );
    288336        }
     
    292340
    293341    /**
    294      * Check if a given request has access to read a post.
    295      *
    296      * @param  WP_REST_Request $request Full details about the request.
    297      * @return WP_Error|boolean
     342     * Checks if a given request has access to read a post.
     343     *
     344     * @since 4.7.0
     345     * @access public
     346     *
     347     * @param WP_REST_Request $request Full details about the request.
     348     * @return bool|WP_Error True if the request has read access for the item, WP_Error object otherwise.
    298349     */
    299350    public function get_item_permissions_check( $request ) {
     
    325376
    326377    /**
    327      * Can the user access password-protected content?
     378     * Checks if the user can access password-protected content.
    328379     *
    329380     * This method determines whether we need to override the regular password
    330381     * check in core with a filter.
    331382     *
     383     * @since 4.7.0
     384     * @access protected
     385     *
    332386     * @param WP_Post         $post    Post to check against.
    333387     * @param WP_REST_Request $request Request data to check.
    334      * @return bool True if the user can access password-protected content, false otherwise.
     388     * @return bool True if the user can access password-protected content, otherwise false.
    335389     */
    336390    protected function can_access_password_content( $post, $request ) {
     
    355409
    356410    /**
    357      * Get a single post.
     411     * Retrieves a single post.
     412     *
     413     * @since 4.7.0
     414     * @access public
    358415     *
    359416     * @param WP_REST_Request $request Full details about the request.
    360      * @return WP_Error|WP_REST_Response
     417     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    361418     */
    362419    public function get_item( $request ) {
    363         $id = (int) $request['id'];
     420        $id   = (int) $request['id'];
    364421        $post = $this->get_post( $id );
    365422
     
    368425        }
    369426
    370         $data = $this->prepare_item_for_response( $post, $request );
     427        $data     = $this->prepare_item_for_response( $post, $request );
    371428        $response = rest_ensure_response( $data );
    372429
     
    379436
    380437    /**
    381      * Check if a given request has access to create a post.
    382      *
    383      * @param  WP_REST_Request $request Full details about the request.
    384      * @return WP_Error|boolean
     438     * Checks if a given request has access to create a post.
     439     *
     440     * @since 4.7.0
     441     * @access public
     442     *
     443     * @param WP_REST_Request $request Full details about the request.
     444     * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
    385445     */
    386446    public function create_item_permissions_check( $request ) {
     
    399459            return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new posts.' ), array( 'status' => rest_authorization_required_code() ) );
    400460        }
     461
    401462        return true;
    402463    }
    403464
    404465    /**
    405      * Create a single post.
     466     * Creates a single post.
     467     *
     468     * @since 4.7.0
     469     * @access public
    406470     *
    407471     * @param WP_REST_Request $request Full details about the request.
    408      * @return WP_Error|WP_REST_Response
     472     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    409473     */
    410474    public function create_item( $request ) {
     
    414478
    415479        $post = $this->prepare_item_for_database( $request );
     480
    416481        if ( is_wp_error( $post ) ) {
    417482            return $post;
     
    419484
    420485        $post->post_type = $this->post_type;
    421         $post_id = wp_insert_post( $post, true );
     486        $post_id         = wp_insert_post( $post, true );
    422487
    423488        if ( is_wp_error( $post_id ) ) {
     
    428493                $post_id->add_data( array( 'status' => 400 ) );
    429494            }
     495
    430496            return $post_id;
    431497        }
     498
    432499        $post->ID = $post_id;
    433500
     
    453520            $this->handle_template( $request['template'], $post->ID );
    454521        }
     522
    455523        $terms_update = $this->handle_terms( $post->ID, $request );
     524
    456525        if ( is_wp_error( $terms_update ) ) {
    457526            return $terms_update;
     
    459528
    460529        $post = $this->get_post( $post_id );
     530
    461531        if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
    462532            $meta_update = $this->meta->update_value( $request['meta'], (int) $request['id'] );
     533
    463534            if ( is_wp_error( $meta_update ) ) {
    464535                return $meta_update;
     
    467538
    468539        $fields_update = $this->update_additional_fields_for_object( $post, $request );
     540
    469541        if ( is_wp_error( $fields_update ) ) {
    470542            return $fields_update;
     
    474546         * Fires after a single post is created or updated via the REST API.
    475547         *
    476          * @param object          $post      Inserted Post object (not a WP_Post object).
    477          * @param WP_REST_Request $request   Request object.
    478          * @param boolean         $creating  True when creating post, false when updating.
     548         * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
     549         *
     550         * @since 4.7.0
     551         *
     552         * @param object          $post     Inserted Post object (not a WP_Post object).
     553         * @param WP_REST_Request $request  Request object.
     554         * @param bool            $creating True when creating post, false when updating.
    479555         */
    480556        do_action( "rest_insert_{$this->post_type}", $post, $request, true );
    481557
    482558        $request->set_param( 'context', 'edit' );
     559
    483560        $response = $this->prepare_item_for_response( $post, $request );
    484561        $response = rest_ensure_response( $response );
     562
    485563        $response->set_status( 201 );
    486564        $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) );
     
    490568
    491569    /**
    492      * Check if a given request has access to update a post.
    493      *
    494      * @param  WP_REST_Request $request Full details about the request.
    495      * @return WP_Error|boolean
     570     * Checks if a given request has access to update a post.
     571     *
     572     * @since 4.7.0
     573     * @access public
     574     *
     575     * @param WP_REST_Request $request Full details about the request.
     576     * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
    496577     */
    497578    public function update_item_permissions_check( $request ) {
     
    516597
    517598    /**
    518      * Update a single post.
     599     * Updates a single post.
     600     *
     601     * @since 4.7.0
     602     * @access public
    519603     *
    520604     * @param WP_REST_Request $request Full details about the request.
    521      * @return WP_Error|WP_REST_Response
     605     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    522606     */
    523607    public function update_item( $request ) {
    524         $id = (int) $request['id'];
     608        $id   = (int) $request['id'];
    525609        $post = $this->get_post( $id );
    526610
     
    530614
    531615        $post = $this->prepare_item_for_database( $request );
     616
    532617        if ( is_wp_error( $post ) ) {
    533618            return $post;
    534619        }
     620
    535621        // convert the post object to an array, otherwise wp_update_post will expect non-escaped input.
    536622        $post_id = wp_update_post( (array) $post, true );
     623
    537624        if ( is_wp_error( $post_id ) ) {
    538625            if ( 'db_update_error' === $post_id->get_error_code() ) {
     
    567654
    568655        $terms_update = $this->handle_terms( $post->ID, $request );
     656
    569657        if ( is_wp_error( $terms_update ) ) {
    570658            return $terms_update;
     
    575663        if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
    576664            $meta_update = $this->meta->update_value( $request['meta'], $post->ID );
     665
    577666            if ( is_wp_error( $meta_update ) ) {
    578667                return $meta_update;
     
    581670
    582671        $fields_update = $this->update_additional_fields_for_object( $post, $request );
     672
    583673        if ( is_wp_error( $fields_update ) ) {
    584674            return $fields_update;
     
    589679
    590680        $request->set_param( 'context', 'edit' );
     681
    591682        $response = $this->prepare_item_for_response( $post, $request );
     683
    592684        return rest_ensure_response( $response );
    593685    }
    594686
    595687    /**
    596      * Check if a given request has access to delete a post.
    597      *
    598      * @param  WP_REST_Request $request Full details about the request.
    599      * @return bool|WP_Error
     688     * Checks if a given request has access to delete a post.
     689     *
     690     * @since 4.7.0
     691     * @access public
     692     *
     693     * @param WP_REST_Request $request Full details about the request.
     694     * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
    600695     */
    601696    public function delete_item_permissions_check( $request ) {
     
    611706
    612707    /**
    613      * Delete a single post.
     708     * Deletes a single post.
     709     *
     710     * @since 4.7.0
     711     * @access public
    614712     *
    615713     * @param WP_REST_Request $request Full details about the request.
    616      * @return WP_REST_Response|WP_Error
     714     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    617715     */
    618716    public function delete_item( $request ) {
    619         $id = (int) $request['id'];
     717        $id    = (int) $request['id'];
    620718        $force = (bool) $request['force'];
    621719
     
    627725
    628726        $supports_trash = ( EMPTY_TRASH_DAYS > 0 );
     727
    629728        if ( 'attachment' === $post->post_type ) {
    630729            $supports_trash = $supports_trash && MEDIA_TRASH;
     
    632731
    633732        /**
    634          * Filter whether a post is trashable.
    635          *
    636          * Return false to disable trash support for the post.
    637          *
    638          * @param boolean $supports_trash Whether the post type support trashing.
     733         * Filters whether a post is trashable.
     734         *
     735         * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
     736         *
     737         * Pass false to disable trash support for the post.
     738         *
     739         * @since 4.7.0
     740         *
     741         * @param bool    $supports_trash Whether the post type support trashing.
    639742         * @param WP_Post $post           The Post object being considered for trashing support.
    640743         */
     
    646749
    647750        $request->set_param( 'context', 'edit' );
     751
    648752        $response = $this->prepare_item_for_response( $post, $request );
    649753
     
    672776
    673777        /**
    674          * Fires after a single post is deleted or trashed via the REST API.
     778         * Fires immediately after a single post is deleted or trashed via the REST API.
     779         *
     780         * They dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
     781         *
     782         * @since 4.7.0
    675783         *
    676784         * @param object           $post     The deleted or trashed post.
     
    684792
    685793    /**
    686      * Determine the allowed query_vars for a get_items() response and
    687      * prepare for WP_Query.
    688      *
    689      * @param array           $prepared_args Prepared WP_Query arguments.
    690      * @param WP_REST_Request $request       Full details about the request.
    691      * @return array          $query_args
     794     * Determines the allowed query_vars for a get_items() response and prepares
     795     * them for WP_Query.
     796     *
     797     * @since 4.7.0
     798     * @access protected
     799     *
     800     * @param array           $prepared_args Optional. Prepared WP_Query arguments. Default empty array.
     801     * @param WP_REST_Request $request       Optional. Full details about the request.
     802     * @return array Items query arguments.
    692803     */
    693804    protected function prepare_items_query( $prepared_args = array(), $request = null ) {
     
    695806        $valid_vars = array_flip( $this->get_allowed_query_vars( $request ) );
    696807        $query_args = array();
     808
    697809        foreach ( $valid_vars as $var => $index ) {
    698810            if ( isset( $prepared_args[ $var ] ) ) {
    699811                /**
    700                  * Filter the query_vars used in `get_items` for the constructed query.
     812                 * Filters the query_vars used in get_items() for the constructed query.
    701813                 *
    702                  * The dynamic portion of the hook name, $var, refers to the query_var key.
     814                 * The dynamic portion of the hook name, `$var`, refers to the query_var key.
    703815                 *
    704                  * @param mixed $prepared_args[ $var ] The query_var value.
     816                 * @since 4.7.0
     817                 *
     818                 * @param string $var The query_var value.
    705819                 */
    706820                $query_args[ $var ] = apply_filters( "rest_query_var-{$var}", $prepared_args[ $var ] );
     
    720834
    721835    /**
    722      * Get all the WP Query vars that are allowed for the API request.
    723      *
    724      * @param WP_REST_Request $request Full details about the request.
    725      * @return array
     836     * Retrieves all of the WP Query vars that are allowed for the REST API request.
     837     *
     838     * @since 4.7.0
     839     * @access protected
     840     *
     841     * @param WP_REST_Request $request Optional. Full details about the request.
     842     * @return array Allowed query variables.
    726843     */
    727844    protected function get_allowed_query_vars( $request = null ) {
     
    729846
    730847        /**
    731          * Filter the publicly allowed query vars.
     848         * Filters the publicly allowed query vars.
    732849         *
    733850         * Allows adjusting of the default query vars that are made public.
     851         *
     852         * @since 4.7.0
    734853         *
    735854         * @param array  Array of allowed WP_Query query vars.
     
    740859        if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
    741860            /**
    742              * Filter the allowed 'private' query vars for authorized users.
     861             * Filters the allowed 'private' query vars for authorized users.
    743862             *
    744863             * If the user has the `edit_posts` capability, we also allow use of
     
    749868             * `add_filter( 'rest_private_query_vars', '__return_empty_array' );`
    750869             *
     870             * @since 4.7.0
     871             *
    751872             * @param array $private_query_vars Array of allowed query vars for authorized users.
    752              * }
    753873             */
    754874            $private = apply_filters( 'rest_private_query_vars', $wp->private_query_vars );
     875
    755876            $valid_vars = array_merge( $valid_vars, $private );
    756877        }
     878
    757879        // Define our own in addition to WP's normal vars.
    758880        $rest_valid = array(
     
    770892            'date_query',
    771893        );
     894
    772895        $valid_vars = array_merge( $valid_vars, $rest_valid );
    773896
    774897        /**
    775          * Filter allowed query vars for the REST API.
     898         * Filters allowed query vars for the REST API.
    776899         *
    777900         * This filter allows you to add or remove query vars from the final allowed
    778901         * list for all requests, including unauthenticated ones. To alter the
    779          * vars for editors only, {@see rest_private_query_vars}.
     902         * vars for editors only, see {@see 'rest_private_query_vars'}.
     903         *
     904         * @since 4.7.0
    780905         *
    781906         * @param array {
    782907         *    Array of allowed WP_Query query vars.
    783908         *
    784          *    @param string $allowed_query_var The query var to allow.
    785          *    @param WP_REST_Request $request Request object.
     909         *    @param string          $allowed_query_var The query var to allow.
     910         *    @param WP_REST_Request $request           Request object.
    786911         * }
    787912         */
     
    792917
    793918    /**
    794      * Check the post_date_gmt or modified_gmt and prepare any post or
     919     * Checks the post_date_gmt or modified_gmt and prepare any post or
    795920     * modified date for single post output.
    796921     *
     922     * @since 4.7.0
     923     * @access protected
     924     *
    797925     * @param string      $date_gmt GMT publication time.
    798      * @param string|null $date     Optional, default is null. Local publication time.
     926     * @param string|null $date     Optional. Local publication time. Default null.
    799927     * @return string|null ISO8601/RFC3339 formatted datetime.
    800928     */
     
    815943
    816944    /**
    817      * Prepare a single post for create or update.
     945     * Prepares a single post for create or update.
     946     *
     947     * @since 4.7.0
     948     * @access protected
    818949     *
    819950     * @param WP_REST_Request $request Request object.
    820      * @return WP_Error|stdClass $prepared_post Post object.
     951     * @return stdClass|WP_Error Post object or WP_Error.
    821952     */
    822953    protected function prepare_item_for_database( $request ) {
    823954        $prepared_post = new stdClass;
    824955
    825         // ID.
     956        // Post ID.
    826957        if ( isset( $request['id'] ) ) {
    827958            $prepared_post->ID = absint( $request['id'] );
     
    865996            $prepared_post->post_type = get_post_type( $request['id'] );
    866997        }
     998
    867999        $post_type = get_post_type_object( $prepared_post->post_type );
    8681000
     
    8701002        if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
    8711003            $status = $this->handle_status_param( $request['status'], $post_type );
     1004
    8721005            if ( is_wp_error( $status ) ) {
    8731006                return $status;
     
    8911024            }
    8921025        }
     1026
    8931027        // Post slug.
    8941028        if ( ! empty( $schema['properties']['slug'] ) && isset( $request['slug'] ) ) {
     
    8991033        if ( ! empty( $schema['properties']['author'] ) && ! empty( $request['author'] ) ) {
    9001034            $post_author = (int) $request['author'];
     1035
    9011036            if ( get_current_user_id() !== $post_author ) {
    9021037                $user_obj = get_userdata( $post_author );
     1038
    9031039                if ( ! $user_obj ) {
    9041040                    return new WP_Error( 'rest_invalid_author', __( 'Invalid author id.' ), array( 'status' => 400 ) );
    9051041                }
    9061042            }
     1043
    9071044            $prepared_post->post_author = $post_author;
    9081045        }
     
    9301067        if ( ! empty( $schema['properties']['parent'] ) && ! empty( $request['parent'] ) ) {
    9311068            $parent = $this->get_post( (int) $request['parent'] );
     1069
    9321070            if ( empty( $parent ) ) {
    9331071                return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post parent id.' ), array( 'status' => 400 ) );
     
    9511089            $prepared_post->ping_status = $request['ping_status'];
    9521090        }
     1091
    9531092        /**
    954          * Filter a post before it is inserted via the REST API.
    955          *
    956          * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
    957          * prepared for insertion.
     1093         * Filters a post before it is inserted via the REST API.
     1094         *
     1095         * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
     1096         *
     1097         * @since 4.7.0
    9581098         *
    9591099         * @param stdClass        $prepared_post An object representing a single post prepared
     
    9661106
    9671107    /**
    968      * Determine validity and normalize provided status param.
     1108     * Determines validity and normalizes the given status parameter.
     1109     *
     1110     * @since 4.7.0
     1111     * @access protected
    9691112     *
    9701113     * @param string $post_status Post status.
    9711114     * @param object $post_type   Post type.
    972      * @return WP_Error|string $post_status
     1115     * @return string|WP_Error Post status or WP_Error if lacking the proper permission.
    9731116     */
    9741117    protected function handle_status_param( $post_status, $post_type ) {
     
    10001143
    10011144    /**
    1002      * Determine the featured media based on a request param.
     1145     * Determines the featured media based on a request param.
     1146     *
     1147     * @since 4.7.0
     1148     * @access protected
    10031149     *
    10041150     * @param int $featured_media Featured Media ID.
    10051151     * @param int $post_id        Post ID.
    1006      * @return bool|WP_Error
     1152     * @return bool|WP_Error Whether the post thumbnail was successfully deleted, otherwise WP_Error.
    10071153     */
    10081154    protected function handle_featured_media( $featured_media, $post_id ) {
     
    10231169
    10241170    /**
    1025      * Set the template for a page.
     1171     * Sets the template for a page.
     1172     *
     1173     * @since 4.7.0
     1174     * @access public
    10261175     *
    10271176     * @param string  $template Page template filename.
     
    10371186
    10381187    /**
    1039      * Update the post's terms from a REST request.
    1040      *
    1041      * @param  int             $post_id The post ID to update the terms form.
    1042      * @param  WP_REST_Request $request The request object with post and terms data.
    1043      * @return null|WP_Error   WP_Error on an error assigning any of the terms.
     1188     * Updates the post's terms from a REST request.
     1189     *
     1190     * @since 4.7.0
     1191     * @access protected
     1192     *
     1193     * @param int             $post_id The post ID to update the terms form.
     1194     * @param WP_REST_Request $request The request object with post and terms data.
     1195     * @return null|WP_Error WP_Error on an error assigning any of the terms, otherwise null.
    10441196     */
    10451197    protected function handle_terms( $post_id, $request ) {
    10461198        $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     1199
    10471200        foreach ( $taxonomies as $taxonomy ) {
    10481201            $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     
    10511204                continue;
    10521205            }
    1053             $terms = array_map( 'absint', $request[ $base ] );
     1206
     1207            $terms  = array_map( 'absint', $request[ $base ] );
    10541208            $result = wp_set_object_terms( $post_id, $terms, $taxonomy->name );
     1209
    10551210            if ( is_wp_error( $result ) ) {
    10561211                return $result;
     
    10601215
    10611216    /**
    1062      * Check if a given post type should be viewed or managed.
     1217     * Checks if a given post type can be viewed or managed.
     1218     *
     1219     * @since 4.7.0
     1220     * @access protected
    10631221     *
    10641222     * @param object|string $post_type Post type name or object.
    1065      * @return boolean Is post type allowed?
     1223     * @return bool Whether the post type is allowed in REST.
    10661224     */
    10671225    protected function check_is_post_type_allowed( $post_type ) {
     
    10781236
    10791237    /**
    1080      * Check if we can read a post.
     1238     * Checks if a post can be read.
    10811239     *
    10821240     * Correctly handles posts with the inherit status.
    10831241     *
     1242     * @since 4.7.0
     1243     * @access public
     1244     *
    10841245     * @param object $post Post object.
    1085      * @return boolean Can we read it?
     1246     * @return bool Whether the post can be read.
    10861247     */
    10871248    public function check_read_permission( $post ) {
     
    10911252        }
    10921253
    1093         // Can we read the post?
     1254        // Is the post readable?
    10941255        if ( 'publish' === $post->post_status || current_user_can( $post_type->cap->read_post, $post->ID ) ) {
    10951256            return true;
     
    11071268        }
    11081269
    1109         // If we don't have a parent, but the status is set to inherit, assume
    1110         // it's published (as per get_post_status()).
     1270        /*
     1271         * If there isn't a parent, but the status is set to inherit, assume
     1272         * it's published (as per get_post_status()).
     1273         */
    11111274        if ( 'inherit' === $post->post_status ) {
    11121275            return true;
     
    11171280
    11181281    /**
    1119      * Check if we can edit a post.
     1282     * Checks if a post can be edited.
     1283     *
     1284     * @since 4.7.0
     1285     * @access protected
    11201286     *
    11211287     * @param object $post Post object.
    1122      * @return boolean Can we edit it?
     1288     * @return bool Whether the post can be edited.
    11231289     */
    11241290    protected function check_update_permission( $post ) {
     
    11331299
    11341300    /**
    1135      * Check if we can create a post.
     1301     * Checks if a post can be created.
     1302     *
     1303     * @since 4.7.0
     1304     * @access protected
    11361305     *
    11371306     * @param object $post Post object.
    1138      * @return boolean Can we create it?.
     1307     * @return bool Whether the post can be created.
    11391308     */
    11401309    protected function check_create_permission( $post ) {
     
    11491318
    11501319    /**
    1151      * Check if we can delete a post.
     1320     * Checks if a post can be deleted.
     1321     *
     1322     * @since 4.7.0
     1323     * @access protected
    11521324     *
    11531325     * @param object $post Post object.
    1154      * @return boolean Can we delete it?
     1326     * @return bool Whether the post can be deleted.
    11551327     */
    11561328    protected function check_delete_permission( $post ) {
     
    11651337
    11661338    /**
    1167      * Prepare a single post output for response.
     1339     * Prepares a single post output for response.
     1340     *
     1341     * @since 4.7.0
     1342     * @access public
    11681343     *
    11691344     * @param WP_Post         $post    Post object.
    11701345     * @param WP_REST_Request $request Request object.
    1171      * @return WP_REST_Response $data
     1346     * @return WP_REST_Response Response object.
    11721347     */
    11731348    public function prepare_item_for_response( $post, $request ) {
    11741349        $GLOBALS['post'] = $post;
     1350
    11751351        setup_postdata( $post );
    11761352
     
    12301406        if ( ! empty( $schema['properties']['title'] ) ) {
    12311407            add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
     1408
    12321409            $data['title'] = array(
    12331410                'raw'      => $post->post_title,
    12341411                'rendered' => get_the_title( $post->ID ),
    12351412            );
     1413
    12361414            remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
    12371415        }
    12381416
    12391417        $has_password_filter = false;
     1418
    12401419        if ( $this->can_access_password_content( $post, $request ) ) {
    12411420            // Allow access to the post, permissions already checked before.
    12421421            add_filter( 'post_password_required', '__return_false' );
     1422
    12431423            $has_password_filter = true;
    12441424        }
     
    13061486        if ( ! empty( $schema['properties']['format'] ) ) {
    13071487            $data['format'] = get_post_format( $post->ID );
     1488
    13081489            // Fill in blank post format.
    13091490            if ( empty( $data['format'] ) ) {
     
    13171498
    13181499        $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     1500
    13191501        foreach ( $taxonomies as $taxonomy ) {
    13201502            $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     1503
    13211504            if ( ! empty( $schema['properties'][ $base ] ) ) {
    13221505                $terms = get_the_terms( $post, $taxonomy->name );
     
    13261509
    13271510        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
    1328         $data = $this->add_additional_fields_to_object( $data, $request );
    1329         $data = $this->filter_response_by_context( $data, $context );
     1511        $data    = $this->add_additional_fields_to_object( $data, $request );
     1512        $data    = $this->filter_response_by_context( $data, $context );
    13301513
    13311514        // Wrap the data in a response object.
     
    13351518
    13361519        /**
    1337          * Filter the post data for a response.
    1338          *
    1339          * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
    1340          * prepared for the response.
    1341          *
    1342          * @param WP_REST_Response   $response   The response object.
    1343          * @param WP_Post            $post       Post object.
    1344          * @param WP_REST_Request    $request    Request object.
     1520         * Filters the post data for a response.
     1521         *
     1522         * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
     1523         *
     1524         * @since 4.7.0
     1525         *
     1526         * @param WP_REST_Response $response The response object.
     1527         * @param WP_Post          $post     Post object.
     1528         * @param WP_REST_Request  $request  Request object.
    13451529         */
    13461530        return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request );
     
    13481532
    13491533    /**
    1350      * Overwrite the default protected title format.
    1351      *
    1352      * By default WordPress will show password protected posts with a title of
     1534     * Overwrites the default protected title format.
     1535     *
     1536     * By default, WordPress will show password protected posts with a title of
    13531537     * "Protected: %s", as the REST API communicates the protected status of a post
    13541538     * in a machine readable format, we remove the "Protected: " prefix.
    13551539     *
    1356      * @return string
     1540     * @return string Protected title format.
    13571541     */
    13581542    public function protected_title_format() {
     
    13611545
    13621546    /**
    1363      * Prepare links for the request.
     1547     * Prepares links for the request.
     1548     *
     1549     * @since 4.7.0
     1550     * @access protected
    13641551     *
    13651552     * @param WP_Post $post Post object.
     
    13931580            $replies_url = rest_url( 'wp/v2/comments' );
    13941581            $replies_url = add_query_arg( 'post', $post->ID, $replies_url );
     1582
    13951583            $links['replies'] = array(
    1396                 'href'         => $replies_url,
    1397                 'embeddable'   => true,
     1584                'href'       => $replies_url,
     1585                'embeddable' => true,
    13981586            );
    13991587        }
     
    14041592            );
    14051593        }
     1594
    14061595        $post_type_obj = get_post_type_object( $post->post_type );
     1596
    14071597        if ( $post_type_obj->hierarchical && ! empty( $post->post_parent ) ) {
    14081598            $links['up'] = array(
     
    14151605        if ( $featured_media = get_post_thumbnail_id( $post->ID ) ) {
    14161606            $image_url = rest_url( 'wp/v2/media/' . $featured_media );
     1607
    14171608            $links['https://api.w.org/featuredmedia'] = array(
    14181609                'href'       => $image_url,
     
    14201611            );
    14211612        }
     1613
    14221614        if ( ! in_array( $post->post_type, array( 'attachment', 'nav_menu_item', 'revision' ), true ) ) {
    14231615            $attachments_url = rest_url( 'wp/v2/media' );
    14241616            $attachments_url = add_query_arg( 'parent', $post->ID, $attachments_url );
     1617
    14251618            $links['https://api.w.org/attachment'] = array(
    1426                 'href'       => $attachments_url,
     1619                'href' => $attachments_url,
    14271620            );
    14281621        }
    14291622
    14301623        $taxonomies = get_object_taxonomies( $post->post_type );
     1624
    14311625        if ( ! empty( $taxonomies ) ) {
    14321626            $links['https://api.w.org/term'] = array();
     
    14341628            foreach ( $taxonomies as $tax ) {
    14351629                $taxonomy_obj = get_taxonomy( $tax );
     1630
    14361631                // Skip taxonomies that are not public.
    14371632                if ( empty( $taxonomy_obj->show_in_rest ) ) {
     
    14401635
    14411636                $tax_base = ! empty( $taxonomy_obj->rest_base ) ? $taxonomy_obj->rest_base : $tax;
     1637
    14421638                $terms_url = add_query_arg(
    14431639                    'post',
     
    14581654
    14591655    /**
    1460      * Get the Post's schema, conforming to JSON Schema.
    1461      *
    1462      * @return array
     1656     * Retrieves the post's schema, conforming to JSON Schema.
     1657     *
     1658     * @since 4.7.0
     1659     * @access public
     1660     *
     1661     * @return array Item schema data.
    14631662     */
    14641663    public function get_item_schema() {
     
    14681667            'title'      => $this->post_type,
    14691668            'type'       => 'object',
    1470             /*
    1471              * Base properties for every Post.
    1472              */
     1669            // Base properties for every Post.
    14731670            'properties' => array(
    14741671                'date'            => array(
     
    15551752
    15561753        $post_type_obj = get_post_type_object( $this->post_type );
     1754
    15571755        if ( $post_type_obj->hierarchical ) {
    15581756            $schema['properties']['parent'] = array(
     
    17871985
    17881986    /**
    1789      * Get the query params for collections of attachments.
    1790      *
    1791      * @return array
     1987     * Retrieves the query params for the posts collection.
     1988     *
     1989     * @since 4.7.0
     1990     * @access public
     1991     *
     1992     * @return array Collection parameters.
    17921993     */
    17931994    public function get_collection_params() {
     
    18022003            'validate_callback'  => 'rest_validate_request_arg',
    18032004        );
     2005
    18042006        if ( post_type_supports( $this->post_type, 'author' ) ) {
    18052007            $params['author'] = array(
     
    18162018            );
    18172019        }
     2020
    18182021        $params['before'] = array(
    18192022            'description'        => __( 'Limit response to resources published before a given ISO8601 compliant date.' ),
     
    18222025            'validate_callback'  => 'rest_validate_request_arg',
    18232026        );
     2027
    18242028        $params['exclude'] = array(
    18252029            'description'        => __( 'Ensure result set excludes specific ids.' ),
     
    18282032            'sanitize_callback'  => 'wp_parse_id_list',
    18292033        );
     2034
    18302035        $params['include'] = array(
    18312036            'description'        => __( 'Limit result set to specific ids.' ),
     
    18342039            'sanitize_callback'  => 'wp_parse_id_list',
    18352040        );
     2041
    18362042        if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
    18372043            $params['menu_order'] = array(
     
    18422048            );
    18432049        }
     2050
    18442051        $params['offset'] = array(
    18452052            'description'        => __( 'Offset the result set by a specific number of items.' ),
     
    18482055            'validate_callback'  => 'rest_validate_request_arg',
    18492056        );
     2057
    18502058        $params['order'] = array(
    18512059            'description'        => __( 'Order sort attribute ascending or descending.' ),
     
    18552063            'validate_callback'  => 'rest_validate_request_arg',
    18562064        );
     2065
    18572066        $params['orderby'] = array(
    18582067            'description'        => __( 'Sort collection by object attribute.' ),
     
    18692078            'validate_callback'  => 'rest_validate_request_arg',
    18702079        );
     2080
    18712081        if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
    18722082            $params['orderby']['enum'][] = 'menu_order';
     
    18742084
    18752085        $post_type_obj = get_post_type_object( $this->post_type );
     2086
    18762087        if ( $post_type_obj->hierarchical || 'attachment' === $this->post_type ) {
    18772088            $params['parent'] = array(
     
    18942105            'validate_callback' => 'rest_validate_request_arg',
    18952106        );
     2107
    18962108        $params['status'] = array(
    18972109            'default'           => 'publish',
     
    19042116
    19052117        $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     2118
    19062119        foreach ( $taxonomies as $taxonomy ) {
    19072120            $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     
    19272140
    19282141    /**
    1929      * Validate whether the user can query private statuses.
     2142     * Validates whether the user can query private statuses.
     2143     *
     2144     * @since 4.7.0
     2145     * @access public
    19302146     *
    19312147     * @param  mixed           $value     Post status.
    19322148     * @param  WP_REST_Request $request   Full details about the request.
    1933      * @param  string          $parameter
    1934      * @return WP_Error|boolean
     2149     * @param  string          $parameter Additional parameter to pass to validation.
     2150     * @return bool|WP_Error Whether the request can query private statuses, otherwise WP_Error object.
    19352151     */
    19362152    public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
     
    19382154            return rest_validate_request_arg( $value, $request, $parameter );
    19392155        }
     2156
    19402157        $post_type_obj = get_post_type_object( $this->post_type );
     2158
    19412159        if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
    19422160            return rest_validate_request_arg( $value, $request, $parameter );
    19432161        }
     2162
    19442163        return new WP_Error( 'rest_forbidden_status', __( 'Status is forbidden.' ), array( 'status' => rest_authorization_required_code() ) );
    19452164    }
Note: See TracChangeset for help on using the changeset viewer.