WordPress.org

Make WordPress Core

Ticket #45677: 45677.10.diff

File 45677.10.diff, 8.9 KB (added by TimothyBlynJacobs, 17 months ago)
  • src/wp-includes/class-wp-post-type.php

    diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php
    index faf7a0d496..0099515050 100644
    a b final class WP_Post_Type { 
    335335         */
    336336        public $rest_controller_class;
    337337
     338        /**
     339         * The controller instance for this post type's REST API endpoints.
     340         *
     341         * Lazily computed. Should be accessed using {@see WP_Post_Type::get_rest_controller()}.
     342         *
     343         * @since 5.3.0
     344         * @var WP_REST_Controller $rest_controller
     345         */
     346        private $rest_controller;
     347
    338348        /**
    339349         * Constructor.
    340350         *
    final class WP_Post_Type { 
    682692        public function remove_hooks() {
    683693                remove_action( 'future_' . $this->name, '_future_post_hook', 5 );
    684694        }
     695
     696        /**
     697         * Gets the REST API controller for this post type.
     698         *
     699         * Will only instantiate the controller class once per request.
     700         *
     701         * @since 5.3.0
     702         *
     703         * @return WP_REST_Controller|null The controller instance, or null if the post type
     704         *                                 is set not to show in rest.
     705         */
     706        public function get_rest_controller() {
     707                if ( ! $this->show_in_rest ) {
     708                        return null;
     709                }
     710
     711                $class = $this->rest_controller_class ? $this->rest_controller_class : WP_REST_Posts_Controller::class;
     712
     713                if ( ! class_exists( $class ) ) {
     714                        return null;
     715                }
     716
     717                if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) {
     718                        return null;
     719                }
     720
     721                if ( ! $this->rest_controller ) {
     722                        $this->rest_controller = new $class( $this->name );
     723                }
     724
     725                return $this->rest_controller;
     726        }
    685727}
  • src/wp-includes/rest-api.php

    diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
    index a0bb8fba3a..c397bdc116 100644
    a b function rest_api_default_filters() { 
    192192 */
    193193function create_initial_rest_routes() {
    194194        foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
    195                 $class = ! empty( $post_type->rest_controller_class ) ? $post_type->rest_controller_class : 'WP_REST_Posts_Controller';
     195                $controller = $post_type->get_rest_controller();
    196196
    197                 if ( ! class_exists( $class ) ) {
    198                         continue;
    199                 }
    200                 $controller = new $class( $post_type->name );
    201                 if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) {
     197                if ( ! $controller ) {
    202198                        continue;
    203199                }
    204200
  • src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
    index 7b2e4b223c..a72541a1ee 100644
    a b class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { 
    5959        public function __construct( $parent_post_type ) {
    6060                $this->parent_post_type = $parent_post_type;
    6161                $post_type_object       = get_post_type_object( $parent_post_type );
     62                $parent_controller      = $post_type_object->get_rest_controller();
    6263
    63                 // Ensure that post type-specific controller logic is available.
    64                 $parent_controller_class = ! empty( $post_type_object->rest_controller_class ) ? $post_type_object->rest_controller_class : 'WP_REST_Posts_Controller';
     64                if ( ! $parent_controller ) {
     65                        $parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
     66                }
    6567
    66                 $this->parent_controller    = new $parent_controller_class( $post_type_object->name );
     68                $this->parent_controller    = $parent_controller;
    6769                $this->revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
    6870                $this->rest_namespace       = 'wp/v2';
    6971                $this->rest_base            = 'autosaves';
  • src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
    index f2ead89ea0..2c87be8b9a 100644
    a b class WP_REST_Comments_Controller extends WP_REST_Controller { 
    15921592         * @return bool Whether post can be read.
    15931593         */
    15941594        protected function check_read_post_permission( $post, $request ) {
    1595                 $posts_controller = new WP_REST_Posts_Controller( $post->post_type );
    15961595                $post_type        = get_post_type_object( $post->post_type );
     1596                $posts_controller = $post_type->get_rest_controller();
     1597
     1598                // We need to specifically assert that the posts controller is a WP_REST_Posts_Controller instance,
     1599                // and not just check that we have a valid controller as we use Posts Controller specific methods.
     1600                if ( ! $posts_controller instanceof WP_REST_Posts_Controller ) {
     1601                        $posts_controller = new WP_REST_Posts_Controller( $post->post_type );
     1602                }
    15971603
    15981604                $has_password_filter = false;
    15991605
  • src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
    index d355c3d076..4a00336e34 100644
    a b  
    1616 */
    1717class WP_REST_Posts_Controller extends WP_REST_Controller {
    1818
     19        /**
     20         * Instances of post type controllers keyed by post type.
     21         *
     22         * @since 5.3.0
     23         * @var WP_REST_Controller[]
     24         */
     25        private static $post_type_controllers = array();
     26
    1927        /**
    2028         * Post type.
    2129         *
  • src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
    index 97c677d27c..9edf6eced6 100644
    a b class WP_REST_Revisions_Controller extends WP_REST_Controller { 
    4949         */
    5050        public function __construct( $parent_post_type ) {
    5151                $this->parent_post_type  = $parent_post_type;
    52                 $this->parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
    5352                $this->namespace         = 'wp/v2';
    5453                $this->rest_base         = 'revisions';
    5554                $post_type_object        = get_post_type_object( $parent_post_type );
    5655                $this->parent_base       = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
     56                $this->parent_controller = $post_type_object->get_rest_controller();
     57
     58                if ( ! $this->parent_controller ) {
     59                        $this->parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
     60                }
    5761        }
    5862
    5963        /**
  • tests/phpunit/tests/rest-api/rest-posts-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php
    index 10d5a1e3a2..2dcbf81a6f 100644
    a b class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te 
    45264526                $this->assertNotEquals( '0000-00-00 00:00:00', get_post( $post->ID )->post_date_gmt );
    45274527        }
    45284528
     4529        /**
     4530         * @ticket 45677
     4531         */
     4532        public function test_get_for_post_type_reuses_same_instance() {
     4533                $this->assertSame(
     4534                        get_post_type_object( 'post' )->get_rest_controller(),
     4535                        get_post_type_object( 'post' )->get_rest_controller()
     4536                );
     4537        }
     4538
     4539        /**
     4540         * @ticket 45677
     4541         */
     4542        public function test_get_for_post_type_returns_null_if_post_type_does_not_show_in_rest() {
     4543                register_post_type(
     4544                        'not_in_rest',
     4545                        array(
     4546                                'show_in_rest' => false,
     4547                        )
     4548                );
     4549
     4550                $this->assertNull( get_post_type_object( 'not_in_rest' )->get_rest_controller() );
     4551        }
     4552
     4553        /**
     4554         * @ticket 45677
     4555         */
     4556        public function test_get_for_post_type_returns_null_if_class_does_not_exist() {
     4557                register_post_type(
     4558                        'class_not_found',
     4559                        array(
     4560                                'show_in_rest'          => true,
     4561                                'rest_controller_class' => 'Class_That_Does_Not_Exist',
     4562                        )
     4563                );
     4564
     4565                $this->assertNull( get_post_type_object( 'class_not_found' )->get_rest_controller() );
     4566        }
     4567
     4568        /**
     4569         * @ticket 45677
     4570         */
     4571        public function test_get_for_post_type_returns_null_if_class_does_not_subclass_rest_controller() {
     4572                register_post_type(
     4573                        'invalid_class',
     4574                        array(
     4575                                'show_in_rest'          => true,
     4576                                'rest_controller_class' => 'WP_Post',
     4577                        ),
     4578                );
     4579
     4580                $this->assertNull( get_post_type_object( 'invalid_class' )->get_rest_controller() );
     4581        }
     4582
     4583        /**
     4584         * @ticket 45677
     4585         */
     4586        public function test_get_for_post_type_returns_posts_controller_if_custom_class_not_specified() {
     4587                register_post_type(
     4588                        'test',
     4589                        array(
     4590                                'show_in_rest' => true,
     4591                        )
     4592                );
     4593
     4594                $this->assertInstanceOf(
     4595                        WP_REST_Posts_Controller::class,
     4596                        get_post_type_object( 'test' )->get_rest_controller()
     4597                );
     4598        }
     4599
     4600        /**
     4601         * @ticket 45677
     4602         */
     4603        public function test_get_for_post_type_returns_provided_controller_class() {
     4604                $this->assertInstanceOf(
     4605                        WP_REST_Blocks_Controller::class,
     4606                        get_post_type_object( 'wp_block' )->get_rest_controller()
     4607                );
     4608        }
     4609
    45294610        public function tearDown() {
    45304611                _unregister_post_type( 'private-post' );
    45314612                _unregister_post_type( 'youseeme' );