Make WordPress Core


Ignore:
Timestamp:
07/11/2018 06:22:10 AM (8 years ago)
Author:
pento
Message:

REST API: Declare user capabilities using JSON Hyper Schema's "targetSchema".

There are a variety of operations a WordPress user can only perform if they have the correct capabilities. A REST API client should only display UI for one of these operations if the WordPress user can perform the operation.

Rather than requiring REST API clients to calculate whether to display UI based on potentially complicated combinations of user capabilities, targetSchema allows us to expose a single flag to show whether the corresponding UI should be displayed.

This change also includes flags on post objects for the following actions:

  • action-publish: The current user can publish this post.
  • action-sticky: The current user can make this post sticky, and the post type supports sticking.
  • `action-assign-author': The current user can change the author on this post.
  • action-assign-{$taxonomy}: The current user can assign terms from the "$taxonomy" taxonomy to this post.
  • action-create-{$taxonomy}: The current user can create terms int the "$taxonomy" taxonomy.

Props TimothyBlynJacobs, danielbachhuber.
Fixes #44287.

File:
1 edited

Legend:

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

    r43087 r43437  
    15911591                $response = rest_ensure_response( $data );
    15921592
    1593                 $response->add_links( $this->prepare_links( $post ) );
     1593                $links = $this->prepare_links( $post );
     1594                $response->add_links( $links );
     1595
     1596                if ( ! empty( $links['self']['href'] ) ) {
     1597                        $actions = $this->get_available_actions( $post, $request );
     1598
     1599                        $self = $links['self']['href'];
     1600
     1601                        foreach ( $actions as $rel ) {
     1602                                $response->add_link( $rel, $self );
     1603                        }
     1604                }
    15941605
    15951606                /**
     
    17281739
    17291740                return $links;
     1741        }
     1742
     1743        /**
     1744         * Get the link relations available for the post and current user.
     1745         *
     1746         * @since 4.9.7
     1747         *
     1748         * @param WP_Post $post Post object.
     1749         * @param WP_REST_Request Request object.
     1750         *
     1751         * @return array List of link relations.
     1752         */
     1753        protected function get_available_actions( $post, $request ) {
     1754
     1755                if ( 'edit' !== $request['context'] ) {
     1756                        return array();
     1757                }
     1758
     1759                $rels = array();
     1760
     1761                $post_type = get_post_type_object( $post->post_type );
     1762
     1763                if ( 'attachment' !== $this->post_type && current_user_can( $post_type->cap->publish_posts ) ) {
     1764                        $rels[] = 'https://api.w.org/action-publish';
     1765                }
     1766
     1767                if ( 'post' === $post_type->name ) {
     1768                        if ( current_user_can( $post_type->cap->edit_others_posts ) && current_user_can( $post_type->cap->publish_posts ) ) {
     1769                                $rels[] = 'https://api.w.org/action-sticky';
     1770                        }
     1771                }
     1772
     1773                if ( post_type_supports( $post_type->name, 'author' ) ) {
     1774                        if ( current_user_can( $post_type->cap->edit_others_posts ) ) {
     1775                                $rels[] = 'https://api.w.org/action-assign-author';
     1776                        }
     1777                }
     1778
     1779                $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     1780
     1781                foreach ( $taxonomies as $tax ) {
     1782                        $tax_base   = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name;
     1783                        $create_cap = is_taxonomy_hierarchical( $tax->name ) ? $tax->cap->edit_terms : $tax->cap->assign_terms;
     1784
     1785                        if ( current_user_can( $create_cap ) ) {
     1786                                $rels[] = 'https://api.w.org/action-create-' . $tax_base;
     1787                        }
     1788
     1789                        if ( current_user_can( $tax->cap->assign_terms ) ) {
     1790                                $rels[] = 'https://api.w.org/action-assign-' . $tax_base;
     1791                        }
     1792                }
     1793
     1794                return $rels;
    17301795        }
    17311796
     
    20702135                }
    20712136
     2137                $schema_links = $this->get_schema_links();
     2138
     2139                if ( $schema_links ) {
     2140                        $schema['links'] = $schema_links;
     2141                }
     2142
    20722143                return $this->add_additional_fields_schema( $schema );
     2144        }
     2145
     2146        /**
     2147         * Retrieve Link Description Objects that should be added to the Schema for the posts collection.
     2148         *
     2149         * @since 4.9.7
     2150         *
     2151         * @return array
     2152         */
     2153        protected function get_schema_links() {
     2154
     2155                $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
     2156
     2157                $links = array();
     2158
     2159                if ( 'attachment' !== $this->post_type ) {
     2160                        $links[] = array(
     2161                                'rel'          => 'https://api.w.org/action-publish',
     2162                                'title'        => __( 'The current user can publish this post.' ),
     2163                                'href'         => $href,
     2164                                'targetSchema' => array(
     2165                                        'type'       => 'object',
     2166                                        'properties' => array(
     2167                                                'status' => array(
     2168                                                        'type' => 'string',
     2169                                                        'enum' => array( 'publish', 'future' ),
     2170                                                ),
     2171                                        ),
     2172                                ),
     2173                        );
     2174                }
     2175
     2176                if ( 'post' === $this->post_type ) {
     2177                        $links[] = array(
     2178                                'rel'          => 'https://api.w.org/action-sticky',
     2179                                'title'        => __( 'The current user can sticky this post.' ),
     2180                                'href'         => $href,
     2181                                'targetSchema' => array(
     2182                                        'type'       => 'object',
     2183                                        'properties' => array(
     2184                                                'sticky' => array(
     2185                                                        'type' => 'boolean',
     2186                                                ),
     2187                                        ),
     2188                                ),
     2189                        );
     2190                }
     2191
     2192                if ( post_type_supports( $this->post_type, 'author' ) ) {
     2193                        $links[] = array(
     2194                                'rel'          => 'https://api.w.org/action-assign-author',
     2195                                'title'        => __( 'The current user can change the author on this post.' ),
     2196                                'href'         => $href,
     2197                                'targetSchema' => array(
     2198                                        'type'       => 'object',
     2199                                        'properties' => array(
     2200                                                'author' => array(
     2201                                                        'type' => 'integer',
     2202                                                ),
     2203                                        ),
     2204                                ),
     2205                        );
     2206                }
     2207
     2208                $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     2209
     2210                foreach ( $taxonomies as $tax ) {
     2211                        $tax_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name;
     2212
     2213                        /* translators: %s: taxonomy name */
     2214                        $assign_title = sprintf( __( 'The current user can assign terms in the %s taxonomy.' ), $tax->name );
     2215                        /* translators: %s: taxonomy name */
     2216                        $create_title = sprintf( __( 'The current user can create terms in the %s taxonomy.' ), $tax->name );
     2217
     2218                        $links[] = array(
     2219                                'rel'          => 'https://api.w.org/action-assign-' . $tax_base,
     2220                                'title'        => $assign_title,
     2221                                'href'         => $href,
     2222                                'targetSchema' => array(
     2223                                        'type'       => 'object',
     2224                                        'properties' => array(
     2225                                                $tax_base => array(
     2226                                                        'type'  => 'array',
     2227                                                        'items' => array(
     2228                                                                'type' => 'integer',
     2229                                                        ),
     2230                                                ),
     2231                                        ),
     2232                                ),
     2233                        );
     2234
     2235                        $links[] = array(
     2236                                'rel'          => 'https://api.w.org/action-create-' . $tax_base,
     2237                                'title'        => $create_title,
     2238                                'href'         => $href,
     2239                                'targetSchema' => array(
     2240                                        'type'       => 'object',
     2241                                        'properties' => array(
     2242                                                $tax_base => array(
     2243                                                        'type'  => 'array',
     2244                                                        'items' => array(
     2245                                                                'type' => 'integer',
     2246                                                        ),
     2247                                                ),
     2248                                        ),
     2249                                ),
     2250                        );
     2251                }
     2252
     2253                return $links;
    20732254        }
    20742255
Note: See TracChangeset for help on using the changeset viewer.