Make WordPress Core


Ignore:
Timestamp:
10/10/2023 02:03:03 PM (20 months ago)
Author:
spacedmonkey
Message:

REST API: Fix issue with Template and Template Part Revision/Autosave REST API controllers.

The Template and Template Part REST API controllers have unique characteristics compared to other post type REST API controllers. They do not rely on integer IDs to reference objects; instead, they use a combination of the theme name and slug of the template, like 'twentytwentyfourhome.' Consequently, when the post types template and template part were introduced in [52062], it led to the registration of REST API endpoints for autosaves and revisions with invalid URL structures.

In this commit, we introduce new functionality to enable custom autosave and revisions endpoints to be registered at the post type level. Similar to the 'rest_controller_class' parameter, developers can now define 'revisions_rest_controller' and 'autosave_rest_controller.' This empowers developers to create custom controllers for these functionalities. Additionally, we introduce a 'late_route_registration' parameter, which proves helpful when dealing with custom URL patterns and regex pattern matching issues.
This commit registers new classes for template and template part autosave and revisions controllers, differentiating them from standard controllers in the following ways:

  • The response shape now matches that of the template controller.
  • Permission checks align with the template controller.
  • A custom URL pattern is introduced to support slug-based identification of templates.

Furthermore, we've updated the utility function '_build_block_template_result_from_post' to support passing revision post objects. This enhancement ensures compatibility with the custom revisions controller.

Props spacedmonkey, revgeorge, andraganescu, hellofromTonya, antonvlasenko, kadamwhite, ironprogrammer, costdev, mukesh27, timothyblynjacobs, adamsilverstein.
Fixes 56922.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-post-type.php

    r56515 r56819  
    396396     */
    397397    public $rest_controller;
     398
     399    /**
     400     * The controller for this post type's revisions REST API endpoints.
     401     *
     402     * Custom controllers must extend WP_REST_Controller.
     403     *
     404     * @since 6.4.0
     405     * @var string|bool $revisions_rest_controller_class
     406     */
     407    public $revisions_rest_controller_class;
     408
     409    /**
     410     * The controller instance for this post type's revisions REST API endpoints.
     411     *
     412     * Lazily computed. Should be accessed using {@see WP_Post_Type::get_revisions_rest_controller()}.
     413     *
     414     * @since 6.4.0
     415     * @var WP_REST_Controller $revisions_rest_controller
     416     */
     417    public $revisions_rest_controller;
     418
     419    /**
     420     * The controller for this post type's autosave REST API endpoints.
     421     *
     422     * Custom controllers must extend WP_REST_Controller.
     423     *
     424     * @since 6.4.0
     425     * @var string|bool $autosave_rest_controller_class
     426     */
     427    public $autosave_rest_controller_class;
     428
     429    /**
     430     * The controller instance for this post type's autosave REST API endpoints.
     431     *
     432     * Lazily computed. Should be accessed using {@see WP_Post_Type::get_autosave_rest_controller()}.
     433     *
     434     * @since 6.4.0
     435     * @var WP_REST_Controller $autosave_rest_controller
     436     */
     437    public $autosave_rest_controller;
     438
     439    /**
     440     * A flag to register the post type REST API controller after its associated autosave / revisions controllers, instead of before. Registration order affects route matching priority.
     441     *
     442     * @since 6.4.0
     443     * @var bool $late_route_registration
     444     */
     445    public $late_route_registration;
    398446
    399447    /**
     
    456504         *
    457505         * @since 6.0.0
     506         * @since 6.4.0 Added `late_route_registration`, `autosave_rest_controller_class` and `revisions_rest_controller_class` arguments.
    458507         *
    459508         * @param array  $args      Array of arguments for registering a post type.
     
    467516        // Args prefixed with an underscore are reserved for internal use.
    468517        $defaults = array(
    469             'labels'                => array(),
    470             'description'           => '',
    471             'public'                => false,
    472             'hierarchical'          => false,
    473             'exclude_from_search'   => null,
    474             'publicly_queryable'    => null,
    475             'show_ui'               => null,
    476             'show_in_menu'          => null,
    477             'show_in_nav_menus'     => null,
    478             'show_in_admin_bar'     => null,
    479             'menu_position'         => null,
    480             'menu_icon'             => null,
    481             'capability_type'       => 'post',
    482             'capabilities'          => array(),
    483             'map_meta_cap'          => null,
    484             'supports'              => array(),
    485             'register_meta_box_cb'  => null,
    486             'taxonomies'            => array(),
    487             'has_archive'           => false,
    488             'rewrite'               => true,
    489             'query_var'             => true,
    490             'can_export'            => true,
    491             'delete_with_user'      => null,
    492             'show_in_rest'          => false,
    493             'rest_base'             => false,
    494             'rest_namespace'        => false,
    495             'rest_controller_class' => false,
    496             'template'              => array(),
    497             'template_lock'         => false,
    498             '_builtin'              => false,
    499             '_edit_link'            => 'post.php?post=%d',
     518            'labels'                          => array(),
     519            'description'                     => '',
     520            'public'                          => false,
     521            'hierarchical'                    => false,
     522            'exclude_from_search'             => null,
     523            'publicly_queryable'              => null,
     524            'show_ui'                         => null,
     525            'show_in_menu'                    => null,
     526            'show_in_nav_menus'               => null,
     527            'show_in_admin_bar'               => null,
     528            'menu_position'                   => null,
     529            'menu_icon'                       => null,
     530            'capability_type'                 => 'post',
     531            'capabilities'                    => array(),
     532            'map_meta_cap'                    => null,
     533            'supports'                        => array(),
     534            'register_meta_box_cb'            => null,
     535            'taxonomies'                      => array(),
     536            'has_archive'                     => false,
     537            'rewrite'                         => true,
     538            'query_var'                       => true,
     539            'can_export'                      => true,
     540            'delete_with_user'                => null,
     541            'show_in_rest'                    => false,
     542            'rest_base'                       => false,
     543            'rest_namespace'                  => false,
     544            'rest_controller_class'           => false,
     545            'autosave_rest_controller_class'  => false,
     546            'revisions_rest_controller_class' => false,
     547            'late_route_registration'         => false,
     548            'template'                        => array(),
     549            'template_lock'                   => false,
     550            '_builtin'                        => false,
     551            '_edit_link'                      => 'post.php?post=%d',
    500552        );
    501553
     
    815867
    816868        return $this->rest_controller;
     869    }
     870
     871    /**
     872     * Gets the REST API revisions controller for this post type.
     873     *
     874     * Will only instantiate the controller class once per request.
     875     *
     876     * @since 6.4.0
     877     *
     878     * @return WP_REST_Controller|null The controller instance, or null if the post type
     879     *                                 is set not to show in rest.
     880     */
     881    public function get_revisions_rest_controller() {
     882        if ( ! $this->show_in_rest ) {
     883            return null;
     884        }
     885
     886        if ( ! post_type_supports( $this->name, 'revisions' ) ) {
     887            return null;
     888        }
     889
     890        $class = $this->revisions_rest_controller_class ? $this->revisions_rest_controller_class : WP_REST_Revisions_Controller::class;
     891        if ( ! class_exists( $class ) ) {
     892            return null;
     893        }
     894
     895        if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) {
     896            return null;
     897        }
     898
     899        if ( ! $this->revisions_rest_controller ) {
     900            $this->revisions_rest_controller = new $class( $this->name );
     901        }
     902
     903        if ( ! ( $this->revisions_rest_controller instanceof $class ) ) {
     904            return null;
     905        }
     906
     907        return $this->revisions_rest_controller;
     908    }
     909
     910    /**
     911     * Gets the REST API autosave controller for this post type.
     912     *
     913     * Will only instantiate the controller class once per request.
     914     *
     915     * @since 6.4.0
     916     *
     917     * @return WP_REST_Controller|null The controller instance, or null if the post type
     918     *                                 is set not to show in rest.
     919     */
     920    public function get_autosave_rest_controller() {
     921        if ( ! $this->show_in_rest ) {
     922            return null;
     923        }
     924
     925        if ( 'attachment' === $this->name ) {
     926            return null;
     927        }
     928
     929        $class = $this->autosave_rest_controller_class ? $this->autosave_rest_controller_class : WP_REST_Autosaves_Controller::class;
     930
     931        if ( ! class_exists( $class ) ) {
     932            return null;
     933        }
     934
     935        if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) {
     936            return null;
     937        }
     938
     939        if ( ! $this->autosave_rest_controller ) {
     940            $this->autosave_rest_controller = new $class( $this->name );
     941        }
     942
     943        if ( ! ( $this->autosave_rest_controller instanceof $class ) ) {
     944            return null;
     945        }
     946
     947        return $this->autosave_rest_controller;
    817948    }
    818949
Note: See TracChangeset for help on using the changeset viewer.