Make WordPress Core


Ignore:
Timestamp:
05/28/2024 12:38:28 PM (6 months ago)
Author:
swissspidy
Message:

REST API: Refactor global styles endpoints in REST API to register with post type.

Updated the global styles endpoints in the REST API to extend from existing posts and revisions controllers. This reduces duplicated code and inconsistencies. The revisions controller is now a subclass of the WP_REST_Revisions_Controller. Related redundant methods were removed and schema generation and collection parameters were adjusted to suit the global styles context. Updated permission checks, constructor, and collection parameters accordingly. This change allows for easy override of these classes using the register_post_type_args filter.

This reintroduces [57624] (reverted in [57628]) with improved backward compatibility and further enhancements.

Props ramonopoly, spacedmonkey, mukesh27, swissspidy.
Fixes #60131.

File:
1 edited

Legend:

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

    r57648 r58225  
    1515 * @see WP_REST_Controller
    1616 */
    17 class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Controller {
     17class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Controller {
     18    /**
     19     * Parent controller.
     20     *
     21     * @since 6.6.0
     22     * @var WP_REST_Controller
     23     */
     24    private $parent_controller;
     25
     26    /**
     27     * The base of the parent controller's route.
     28     *
     29     * @since 6.3.0
     30     * @var string
     31     */
     32    protected $parent_base;
     33
    1834    /**
    1935     * Parent post type.
    2036     *
    21      * @since 6.3.0
     37     * @since 6.6.0
    2238     * @var string
    2339     */
     
    2541
    2642    /**
    27      * The base of the parent controller's route.
    28      *
    29      * @since 6.3.0
    30      * @var string
    31      */
    32     protected $parent_base;
    33 
    34     /**
    3543     * Constructor.
    3644     *
    3745     * @since 6.3.0
    38      */
    39     public function __construct() {
    40         $this->parent_post_type = 'wp_global_styles';
    41         $this->rest_base        = 'revisions';
    42         $this->parent_base      = 'global-styles';
    43         $this->namespace        = 'wp/v2';
     46     * @since 6.6.0 Extends class from WP_REST_Revisions_Controller.
     47     *
     48     * @param string $parent_post_type Post type of the parent.
     49     */
     50    public function __construct( $parent_post_type = 'wp_global_styles' ) {
     51        parent::__construct( $parent_post_type );
     52        $post_type_object  = get_post_type_object( $parent_post_type );
     53        $parent_controller = $post_type_object->get_rest_controller();
     54
     55        if ( ! $parent_controller ) {
     56            $parent_controller = new WP_REST_Global_Styles_Controller( $parent_post_type );
     57        }
     58
     59        $this->parent_controller = $parent_controller;
     60        $this->rest_base         = 'revisions';
     61        $this->parent_base       = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
     62        $this->namespace         = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
    4463    }
    4564
     
    4867     *
    4968     * @since 6.3.0
    50      * @since 6.5.0 Added route to fetch individual global styles revisions.
     69     * @since 6.6.0 Added route to fetch individual global styles revisions.
    5170     */
    5271    public function register_routes() {
     
    6483                    'methods'             => WP_REST_Server::READABLE,
    6584                    'callback'            => array( $this, 'get_items' ),
    66                     'permission_callback' => array( $this, 'get_item_permissions_check' ),
     85                    'permission_callback' => array( $this, 'get_items_permissions_check' ),
    6786                    'args'                => $this->get_collection_params(),
    6887                ),
     
    99118
    100119    /**
    101      * Retrieves the query params for collections.
    102      *
    103      * Inherits from WP_REST_Controller::get_collection_params(),
    104      * also reflects changes to return value WP_REST_Revisions_Controller::get_collection_params().
    105      *
    106      * @since 6.3.0
    107      *
    108      * @return array Collection parameters.
    109      */
    110     public function get_collection_params() {
    111         $collection_params                       = parent::get_collection_params();
    112         $collection_params['context']['default'] = 'view';
    113         $collection_params['offset']             = array(
    114             'description' => __( 'Offset the result set by a specific number of items.' ),
    115             'type'        => 'integer',
    116         );
    117         unset( $collection_params['search'] );
    118         unset( $collection_params['per_page']['default'] );
    119 
    120         return $collection_params;
    121     }
    122 
    123     /**
    124120     * Returns decoded JSON from post content string,
    125121     * or a 404 if not found.
     
    270266
    271267    /**
    272      * Retrieves one global styles revision from the collection.
    273      *
    274      * @since 6.5.0
    275      *
    276      * @param WP_REST_Request $request Full details about the request.
    277      * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    278      */
    279     public function get_item( $request ) {
    280         $parent = $this->get_parent( $request['parent'] );
    281         if ( is_wp_error( $parent ) ) {
    282             return $parent;
    283         }
    284 
    285         $revision = $this->get_revision( $request['id'] );
    286         if ( is_wp_error( $revision ) ) {
    287             return $revision;
    288         }
    289 
    290         $response = $this->prepare_item_for_response( $revision, $request );
    291         return rest_ensure_response( $response );
    292     }
    293 
    294     /**
    295      * Gets the global styles revision, if the ID is valid.
    296      *
    297      * @since 6.5.0
    298      *
    299      * @param int $id Supplied ID.
    300      * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise.
    301      */
    302     protected function get_revision( $id ) {
    303         $error = new WP_Error(
    304             'rest_post_invalid_id',
    305             __( 'Invalid global styles revision ID.' ),
    306             array( 'status' => 404 )
    307         );
    308 
    309         if ( (int) $id <= 0 ) {
    310             return $error;
    311         }
    312 
    313         $revision = get_post( (int) $id );
    314         if ( empty( $revision ) || empty( $revision->ID ) || 'revision' !== $revision->post_type ) {
    315             return $error;
    316         }
    317 
    318         return $revision;
    319     }
    320 
    321     /**
    322      * Checks the post_date_gmt or modified_gmt and prepare any post or
    323      * modified date for single post output.
    324      *
    325      * Duplicate of WP_REST_Revisions_Controller::prepare_date_response.
    326      *
    327      * @since 6.3.0
    328      *
    329      * @param string      $date_gmt GMT publication time.
    330      * @param string|null $date     Optional. Local publication time. Default null.
    331      * @return string|null ISO8601/RFC3339 formatted datetime, otherwise null.
    332      */
    333     protected function prepare_date_response( $date_gmt, $date = null ) {
    334         if ( '0000-00-00 00:00:00' === $date_gmt ) {
    335             return null;
    336         }
    337 
    338         if ( isset( $date ) ) {
    339             return mysql_to_rfc3339( $date );
    340         }
    341 
    342         return mysql_to_rfc3339( $date_gmt );
    343     }
    344 
    345     /**
    346268     * Prepares the revision for the REST response.
    347269     *
     
    412334     *
    413335     * @since 6.3.0
     336     * @since 6.6.0 Merged parent and parent controller schema data.
    414337     *
    415338     * @return array Item schema data.
     
    420343        }
    421344
    422         $schema = array(
    423             '$schema'    => 'http://json-schema.org/draft-04/schema#',
    424             'title'      => "{$this->parent_post_type}-revision",
    425             'type'       => 'object',
    426             // Base properties for every revision.
    427             'properties' => array(
    428 
    429                 /*
    430                  * Adds settings and styles from the WP_REST_Revisions_Controller item fields.
    431                  * Leaves out GUID as global styles shouldn't be accessible via URL.
    432                  */
    433                 'author'       => array(
    434                     'description' => __( 'The ID for the author of the revision.' ),
    435                     'type'        => 'integer',
    436                     'context'     => array( 'view', 'edit', 'embed' ),
    437                 ),
    438                 'date'         => array(
    439                     'description' => __( "The date the revision was published, in the site's timezone." ),
    440                     'type'        => 'string',
    441                     'format'      => 'date-time',
    442                     'context'     => array( 'view', 'edit', 'embed' ),
    443                 ),
    444                 'date_gmt'     => array(
    445                     'description' => __( 'The date the revision was published, as GMT.' ),
    446                     'type'        => 'string',
    447                     'format'      => 'date-time',
    448                     'context'     => array( 'view', 'edit' ),
    449                 ),
    450                 'id'           => array(
    451                     'description' => __( 'Unique identifier for the revision.' ),
    452                     'type'        => 'integer',
    453                     'context'     => array( 'view', 'edit', 'embed' ),
    454                 ),
    455                 'modified'     => array(
    456                     'description' => __( "The date the revision was last modified, in the site's timezone." ),
    457                     'type'        => 'string',
    458                     'format'      => 'date-time',
    459                     'context'     => array( 'view', 'edit' ),
    460                 ),
    461                 'modified_gmt' => array(
    462                     'description' => __( 'The date the revision was last modified, as GMT.' ),
    463                     'type'        => 'string',
    464                     'format'      => 'date-time',
    465                     'context'     => array( 'view', 'edit' ),
    466                 ),
    467                 'parent'       => array(
    468                     'description' => __( 'The ID for the parent of the revision.' ),
    469                     'type'        => 'integer',
    470                     'context'     => array( 'view', 'edit', 'embed' ),
    471                 ),
    472 
    473                 // Adds settings and styles from the WP_REST_Global_Styles_Controller parent schema.
    474                 'styles'       => array(
    475                     'description' => __( 'Global styles.' ),
    476                     'type'        => array( 'object' ),
    477                     'context'     => array( 'view', 'edit' ),
    478                 ),
    479                 'settings'     => array(
    480                     'description' => __( 'Global settings.' ),
    481                     'type'        => array( 'object' ),
    482                     'context'     => array( 'view', 'edit' ),
    483                 ),
    484             ),
    485         );
    486 
    487         $this->schema = $schema;
     345        $schema               = parent::get_item_schema();
     346        $parent_schema        = $this->parent_controller->get_item_schema();
     347        $schema['properties'] = array_merge( $schema['properties'], $parent_schema['properties'] );
     348
     349        unset(
     350            $schema['properties']['guid'],
     351            $schema['properties']['slug'],
     352            $schema['properties']['meta'],
     353            $schema['properties']['content'],
     354            $schema['properties']['title']
     355        );
     356
     357            $this->schema = $schema;
    488358
    489359        return $this->add_additional_fields_schema( $this->schema );
     
    491361
    492362    /**
    493      * Checks if a given request has access to read a single global style.
    494      *
    495      * @since 6.3.0
    496      *
    497      * @param WP_REST_Request $request Full details about the request.
    498      * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
    499      */
    500     public function get_item_permissions_check( $request ) {
    501         $post = $this->get_parent( $request['parent'] );
    502         if ( is_wp_error( $post ) ) {
    503             return $post;
    504         }
    505 
    506         /*
    507          * The same check as WP_REST_Global_Styles_Controller::get_item_permissions_check.
    508          */
    509         if ( ! current_user_can( 'read_post', $post->ID ) ) {
    510             return new WP_Error(
    511                 'rest_cannot_view',
    512                 __( 'Sorry, you are not allowed to view revisions for this global style.' ),
    513                 array( 'status' => rest_authorization_required_code() )
    514             );
    515         }
    516 
    517         return true;
    518     }
    519 
    520     /**
    521      * Gets the parent post, if the ID is valid.
    522      *
    523      * Duplicate of WP_REST_Revisions_Controller::get_parent.
    524      *
    525      * @since 6.3.0
    526      *
    527      * @param int $parent_post_id Supplied ID.
    528      * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
    529      */
    530     protected function get_parent( $parent_post_id ) {
    531         $error = new WP_Error(
    532             'rest_post_invalid_parent',
    533             __( 'Invalid post parent ID.' ),
    534             array( 'status' => 404 )
    535         );
    536 
    537         if ( (int) $parent_post_id <= 0 ) {
    538             return $error;
    539         }
    540 
    541         $parent_post = get_post( (int) $parent_post_id );
    542 
    543         if ( empty( $parent_post ) || empty( $parent_post->ID )
    544             || $this->parent_post_type !== $parent_post->post_type
    545         ) {
    546             return $error;
    547         }
    548 
    549         return $parent_post;
     363     * Retrieves the query params for collections.
     364     * Removes params that are not supported by global styles revisions.
     365     *
     366     * @since 6.6.0
     367     *
     368     * @return array Collection parameters.
     369     */
     370    public function get_collection_params() {
     371        $query_params = parent::get_collection_params();
     372        unset(
     373            $query_params['exclude'],
     374            $query_params['include'],
     375            $query_params['search'],
     376            $query_params['order'],
     377            $query_params['orderby']
     378        );
     379        return $query_params;
    550380    }
    551381}
Note: See TracChangeset for help on using the changeset viewer.