Make WordPress Core

Ticket #44287: 44287.1.patch

File 44287.1.patch, 20.1 KB (added by TimothyBlynJacobs, 5 years ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    368368
    369369                $data = $this->filter_response_by_context( $data, $context );
    370370
     371                $links = $response->get_links();
     372
    371373                // Wrap the data in a response object.
    372374                $response = rest_ensure_response( $data );
    373 
    374                 $response->add_links( $this->prepare_links( $post ) );
     375                $response->add_links( $links );
    375376
    376377                /**
    377378                 * Filters an attachment returned from the REST API.
  • src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    15901590                // Wrap the data in a response object.
    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                /**
    15961607                 * Filters the post data for a response.
     
    17291740                return $links;
    17301741        }
    17311742
     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;
     1795        }
     1796
    17321797        /**
    17331798         * Retrieves the post's schema, conforming to JSON Schema.
    17341799         *
     
    20692134                        );
    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 );
    20732144        }
    20742145
     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                        $links[] = array(
     2214                                'rel'          => 'https://api.w.org/action-assign-' . $tax_base,
     2215                                'title'        => sprintf( __( 'The current user can assign terms in the %s taxonomy.' ), $tax->name ),
     2216                                'href'         => $href,
     2217                                'targetSchema' => array(
     2218                                        'type'       => 'object',
     2219                                        'properties' => array(
     2220                                                $tax_base => array(
     2221                                                        'type'  => 'array',
     2222                                                        'items' => array(
     2223                                                                'type' => 'integer',
     2224                                                        ),
     2225                                                ),
     2226                                        ),
     2227                                ),
     2228                        );
     2229
     2230                        $links[] = array(
     2231                                'rel'          => 'https://api.w.org/action-create-' . $tax_base,
     2232                                'title'        => sprintf( __( 'The current user can create terms in the %s taxonomy.' ), $tax->name ),
     2233                                'href'         => $href,
     2234                                'targetSchema' => array(
     2235                                        'type'       => 'object',
     2236                                        'properties' => array(
     2237                                                $tax_base => array(
     2238                                                        'type'  => 'array',
     2239                                                        'items' => array(
     2240                                                                'type' => 'integer',
     2241                                                        ),
     2242                                                ),
     2243                                        ),
     2244                                ),
     2245                        );
     2246                }
     2247
     2248                return $links;
     2249        }
     2250
    20752251        /**
    20762252         * Retrieves the query params for the posts collection.
    20772253         *
  • tests/phpunit/tests/rest-api/rest-posts-controller.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    36403640                update_post_meta( $post->ID, 'my_custom_int', $value );
    36413641        }
    36423642
     3643        public function test_publish_action_ldo_registered() {
     3644
     3645                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3646                $data     = $response->get_data();
     3647                $schema   = $data['schema'];
     3648
     3649                $this->assertArrayHasKey( 'links', $schema );
     3650                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-publish' ) );
     3651
     3652                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3653        }
     3654
     3655        public function test_sticky_action_ldo_registered_for_posts() {
     3656
     3657                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3658                $data     = $response->get_data();
     3659                $schema   = $data['schema'];
     3660
     3661                $this->assertArrayHasKey( 'links', $schema );
     3662                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3663
     3664                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3665        }
     3666
     3667        public function test_sticky_action_ldo_not_registered_for_non_posts() {
     3668
     3669                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/pages' ) );
     3670                $data     = $response->get_data();
     3671                $schema   = $data['schema'];
     3672
     3673                $this->assertArrayHasKey( 'links', $schema );
     3674                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3675
     3676                $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3677        }
     3678
     3679        public function test_author_action_ldo_registered_for_post_types_with_author_support() {
     3680
     3681                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3682                $data     = $response->get_data();
     3683                $schema   = $data['schema'];
     3684
     3685                $this->assertArrayHasKey( 'links', $schema );
     3686                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3687
     3688                $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3689        }
     3690
     3691        public function test_author_action_ldo_not_registered_for_post_types_without_author_support() {
     3692
     3693                remove_post_type_support( 'post', 'author' );
     3694
     3695                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3696                $data     = $response->get_data();
     3697                $schema   = $data['schema'];
     3698
     3699                $this->assertArrayHasKey( 'links', $schema );
     3700                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3701
     3702                $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3703        }
     3704
     3705        public function test_term_action_ldos_registered() {
     3706
     3707                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3708                $data     = $response->get_data();
     3709                $schema   = $data['schema'];
     3710
     3711                $this->assertArrayHasKey( 'links', $schema );
     3712                $rels = array_flip( wp_list_pluck( $schema['links'], 'rel' ) );
     3713
     3714                $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $rels );
     3715                $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $rels );
     3716                $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $rels );
     3717                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $rels );
     3718
     3719                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-post_format', $rels );
     3720                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $rels );
     3721                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-nav_menu', $rels );
     3722                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-nav_menu', $rels );
     3723        }
     3724
     3725        public function test_action_links_only_available_in_edit_context() {
     3726
     3727                wp_set_current_user( self::$author_id );
     3728
     3729                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3730                $this->assertGreaterThan( 0, $post );
     3731
     3732                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3733                $request->set_query_params( array( 'context' => 'view' ) );
     3734
     3735                $response = rest_get_server()->dispatch( $request );
     3736                $links = $response->get_links();
     3737
     3738                $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3739        }
     3740
     3741        public function test_publish_action_link_exists_for_author() {
     3742
     3743                wp_set_current_user( self::$author_id );
     3744
     3745                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3746                $this->assertGreaterThan( 0, $post );
     3747
     3748                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3749                $request->set_query_params( array( 'context' => 'edit' ) );
     3750
     3751                $response = rest_get_server()->dispatch( $request );
     3752                $links = $response->get_links();
     3753
     3754                $this->assertArrayHasKey( 'https://api.w.org/action-publish', $links );
     3755        }
     3756
     3757        public function test_publish_action_link_does_not_exist_for_contributor() {
     3758
     3759                wp_set_current_user( self::$contributor_id );
     3760
     3761                $post = self::factory()->post->create( array( 'post_author' => self::$contributor_id ) );
     3762                $this->assertGreaterThan( 0, $post );
     3763
     3764                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}");
     3765                $request->set_query_params( array( 'context' => 'edit' ) );
     3766
     3767                $response = rest_get_server()->dispatch( $request );
     3768                $links    = $response->get_links();
     3769
     3770                $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3771        }
     3772
     3773        public function test_sticky_action_exists_for_editor() {
     3774
     3775                wp_set_current_user( self::$editor_id );
     3776
     3777                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3778                $this->assertGreaterThan( 0, $post );
     3779
     3780                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3781                $request->set_query_params( array( 'context' => 'edit' ) );
     3782
     3783                $response = rest_get_server()->dispatch( $request );
     3784                $links    = $response->get_links();
     3785
     3786                $this->assertArrayHasKey( 'https://api.w.org/action-sticky', $links );
     3787        }
     3788
     3789        public function test_sticky_action_does_not_exist_for_author() {
     3790
     3791                wp_set_current_user( self::$author_id );
     3792
     3793                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3794                $this->assertGreaterThan( 0, $post );
     3795
     3796                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3797                $request->set_query_params( array( 'context' => 'edit' ) );
     3798
     3799                $response = rest_get_server()->dispatch( $request );
     3800                $links    = $response->get_links();
     3801
     3802                $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3803        }
     3804
     3805        public function test_sticky_action_does_not_exist_for_non_post_posts() {
     3806
     3807                wp_set_current_user( self::$editor_id );
     3808
     3809                $post = self::factory()->post->create( array( 'post_author' => self::$author_id, 'post_type' => 'page' ) );
     3810                $this->assertGreaterThan( 0, $post );
     3811
     3812                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3813                $request->set_query_params( array( 'context' => 'edit' ) );
     3814
     3815                $response = rest_get_server()->dispatch( $request );
     3816                $links    = $response->get_links();
     3817
     3818                $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3819        }
     3820
     3821
     3822        public function test_assign_author_action_exists_for_editor() {
     3823
     3824                wp_set_current_user( self::$editor_id );
     3825
     3826                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3827                $this->assertGreaterThan( 0, $post );
     3828
     3829                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3830                $request->set_query_params( array( 'context' => 'edit' ) );
     3831
     3832                $response = rest_get_server()->dispatch( $request );
     3833                $links    = $response->get_links();
     3834
     3835                $this->assertArrayHasKey( 'https://api.w.org/action-assign-author', $links );
     3836        }
     3837
     3838        public function test_assign_author_action_does_not_exist_for_author() {
     3839
     3840                wp_set_current_user( self::$author_id );
     3841
     3842                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3843                $this->assertGreaterThan( 0, $post );
     3844
     3845                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3846                $request->set_query_params( array( 'context' => 'edit' ) );
     3847
     3848                $response = rest_get_server()->dispatch( $request );
     3849                $links    = $response->get_links();
     3850
     3851                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3852        }
     3853
     3854        public function test_assign_author_action_does_not_exist_for_post_types_without_author_support() {
     3855
     3856                remove_post_type_support( 'post', 'author' );
     3857
     3858                wp_set_current_user( self::$editor_id );
     3859
     3860                $post = self::factory()->post->create();
     3861                $this->assertGreaterThan( 0, $post );
     3862
     3863                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3864                $request->set_query_params( array( 'context' => 'edit' ) );
     3865
     3866                $response = rest_get_server()->dispatch( $request );
     3867                $links    = $response->get_links();
     3868
     3869                $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3870        }
     3871
     3872        public function test_create_term_action_exists_for_editor() {
     3873
     3874                wp_set_current_user( self::$editor_id );
     3875
     3876                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3877                $this->assertGreaterThan( 0, $post );
     3878
     3879                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3880                $request->set_query_params( array( 'context' => 'edit' ) );
     3881
     3882                $response = rest_get_server()->dispatch( $request );
     3883                $links    = $response->get_links();
     3884
     3885                $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $links );
     3886                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3887                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $links );
     3888        }
     3889
     3890        public function test_create_term_action_non_hierarchical_exists_for_author() {
     3891
     3892                wp_set_current_user( self::$author_id );
     3893
     3894                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3895                $this->assertGreaterThan( 0, $post );
     3896
     3897                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3898                $request->set_query_params( array( 'context' => 'edit' ) );
     3899
     3900                $response = rest_get_server()->dispatch( $request );
     3901                $links    = $response->get_links();
     3902
     3903                $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3904        }
     3905
     3906        public function test_create_term_action_hierarchical_does_not_exists_for_author() {
     3907
     3908                wp_set_current_user( self::$author_id );
     3909
     3910                $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3911                $this->assertGreaterThan( 0, $post );
     3912
     3913                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3914                $request->set_query_params( array( 'context' => 'edit' ) );
     3915
     3916                $response = rest_get_server()->dispatch( $request );
     3917                $links    = $response->get_links();
     3918
     3919                $this->assertArrayNotHasKey( 'https://api.w.org/action-create-categories', $links );
     3920        }
     3921
     3922        public function test_assign_term_action_exists_for_contributor() {
     3923
     3924                wp_set_current_user( self::$contributor_id );
     3925
     3926                $post = self::factory()->post->create( array( 'post_author' => self::$contributor_id, 'post_status' => 'draft' ) );
     3927                $this->assertGreaterThan( 0, $post );
     3928
     3929                $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3930                $request->set_query_params( array( 'context' => 'edit' ) );
     3931
     3932                $response = rest_get_server()->dispatch( $request );
     3933                $links    = $response->get_links();
     3934
     3935                $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $links );
     3936                $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $links );
     3937        }
     3938
    36433939        public function tearDown() {
    36443940                _unregister_post_type( 'youseeeme' );
    36453941                if ( isset( $this->attachment_id ) ) {
  • tests/phpunit/tests/rest-api/rest-attachments-controller.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    13501350                }
    13511351        }
    13521352
     1353        public function test_links_exist() {
     1354
     1355                wp_set_current_user( self::$editor_id );
     1356
     1357                $post = self::factory()->attachment->create( array( 'post_author' => self::$editor_id ) );
     1358                $this->assertGreaterThan( 0, $post );
     1359
     1360                $request = new WP_REST_Request( 'GET', "/wp/v2/media/{$post}" );
     1361                $request->set_query_params( array( 'context' => 'edit' ) );
     1362
     1363                $response = rest_get_server()->dispatch( $request );
     1364                $links = $response->get_links();
     1365
     1366                $this->assertArrayHasKey( 'self', $links );
     1367        }
     1368
     1369        public function test_publish_action_ldo_not_registered() {
     1370
     1371                $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/media' ) );
     1372                $data     = $response->get_data();
     1373                $schema   = $data['schema'];
     1374
     1375                $this->assertArrayHasKey( 'links', $schema );
     1376                $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-publish' ) );
     1377
     1378                $this->assertCount( 0, $publish, 'LDO not found on schema.' );
     1379        }
     1380
     1381        public function test_publish_action_link_does_not_exists() {
     1382
     1383                wp_set_current_user( self::$editor_id );
     1384
     1385                $post = self::factory()->attachment->create( array( 'post_author' => self::$editor_id ) );
     1386                $this->assertGreaterThan( 0, $post );
     1387
     1388                $request = new WP_REST_Request( 'GET', "/wp/v2/media/{$post}" );
     1389                $request->set_query_params( array( 'context' => 'edit' ) );
     1390
     1391                $response = rest_get_server()->dispatch( $request );
     1392                $links = $response->get_links();
     1393
     1394                $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     1395        }
     1396
    13531397        public function tearDown() {
    13541398                parent::tearDown();
    13551399                if ( file_exists( $this->test_file ) ) {