From 7d192d8adfa0860430e5652a95b9e48f3fe911fa Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 15:59:45 +1100 Subject: [PATCH 01/25] Initial commit. WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Controller --- src/wp-includes/post.php | 26 ++- src/wp-includes/rest-api.php | 4 - ...est-global-styles-revisions-controller.php | 196 +++++------------- src/wp-settings.php | 2 +- 4 files changed, 67 insertions(+), 161 deletions(-) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 08cb5fb2cacf9..722c979056424 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -473,15 +473,19 @@ function create_initial_post_types() { register_post_type( 'wp_global_styles', array( - 'label' => _x( 'Global Styles', 'post type general name' ), - 'description' => __( 'Global styles to include in themes.' ), - 'public' => false, - '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ - 'show_ui' => false, - 'show_in_rest' => false, - 'rewrite' => false, - 'capabilities' => array( + 'label' => _x( 'Global Styles', 'post type general name' ), + 'description' => __( 'Global styles to include in themes.' ), + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ + 'show_ui' => false, + 'show_in_rest' => true, + 'rewrite' => false, + 'rest_base' => 'global-styles', + 'rest_controller_class' => 'WP_REST_Global_Styles_Controller', + 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller', + 'late_route_registration' => true, + 'capabilities' => array( 'read' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', @@ -490,8 +494,8 @@ function create_initial_post_types() { 'edit_others_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', ), - 'map_meta_cap' => true, - 'supports' => array( + 'map_meta_cap' => true, + 'supports' => array( 'title', 'editor', 'revisions', diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 2631a6663fe92..244bf493db96e 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -323,10 +323,6 @@ function create_initial_rest_routes() { $controller = new WP_REST_Block_Types_Controller(); $controller->register_routes(); - // Global Styles revisions. - $controller = new WP_REST_Global_Styles_Revisions_Controller(); - $controller->register_routes(); - // Global Styles. $controller = new WP_REST_Global_Styles_Controller(); $controller->register_routes(); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index db1be197e5ab4..cc6e37d738999 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -14,14 +14,22 @@ * * @see WP_REST_Controller */ -class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Controller { +class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Controller { /** * Parent post type. * * @since 6.3.0 * @var string */ - protected $parent_post_type; + private $parent_post_type; + + /** + * Parent controller. + * + * @since 6.5.0 + * @var WP_REST_Controller + */ + private $parent_controller; /** * The base of the parent controller's route. @@ -35,12 +43,23 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Controller { * Constructor. * * @since 6.3.0 + * + * @param string $parent_post_type Post type of the parent. */ - public function __construct() { - $this->parent_post_type = 'wp_global_styles'; - $this->rest_base = 'revisions'; - $this->parent_base = 'global-styles'; - $this->namespace = 'wp/v2'; + public function __construct( $parent_post_type ) { + parent::__construct( $parent_post_type ); + $this->parent_post_type = $parent_post_type; + $post_type_object = get_post_type_object( $parent_post_type ); + $parent_controller = $post_type_object->get_rest_controller(); + + if ( ! $parent_controller ) { + $parent_controller = new WP_REST_Global_Styles_Controller(); + } + + $this->parent_controller = $parent_controller; + $this->rest_base = 'revisions'; + $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; + $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** @@ -63,7 +82,7 @@ public function register_routes() { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -97,29 +116,6 @@ public function register_routes() { ); } - /** - * Retrieves the query params for collections. - * - * Inherits from WP_REST_Controller::get_collection_params(), - * also reflects changes to return value WP_REST_Revisions_Controller::get_collection_params(). - * - * @since 6.3.0 - * - * @return array Collection parameters. - */ - public function get_collection_params() { - $collection_params = parent::get_collection_params(); - $collection_params['context']['default'] = 'view'; - $collection_params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.' ), - 'type' => 'integer', - ); - unset( $collection_params['search'] ); - unset( $collection_params['per_page']['default'] ); - - return $collection_params; - } - /** * Returns decoded JSON from post content string, * or a 404 if not found. @@ -318,30 +314,6 @@ protected function get_revision( $id ) { return $revision; } - /** - * Checks the post_date_gmt or modified_gmt and prepare any post or - * modified date for single post output. - * - * Duplicate of WP_REST_Revisions_Controller::prepare_date_response. - * - * @since 6.3.0 - * - * @param string $date_gmt GMT publication time. - * @param string|null $date Optional. Local publication time. Default null. - * @return string|null ISO8601/RFC3339 formatted datetime, otherwise null. - */ - protected function prepare_date_response( $date_gmt, $date = null ) { - if ( '0000-00-00 00:00:00' === $date_gmt ) { - return null; - } - - if ( isset( $date ) ) { - return mysql_to_rfc3339( $date ); - } - - return mysql_to_rfc3339( $date_gmt ); - } - /** * Prepares the revision for the REST response. * @@ -419,85 +391,39 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => "{$this->parent_post_type}-revision", - 'type' => 'object', - // Base properties for every revision. - 'properties' => array( - - /* - * Adds settings and styles from the WP_REST_Revisions_Controller item fields. - * Leaves out GUID as global styles shouldn't be accessible via URL. - */ - 'author' => array( - 'description' => __( 'The ID for the author of the revision.' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'date' => array( - 'description' => __( "The date the revision was published, in the site's timezone." ), - 'type' => 'string', - 'format' => 'date-time', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'date_gmt' => array( - 'description' => __( 'The date the revision was published, as GMT.' ), - 'type' => 'string', - 'format' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'id' => array( - 'description' => __( 'Unique identifier for the revision.' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'modified' => array( - 'description' => __( "The date the revision was last modified, in the site's timezone." ), - 'type' => 'string', - 'format' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'modified_gmt' => array( - 'description' => __( 'The date the revision was last modified, as GMT.' ), - 'type' => 'string', - 'format' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'parent' => array( - 'description' => __( 'The ID for the parent of the revision.' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - ), + // Adds settings and styles from the WP_REST_Revisions_Controller item fields. + $schema = parent::get_item_schema(); - // Adds settings and styles from the WP_REST_Global_Styles_Controller parent schema. - 'styles' => array( - 'description' => __( 'Global styles.' ), - 'type' => array( 'object' ), - 'context' => array( 'view', 'edit' ), - ), - 'settings' => array( - 'description' => __( 'Global settings.' ), - 'type' => array( 'object' ), - 'context' => array( 'view', 'edit' ), - ), - ), + // Adds settings and styles from the WP_REST_Global_Styles_Controller parent schema. + $schema['properties']['styles'] = array( + 'description' => __( 'Global styles.' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ); + + $schema['properties']['settings'] = array( + 'description' => __( 'Global settings.' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), ); + unset( $schema['properties']['guid'] ); + unset( $schema['properties']['slug'] ); + $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** - * Checks if a given request has access to read a single global style. + * Checks if a given request has access to get global styles revisions. * - * @since 6.3.0 + * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ - public function get_item_permissions_check( $request ) { + public function get_items_permissions_check( $request ) { $post = $this->get_parent( $request['parent'] ); if ( is_wp_error( $post ) ) { return $post; @@ -518,34 +444,14 @@ public function get_item_permissions_check( $request ) { } /** - * Gets the parent post, if the ID is valid. - * - * Duplicate of WP_REST_Revisions_Controller::get_parent. + * Checks if a given request has access to read a single global style revision. * * @since 6.3.0 * - * @param int $parent_post_id Supplied ID. - * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. + * @param WP_REST_Request $request Full details about the request. + * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ - protected function get_parent( $parent_post_id ) { - $error = new WP_Error( - 'rest_post_invalid_parent', - __( 'Invalid post parent ID.' ), - array( 'status' => 404 ) - ); - - if ( (int) $parent_post_id <= 0 ) { - return $error; - } - - $parent_post = get_post( (int) $parent_post_id ); - - if ( empty( $parent_post ) || empty( $parent_post->ID ) - || $this->parent_post_type !== $parent_post->post_type - ) { - return $error; - } - - return $parent_post; + public function get_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); } } diff --git a/src/wp-settings.php b/src/wp-settings.php index c881eaa5bf4a8..b91f34de6edb4 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -276,10 +276,10 @@ require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-posts-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-attachments-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-global-styles-controller.php'; -require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-types-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-statuses-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-revisions-controller.php'; +require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-template-revisions-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-autosaves-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php'; From d7b4c1ca9e148bb4d370f2a36c4d52d1eb35ae19 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 16:47:53 +1100 Subject: [PATCH 02/25] Adding title to schema. --- ...est-global-styles-revisions-controller.php | 19 ++++--------------- ...est-global-styles-revisions-controller.php | 3 ++- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index cc6e37d738999..c7339278475fc 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -391,24 +391,13 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } - // Adds settings and styles from the WP_REST_Revisions_Controller item fields. - $schema = parent::get_item_schema(); - - // Adds settings and styles from the WP_REST_Global_Styles_Controller parent schema. - $schema['properties']['styles'] = array( - 'description' => __( 'Global styles.' ), - 'type' => array( 'object' ), - 'context' => array( 'view', 'edit' ), - ); - - $schema['properties']['settings'] = array( - 'description' => __( 'Global settings.' ), - 'type' => array( 'object' ), - 'context' => array( 'view', 'edit' ), - ); + $schema = parent::get_item_schema(); + $parent_schema = $this->parent_controller->get_item_schema(); + $schema['properties'] = array_merge( $schema['properties'], $parent_schema['properties'] ); unset( $schema['properties']['guid'] ); unset( $schema['properties']['slug'] ); + unset( $schema['properties']['meta'] ); $this->schema = $schema; diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index 3773b5fd1f9e4..9d894c113deef 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -406,9 +406,10 @@ public function test_get_item_schema() { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertCount( 9, $properties, 'Schema properties array has exactly 9 elements.' ); + $this->assertCount( 10, $properties, 'Schema properties array has exactly 9 elements.' ); $this->assertArrayHasKey( 'id', $properties, 'Schema properties array has "id" key.' ); $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array has "styles" key.' ); + $this->assertArrayHasKey( 'title', $properties, 'Schema properties array has "title" key.' ); $this->assertArrayHasKey( 'settings', $properties, 'Schema properties array has "settings" key.' ); $this->assertArrayHasKey( 'parent', $properties, 'Schema properties array has "parent" key.' ); $this->assertArrayHasKey( 'author', $properties, 'Schema properties array has "author" key.' ); From 41c98a5b8be9a663936085379b35ed44e48200c7 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 17:18:41 +1100 Subject: [PATCH 03/25] Remove permissions checks and favour parent's --- ...est-global-styles-revisions-controller.php | 40 ------------------- ...est-global-styles-revisions-controller.php | 2 +- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index c7339278475fc..ca288e5765071 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -403,44 +403,4 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } - - /** - * Checks if a given request has access to get global styles revisions. - * - * @since 6.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { - $post = $this->get_parent( $request['parent'] ); - if ( is_wp_error( $post ) ) { - return $post; - } - - /* - * The same check as WP_REST_Global_Styles_Controller::get_item_permissions_check. - */ - if ( ! current_user_can( 'read_post', $post->ID ) ) { - return new WP_Error( - 'rest_cannot_view', - __( 'Sorry, you are not allowed to view revisions for this global style.' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Checks if a given request has access to read a single global style revision. - * - * @since 6.3.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - return $this->get_items_permissions_check( $request ); - } } diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index 9d894c113deef..bc49ec8e3b501 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -429,7 +429,7 @@ public function test_get_item_permissions_check() { $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( 'rest_cannot_view', $response, 403 ); + $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); } /** From 59d6953bb014affc6d7fb5be3b04f4c0b423eafc Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 17:25:42 +1100 Subject: [PATCH 04/25] Remove duplicated tests --- ...est-global-styles-revisions-controller.php | 1 + ...est-global-styles-revisions-controller.php | 407 ------------------ 2 files changed, 1 insertion(+), 407 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index ca288e5765071..78f73641841ea 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -383,6 +383,7 @@ public function prepare_item_for_response( $post, $request ) { * Retrieves the revision's schema, conforming to JSON Schema. * * @since 6.3.0 + * @since 6.5.0 Merging parent and parent controller schemata. * * @return array Item schema data. */ diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index bc49ec8e3b501..1eb2c1856b8eb 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -419,413 +419,6 @@ public function test_get_item_schema() { $this->assertArrayHasKey( 'modified_gmt', $properties, 'Schema properties array has "modified_gmt" key.' ); } - /** - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_item_permissions_check - */ - public function test_get_item_permissions_check() { - wp_set_current_user( self::$author_id ); - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $response = rest_get_server()->dispatch( $request ); - - $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); - } - - /** - * Tests the pagination header of the first page. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_first_page - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_pagination_header_of_the_first_page() { - wp_set_current_user( self::$admin_id ); - - $rest_route = '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions'; - $per_page = 2; - $total_pages = (int) ceil( $this->total_revisions / $per_page ); - $page = 1; // First page. - - $request = new WP_REST_Request( 'GET', $rest_route ); - $request->set_query_params( - array( - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $headers = $response->get_headers(); - $this->assertSame( $this->total_revisions, $headers['X-WP-Total'] ); - $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); - $next_link = add_query_arg( - array( - 'per_page' => $per_page, - 'page' => $page + 1, - ), - rest_url( $rest_route ) - ); - $this->assertStringNotContainsString( 'rel="prev"', $headers['Link'] ); - $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] ); - } - - /** - * Tests the pagination header of the last page. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_last_page - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_pagination_header_of_the_last_page() { - wp_set_current_user( self::$admin_id ); - - $rest_route = '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions'; - $per_page = 2; - $total_pages = (int) ceil( $this->total_revisions / $per_page ); - $page = 2; // Last page. - - $request = new WP_REST_Request( 'GET', $rest_route ); - $request->set_query_params( - array( - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $headers = $response->get_headers(); - $this->assertSame( $this->total_revisions, $headers['X-WP-Total'] ); - $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); - $prev_link = add_query_arg( - array( - 'per_page' => $per_page, - 'page' => $page - 1, - ), - rest_url( $rest_route ) - ); - $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] ); - } - - /** - * Tests that invalid 'per_page' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_per_page_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_invalid_per_page_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = -1; // Invalid number. - $expected_error = 'rest_invalid_param'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_param( 'per_page', $per_page ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that out of bounds 'page' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bounds_page_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_out_of_bounds_page_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $total_pages = (int) ceil( $this->total_revisions / $per_page ); - $page = $total_pages + 1; // Out of bound page. - $expected_error = 'rest_revision_invalid_page_number'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that impossibly high 'page' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_max_pages_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_invalid_max_pages_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $page = REST_TESTS_IMPOSSIBLY_HIGH_NUMBER; // Invalid number. - $expected_error = 'rest_revision_invalid_page_number'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that the default query should fetch all revisions. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_default_query_should_fetch_all_revisons - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_default_query_should_fetch_all_revisons() { - wp_set_current_user( self::$admin_id ); - - $expected_count = $this->total_revisions; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $response = rest_get_server()->dispatch( $request ); - $this->assertCount( $expected_count, $response->get_data() ); - } - - /** - * Tests that 'offset' query shouldn't work without 'per_page' (fallback -1). - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_not_work_without_per_page - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_offset_should_not_work_without_per_page() { - wp_set_current_user( self::$admin_id ); - - $offset = 1; - $expected_count = $this->total_revisions; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_param( 'offset', $offset ); - $response = rest_get_server()->dispatch( $request ); - $this->assertCount( $expected_count, $response->get_data() ); - } - - /** - * Tests that 'offset' query should work with 'per_page'. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_work_with_per_page - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_offset_should_work_with_per_page() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = 1; - $expected_count = 2; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertCount( $expected_count, $response->get_data() ); - } - - /** - * Tests that 'offset' query should take priority over 'page'. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_take_priority_over_page - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_offset_should_take_priority_over_page() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = 1; - $page = 1; - $expected_count = 2; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertCount( $expected_count, $response->get_data() ); - } - - /** - * Tests that 'offset' query, as the total revisions count, should return empty data. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_total_revisions_offset_should_return_empty_data - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_total_revisions_offset_should_return_empty_data() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = $this->total_revisions; - $expected_error = 'rest_revision_invalid_offset_number'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that out of bound 'offset' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bound_offset_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_out_of_bound_offset_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = $this->total_revisions + 1; - $expected_error = 'rest_revision_invalid_offset_number'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that impossible high number for 'offset' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_impossible_high_number_offset_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_impossible_high_number_offset_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = REST_TESTS_IMPOSSIBLY_HIGH_NUMBER; - $expected_error = 'rest_revision_invalid_offset_number'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that invalid 'offset' query should error. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_offset_should_error - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_invalid_offset_should_error() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $offset = 'moreplease'; - $expected_error = 'rest_invalid_param'; - $expected_status = 400; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => $offset, - 'per_page' => $per_page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( $expected_error, $response, $expected_status ); - } - - /** - * Tests that out of bounds 'page' query should not error when offset is provided, - * because it takes precedence. - * - * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bounds_page_should_not_error_if_offset - * - * @ticket 58524 - * - * @covers WP_REST_Global_Styles_Controller::get_items - */ - public function test_get_items_out_of_bounds_page_should_not_error_if_offset() { - wp_set_current_user( self::$admin_id ); - - $per_page = 2; - $total_pages = (int) ceil( $this->total_revisions / $per_page ); - $page = $total_pages + 1; // Out of bound page. - $expected_count = 2; - - $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); - $request->set_query_params( - array( - 'offset' => 1, - 'per_page' => $per_page, - 'page' => $page, - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertCount( $expected_count, $response->get_data() ); - } - /** * @doesNotPerformAssertions */ From dbcc3b5b2b2436dc07c40e44ed84671c9ce7aa5c Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 17:49:18 +1100 Subject: [PATCH 05/25] Reverting post type registration changes as it assigns an autosave controller. we --- src/wp-includes/post.php | 26 +++++++--------- src/wp-includes/rest-api.php | 4 +++ ...est-global-styles-revisions-controller.php | 30 +++++-------------- ...est-global-styles-revisions-controller.php | 2 +- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 722c979056424..08cb5fb2cacf9 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -473,19 +473,15 @@ function create_initial_post_types() { register_post_type( 'wp_global_styles', array( - 'label' => _x( 'Global Styles', 'post type general name' ), - 'description' => __( 'Global styles to include in themes.' ), - 'public' => false, - '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ - 'show_ui' => false, - 'show_in_rest' => true, - 'rewrite' => false, - 'rest_base' => 'global-styles', - 'rest_controller_class' => 'WP_REST_Global_Styles_Controller', - 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller', - 'late_route_registration' => true, - 'capabilities' => array( + 'label' => _x( 'Global Styles', 'post type general name' ), + 'description' => __( 'Global styles to include in themes.' ), + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ + 'show_ui' => false, + 'show_in_rest' => false, + 'rewrite' => false, + 'capabilities' => array( 'read' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', @@ -494,8 +490,8 @@ function create_initial_post_types() { 'edit_others_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', ), - 'map_meta_cap' => true, - 'supports' => array( + 'map_meta_cap' => true, + 'supports' => array( 'title', 'editor', 'revisions', diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 244bf493db96e..2631a6663fe92 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -323,6 +323,10 @@ function create_initial_rest_routes() { $controller = new WP_REST_Block_Types_Controller(); $controller->register_routes(); + // Global Styles revisions. + $controller = new WP_REST_Global_Styles_Revisions_Controller(); + $controller->register_routes(); + // Global Styles. $controller = new WP_REST_Global_Styles_Controller(); $controller->register_routes(); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 78f73641841ea..3ace71765205e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -15,14 +15,6 @@ * @see WP_REST_Controller */ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Controller { - /** - * Parent post type. - * - * @since 6.3.0 - * @var string - */ - private $parent_post_type; - /** * Parent controller. * @@ -43,23 +35,13 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr * Constructor. * * @since 6.3.0 - * - * @param string $parent_post_type Post type of the parent. */ - public function __construct( $parent_post_type ) { - parent::__construct( $parent_post_type ); - $this->parent_post_type = $parent_post_type; - $post_type_object = get_post_type_object( $parent_post_type ); - $parent_controller = $post_type_object->get_rest_controller(); - - if ( ! $parent_controller ) { - $parent_controller = new WP_REST_Global_Styles_Controller(); - } - - $this->parent_controller = $parent_controller; + public function __construct() { + parent::__construct( 'wp_global_styles' ); + $this->parent_controller = new WP_REST_Global_Styles_Controller(); $this->rest_base = 'revisions'; - $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; - $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; + $this->parent_base = $this->parent_controller->rest_base; + $this->namespace = $this->parent_controller->namespace; } /** @@ -399,6 +381,8 @@ public function get_item_schema() { unset( $schema['properties']['guid'] ); unset( $schema['properties']['slug'] ); unset( $schema['properties']['meta'] ); + unset( $schema['properties']['content'] ); + unset( $schema['properties']['excerpt'] ); $this->schema = $schema; diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index 1eb2c1856b8eb..3651f413ac169 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -406,7 +406,7 @@ public function test_get_item_schema() { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertCount( 10, $properties, 'Schema properties array has exactly 9 elements.' ); + $this->assertCount( 10, $properties, 'Schema properties array has exactly 10 elements.' ); $this->assertArrayHasKey( 'id', $properties, 'Schema properties array has "id" key.' ); $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array has "styles" key.' ); $this->assertArrayHasKey( 'title', $properties, 'Schema properties array has "title" key.' ); From 25cbe83b6f9171c70d688a58174770ca1fcb336e Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 18:03:19 +1100 Subject: [PATCH 06/25] Regenerated fixture --- tests/qunit/fixtures/wp-api-generated.js | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 6c961548eb8e2..de6c36a1643e0 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -10035,10 +10035,58 @@ mockedApiResponse.Schema = { "maximum": 100, "required": false }, + "search": { + "description": "Limit results to those matching a string.", + "type": "string", + "required": false + }, + "exclude": { + "description": "Ensure result set excludes specific IDs.", + "type": "array", + "items": { + "type": "integer" + }, + "default": [], + "required": false + }, + "include": { + "description": "Limit result set to specific IDs.", + "type": "array", + "items": { + "type": "integer" + }, + "default": [], + "required": false + }, "offset": { "description": "Offset the result set by a specific number of items.", "type": "integer", "required": false + }, + "order": { + "description": "Order sort attribute ascending or descending.", + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ], + "required": false + }, + "orderby": { + "description": "Sort collection by object attribute.", + "type": "string", + "default": "date", + "enum": [ + "date", + "id", + "include", + "relevance", + "slug", + "include_slugs", + "title" + ], + "required": false } } } From e9d1f1069bbe44408e1aeb358ba798dd10e24874 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 23 Nov 2023 20:15:41 +1100 Subject: [PATCH 07/25] Revert introducing title in schema --- .../class-wp-rest-global-styles-revisions-controller.php | 4 ++-- .../rest-api/rest-global-styles-revisions-controller.php | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 3ace71765205e..f2877aba6e4ba 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -365,7 +365,7 @@ public function prepare_item_for_response( $post, $request ) { * Retrieves the revision's schema, conforming to JSON Schema. * * @since 6.3.0 - * @since 6.5.0 Merging parent and parent controller schemata. + * @since 6.5.0 Merged parent and parent controller schemata. * * @return array Item schema data. */ @@ -382,7 +382,7 @@ public function get_item_schema() { unset( $schema['properties']['slug'] ); unset( $schema['properties']['meta'] ); unset( $schema['properties']['content'] ); - unset( $schema['properties']['excerpt'] ); + unset( $schema['properties']['title'] ); $this->schema = $schema; diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index 3651f413ac169..d4f9c21343e00 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -406,10 +406,9 @@ public function test_get_item_schema() { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertCount( 10, $properties, 'Schema properties array has exactly 10 elements.' ); + $this->assertCount( 9, $properties, 'Schema properties array has exactly 9 elements.' ); $this->assertArrayHasKey( 'id', $properties, 'Schema properties array has "id" key.' ); $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array has "styles" key.' ); - $this->assertArrayHasKey( 'title', $properties, 'Schema properties array has "title" key.' ); $this->assertArrayHasKey( 'settings', $properties, 'Schema properties array has "settings" key.' ); $this->assertArrayHasKey( 'parent', $properties, 'Schema properties array has "parent" key.' ); $this->assertArrayHasKey( 'author', $properties, 'Schema properties array has "author" key.' ); From ec4229fcb4dbc359692cbdf275eb96247c5050fe Mon Sep 17 00:00:00 2001 From: ramon Date: Wed, 3 Jan 2024 11:01:56 +1100 Subject: [PATCH 08/25] Reinstating global styles revision controller tests that were duplicated from WP_REST_Revisions_Controller tests --- ...est-global-styles-revisions-controller.php | 408 ++++++++++++++++++ 1 file changed, 408 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index d4f9c21343e00..9afddce615d14 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -418,6 +418,414 @@ public function test_get_item_schema() { $this->assertArrayHasKey( 'modified_gmt', $properties, 'Schema properties array has "modified_gmt" key.' ); } + /** + * @ticket 58524 + * @ticket 60131 + * + * @covers WP_REST_Global_Styles_Controller::get_item_permissions_check + */ + public function test_get_item_permissions_check() { + wp_set_current_user( self::$author_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $response = rest_get_server()->dispatch( $request ); + + $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); + } + + /** + * Tests the pagination header of the first page. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_first_page + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_pagination_header_of_the_first_page() { + wp_set_current_user( self::$admin_id ); + + $rest_route = '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions'; + $per_page = 2; + $total_pages = (int) ceil( $this->total_revisions / $per_page ); + $page = 1; // First page. + + $request = new WP_REST_Request( 'GET', $rest_route ); + $request->set_query_params( + array( + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $headers = $response->get_headers(); + $this->assertSame( $this->total_revisions, $headers['X-WP-Total'] ); + $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); + $next_link = add_query_arg( + array( + 'per_page' => $per_page, + 'page' => $page + 1, + ), + rest_url( $rest_route ) + ); + $this->assertStringNotContainsString( 'rel="prev"', $headers['Link'] ); + $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] ); + } + + /** + * Tests the pagination header of the last page. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_last_page + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_pagination_header_of_the_last_page() { + wp_set_current_user( self::$admin_id ); + + $rest_route = '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions'; + $per_page = 2; + $total_pages = (int) ceil( $this->total_revisions / $per_page ); + $page = 2; // Last page. + + $request = new WP_REST_Request( 'GET', $rest_route ); + $request->set_query_params( + array( + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $headers = $response->get_headers(); + $this->assertSame( $this->total_revisions, $headers['X-WP-Total'] ); + $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); + $prev_link = add_query_arg( + array( + 'per_page' => $per_page, + 'page' => $page - 1, + ), + rest_url( $rest_route ) + ); + $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] ); + } + + /** + * Tests that invalid 'per_page' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_per_page_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_invalid_per_page_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = -1; // Invalid number. + $expected_error = 'rest_invalid_param'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_param( 'per_page', $per_page ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that out of bounds 'page' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bounds_page_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_out_of_bounds_page_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $total_pages = (int) ceil( $this->total_revisions / $per_page ); + $page = $total_pages + 1; // Out of bound page. + $expected_error = 'rest_revision_invalid_page_number'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that impossibly high 'page' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_max_pages_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_invalid_max_pages_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $page = REST_TESTS_IMPOSSIBLY_HIGH_NUMBER; // Invalid number. + $expected_error = 'rest_revision_invalid_page_number'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that the default query should fetch all revisions. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_default_query_should_fetch_all_revisons + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_default_query_should_fetch_all_revisons() { + wp_set_current_user( self::$admin_id ); + + $expected_count = $this->total_revisions; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $response = rest_get_server()->dispatch( $request ); + $this->assertCount( $expected_count, $response->get_data() ); + } + + /** + * Tests that 'offset' query shouldn't work without 'per_page' (fallback -1). + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_not_work_without_per_page + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_offset_should_not_work_without_per_page() { + wp_set_current_user( self::$admin_id ); + + $offset = 1; + $expected_count = $this->total_revisions; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_param( 'offset', $offset ); + $response = rest_get_server()->dispatch( $request ); + $this->assertCount( $expected_count, $response->get_data() ); + } + + /** + * Tests that 'offset' query should work with 'per_page'. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_work_with_per_page + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_offset_should_work_with_per_page() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = 1; + $expected_count = 2; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertCount( $expected_count, $response->get_data() ); + } + + /** + * Tests that 'offset' query should take priority over 'page'. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_offset_should_take_priority_over_page + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_offset_should_take_priority_over_page() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = 1; + $page = 1; + $expected_count = 2; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertCount( $expected_count, $response->get_data() ); + } + + /** + * Tests that 'offset' query, as the total revisions count, should return empty data. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_total_revisions_offset_should_return_empty_data + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_total_revisions_offset_should_return_empty_data() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = $this->total_revisions; + $expected_error = 'rest_revision_invalid_offset_number'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that out of bound 'offset' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bound_offset_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_out_of_bound_offset_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = $this->total_revisions + 1; + $expected_error = 'rest_revision_invalid_offset_number'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that impossible high number for 'offset' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_impossible_high_number_offset_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_impossible_high_number_offset_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = REST_TESTS_IMPOSSIBLY_HIGH_NUMBER; + $expected_error = 'rest_revision_invalid_offset_number'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that invalid 'offset' query should error. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_offset_should_error + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_invalid_offset_should_error() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $offset = 'moreplease'; + $expected_error = 'rest_invalid_param'; + $expected_status = 400; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => $offset, + 'per_page' => $per_page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( $expected_error, $response, $expected_status ); + } + + /** + * Tests that out of bounds 'page' query should not error when offset is provided, + * because it takes precedence. + * + * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bounds_page_should_not_error_if_offset + * + * @ticket 58524 + * + * @covers WP_REST_Global_Styles_Controller::get_items + */ + public function test_get_items_out_of_bounds_page_should_not_error_if_offset() { + wp_set_current_user( self::$admin_id ); + + $per_page = 2; + $total_pages = (int) ceil( $this->total_revisions / $per_page ); + $page = $total_pages + 1; // Out of bound page. + $expected_count = 2; + + $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); + $request->set_query_params( + array( + 'offset' => 1, + 'per_page' => $per_page, + 'page' => $page, + ) + ); + $response = rest_get_server()->dispatch( $request ); + $this->assertCount( $expected_count, $response->get_data() ); + } + /** * @doesNotPerformAssertions */ From ca524b2b07115def232bfe117fd7fdb16525c6ff Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 22 Dec 2023 16:20:59 +1100 Subject: [PATCH 09/25] Update src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php Co-authored-by: Mukesh Panchal --- .../class-wp-rest-global-styles-revisions-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index f2877aba6e4ba..68e05339d9c87 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -365,7 +365,7 @@ public function prepare_item_for_response( $post, $request ) { * Retrieves the revision's schema, conforming to JSON Schema. * * @since 6.3.0 - * @since 6.5.0 Merged parent and parent controller schemata. + * @since 6.5.0 Merged parent and parent controller schema data. * * @return array Item schema data. */ From 93190aeb09dc623e29305d2498ccf75c53962be6 Mon Sep 17 00:00:00 2001 From: ramon Date: Wed, 3 Jan 2024 12:21:26 +1100 Subject: [PATCH 10/25] Excluding search, include and exclude from the collection query params Excluding order and order by from the collection query params Comment --- ...est-global-styles-revisions-controller.php | 18 +++++++ ...est-global-styles-revisions-controller.php | 2 +- tests/qunit/fixtures/wp-api-generated.js | 48 ------------------- 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 68e05339d9c87..c71ada44364ef 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -388,4 +388,22 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } + + /** + * Retrieves the query params for collections. + * Removes params that are not supported by global styles revisions. + * + * @since 6.5.0 + * + * @return array Collection parameters. + */ + public function get_collection_params() { + $query_params = parent::get_collection_params(); + unset( $query_params['exclude'] ); + unset( $query_params['include'] ); + unset( $query_params['search'] ); + unset( $query_params['order'] ); + unset( $query_params['orderby'] ); + return $query_params; + } } diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index 9afddce615d14..5e6385c730ab3 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -830,7 +830,7 @@ public function test_get_items_out_of_bounds_page_should_not_error_if_offset() { * @doesNotPerformAssertions */ public function test_context_param() { - // Controller does not implement test_context_param(). + // Controller does not implement get_context_param(). } /** diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index de6c36a1643e0..6c961548eb8e2 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -10035,58 +10035,10 @@ mockedApiResponse.Schema = { "maximum": 100, "required": false }, - "search": { - "description": "Limit results to those matching a string.", - "type": "string", - "required": false - }, - "exclude": { - "description": "Ensure result set excludes specific IDs.", - "type": "array", - "items": { - "type": "integer" - }, - "default": [], - "required": false - }, - "include": { - "description": "Limit result set to specific IDs.", - "type": "array", - "items": { - "type": "integer" - }, - "default": [], - "required": false - }, "offset": { "description": "Offset the result set by a specific number of items.", "type": "integer", "required": false - }, - "order": { - "description": "Order sort attribute ascending or descending.", - "type": "string", - "default": "desc", - "enum": [ - "asc", - "desc" - ], - "required": false - }, - "orderby": { - "description": "Sort collection by object attribute.", - "type": "string", - "default": "date", - "enum": [ - "date", - "id", - "include", - "relevance", - "slug", - "include_slugs", - "title" - ], - "required": false } } } From b43344dbdcc5dc08b78af6461154a2a556f7fe1f Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 1 Feb 2024 08:49:29 +1100 Subject: [PATCH 11/25] Now that https://github.com/WordPress/wordpress-develop/pull/5655 has landed, use inherited methods for getting individual items. --- ...est-global-styles-revisions-controller.php | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index c71ada44364ef..0f780a83e44d8 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -246,56 +246,6 @@ public function get_items( $request ) { return $response; } - /** - * Retrieves one global styles revision from the collection. - * - * @since 6.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - $parent = $this->get_parent( $request['parent'] ); - if ( is_wp_error( $parent ) ) { - return $parent; - } - - $revision = $this->get_revision( $request['id'] ); - if ( is_wp_error( $revision ) ) { - return $revision; - } - - $response = $this->prepare_item_for_response( $revision, $request ); - return rest_ensure_response( $response ); - } - - /** - * Gets the global styles revision, if the ID is valid. - * - * @since 6.5.0 - * - * @param int $id Supplied ID. - * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. - */ - protected function get_revision( $id ) { - $error = new WP_Error( - 'rest_post_invalid_id', - __( 'Invalid global styles revision ID.' ), - array( 'status' => 404 ) - ); - - if ( (int) $id <= 0 ) { - return $error; - } - - $revision = get_post( (int) $id ); - if ( empty( $revision ) || empty( $revision->ID ) || 'revision' !== $revision->post_type ) { - return $error; - } - - return $revision; - } - /** * Prepares the revision for the REST response. * From dac8e0b0d6c098f82a44e624ed8abb2f19113577 Mon Sep 17 00:00:00 2001 From: ramon Date: Wed, 7 Feb 2024 12:28:03 +1100 Subject: [PATCH 12/25] Pulling across changes from https://github.com/WordPress/wordpress-develop/pull/6022 Updating generated API file --- src/wp-includes/class-wp-post-type.php | 3 +- src/wp-includes/post.php | 26 +- src/wp-includes/rest-api.php | 8 - ...class-wp-rest-global-styles-controller.php | 64 +-- ...est-global-styles-revisions-controller.php | 18 +- tests/qunit/fixtures/wp-api-generated.js | 433 ++++++++++-------- 6 files changed, 280 insertions(+), 272 deletions(-) diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php index 7a2769ed88327..9d22e2617b639 100644 --- a/src/wp-includes/class-wp-post-type.php +++ b/src/wp-includes/class-wp-post-type.php @@ -913,6 +913,7 @@ public function get_revisions_rest_controller() { * Will only instantiate the controller class once per request. * * @since 6.4.0 + * @since 6.5.0 Prevents autosave class instantiation for wp_global_styles post types. * * @return WP_REST_Controller|null The controller instance, or null if the post type * is set not to show in rest. @@ -922,7 +923,7 @@ public function get_autosave_rest_controller() { return null; } - if ( 'attachment' === $this->name ) { + if ( in_array( $this->name, array( 'attachment', 'wp_global_styles' ), true ) ) { return null; } diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 08cb5fb2cacf9..722c979056424 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -473,15 +473,19 @@ function create_initial_post_types() { register_post_type( 'wp_global_styles', array( - 'label' => _x( 'Global Styles', 'post type general name' ), - 'description' => __( 'Global styles to include in themes.' ), - 'public' => false, - '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ - 'show_ui' => false, - 'show_in_rest' => false, - 'rewrite' => false, - 'capabilities' => array( + 'label' => _x( 'Global Styles', 'post type general name' ), + 'description' => __( 'Global styles to include in themes.' ), + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */ + 'show_ui' => false, + 'show_in_rest' => true, + 'rewrite' => false, + 'rest_base' => 'global-styles', + 'rest_controller_class' => 'WP_REST_Global_Styles_Controller', + 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller', + 'late_route_registration' => true, + 'capabilities' => array( 'read' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', @@ -490,8 +494,8 @@ function create_initial_post_types() { 'edit_others_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', ), - 'map_meta_cap' => true, - 'supports' => array( + 'map_meta_cap' => true, + 'supports' => array( 'title', 'editor', 'revisions', diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 2631a6663fe92..2dead4ad8f2f0 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -323,14 +323,6 @@ function create_initial_rest_routes() { $controller = new WP_REST_Block_Types_Controller(); $controller->register_routes(); - // Global Styles revisions. - $controller = new WP_REST_Global_Styles_Revisions_Controller(); - $controller->register_routes(); - - // Global Styles. - $controller = new WP_REST_Global_Styles_Controller(); - $controller->register_routes(); - // Settings. $controller = new WP_REST_Settings_Controller(); $controller->register_routes(); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 9837f535e268d..dd84c2b393c40 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -10,24 +10,20 @@ /** * Base Global Styles REST API Controller. */ -class WP_REST_Global_Styles_Controller extends WP_REST_Controller { - - /** - * Post type. - * - * @since 5.9.0 - * @var string - */ - protected $post_type; - +class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { /** * Constructor. + * * @since 5.9.0 + * @since 6.5.0 Extends class from WP_REST_Posts_Controller. + * + * @param string $post_type Post type. */ - public function __construct() { - $this->namespace = 'wp/v2'; - $this->rest_base = 'global-styles'; - $this->post_type = 'wp_global_styles'; + public function __construct( $post_type ) { + $this->post_type = $post_type; + $obj = get_post_type_object( $post_type ); + $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; + $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; } /** @@ -194,7 +190,7 @@ public function get_item_permissions_check( $request ) { * @param WP_Post $post Post object. * @return bool Whether the post can be read. */ - protected function check_read_permission( $post ) { + public function check_read_permission( $post ) { return current_user_can( 'read_post', $post->ID ); } @@ -241,18 +237,6 @@ public function update_item_permissions_check( $request ) { return true; } - /** - * Checks if a global style can be edited. - * - * @since 5.9.0 - * - * @param WP_Post $post Post object. - * @return bool Whether the post can be edited. - */ - protected function check_update_permission( $post ) { - return current_user_can( 'edit_post', $post->ID ); - } - /** * Updates a single global style config. * @@ -407,7 +391,7 @@ public function prepare_item_for_response( $post, $request ) { $links = $this->prepare_links( $post->ID ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { - $actions = $this->get_available_actions(); + $actions = $this->get_available_actions( $post, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); @@ -431,9 +415,12 @@ protected function prepare_links( $id ) { $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); $links = array( - 'self' => array( + 'self' => array( 'href' => rest_url( trailingslashit( $base ) . $id ), ), + 'about' => array( + 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), + ), ); if ( post_type_supports( $this->post_type, 'revisions' ) ) { @@ -457,10 +444,10 @@ protected function prepare_links( $id ) { * * @return array List of link relations. */ - protected function get_available_actions() { + protected function get_available_actions( $post, $request ) { $rels = array(); - $post_type = get_post_type_object( $this->post_type ); + $post_type = get_post_type_object( $post->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } @@ -472,21 +459,6 @@ protected function get_available_actions() { return $rels; } - /** - * Overwrites the default protected title format. - * - * By default, WordPress will show password protected posts with a title of - * "Protected: %s", as the REST API communicates the protected status of a post - * in a machine readable format, we remove the "Protected: " prefix. - * - * @since 5.9.0 - * - * @return string Protected title format. - */ - public function protected_title_format() { - return '%s'; - } - /** * Retrieves the query params for the global styles collection. * diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 0f780a83e44d8..ce484f3880161 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -35,13 +35,21 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr * Constructor. * * @since 6.3.0 + * @since 6.5.0 Extends class from WP_REST_Revisions_Controller. */ - public function __construct() { - parent::__construct( 'wp_global_styles' ); - $this->parent_controller = new WP_REST_Global_Styles_Controller(); + public function __construct( $parent_post_type ) { + parent::__construct( $parent_post_type ); + $post_type_object = get_post_type_object( $parent_post_type ); + $parent_controller = $post_type_object->get_rest_controller(); + + if ( ! $parent_controller ) { + $parent_controller = new WP_REST_Global_Styles_Controller( $parent_post_type ); + } + + $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; - $this->parent_base = $this->parent_controller->rest_base; - $this->namespace = $this->parent_controller->namespace; + $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; + $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 6c961548eb8e2..dada5781daa24 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -5811,6 +5811,207 @@ mockedApiResponse.Schema = { } ] }, + "/wp/v2/global-styles/(?P[\\d]+)/revisions": { + "namespace": "wp/v2", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "parent": { + "description": "The ID for the parent of the revision.", + "type": "integer", + "required": false + }, + "context": { + "description": "Scope under which the request is made; determines fields present in response.", + "type": "string", + "enum": [ + "view", + "embed", + "edit" + ], + "default": "view", + "required": false + }, + "page": { + "description": "Current page of the collection.", + "type": "integer", + "default": 1, + "minimum": 1, + "required": false + }, + "per_page": { + "description": "Maximum number of items to be returned in result set.", + "type": "integer", + "minimum": 1, + "maximum": 100, + "required": false + }, + "offset": { + "description": "Offset the result set by a specific number of items.", + "type": "integer", + "required": false + } + } + } + ] + }, + "/wp/v2/global-styles/(?P[\\d]+)/revisions/(?P[\\d]+)": { + "namespace": "wp/v2", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "parent": { + "description": "The ID for the parent of the global styles revision.", + "type": "integer", + "required": false + }, + "id": { + "description": "Unique identifier for the global styles revision.", + "type": "integer", + "required": false + }, + "context": { + "description": "Scope under which the request is made; determines fields present in response.", + "type": "string", + "enum": [ + "view", + "embed", + "edit" + ], + "default": "view", + "required": false + } + } + } + ] + }, + "/wp/v2/global-styles/themes/(?P[\\/\\s%\\w\\.\\(\\)\\[\\]\\@_\\-]+)/variations": { + "namespace": "wp/v2", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "stylesheet": { + "description": "The theme identifier", + "type": "string", + "required": false + } + } + } + ] + }, + "/wp/v2/global-styles/themes/(?P[^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)": { + "namespace": "wp/v2", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "stylesheet": { + "description": "The theme identifier", + "type": "string", + "required": false + } + } + } + ] + }, + "/wp/v2/global-styles/(?P[\\/\\w-]+)": { + "namespace": "wp/v2", + "methods": [ + "GET", + "POST", + "PUT", + "PATCH" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "id": { + "description": "The id of a template", + "type": "string", + "required": false + } + } + }, + { + "methods": [ + "POST", + "PUT", + "PATCH" + ], + "args": { + "styles": { + "description": "Global styles.", + "type": [ + "object" + ], + "required": false + }, + "settings": { + "description": "Global settings.", + "type": [ + "object" + ], + "required": false + }, + "title": { + "description": "Title of the global styles variation.", + "type": [ + "object", + "string" + ], + "properties": { + "raw": { + "description": "Title for the global styles variation, as it exists in the database.", + "type": "string", + "context": [ + "view", + "edit", + "embed" + ] + }, + "rendered": { + "description": "HTML title for the post, transformed for display.", + "type": "string", + "context": [ + "view", + "edit", + "embed" + ], + "readonly": true + } + }, + "required": false + } + } + } + ] + }, "/wp/v2/navigation": { "namespace": "wp/v2", "methods": [ @@ -8784,6 +8985,7 @@ mockedApiResponse.Schema = { "wp_block": "wp_block", "wp_template": "wp_template", "wp_template_part": "wp_template_part", + "wp_global_styles": "wp_global_styles", "wp_navigation": "wp_navigation", "attachment": "attachment" } @@ -9994,207 +10196,6 @@ mockedApiResponse.Schema = { } ] }, - "/wp/v2/global-styles/(?P[\\d]+)/revisions": { - "namespace": "wp/v2", - "methods": [ - "GET" - ], - "endpoints": [ - { - "methods": [ - "GET" - ], - "args": { - "parent": { - "description": "The ID for the parent of the revision.", - "type": "integer", - "required": false - }, - "context": { - "description": "Scope under which the request is made; determines fields present in response.", - "type": "string", - "enum": [ - "view", - "embed", - "edit" - ], - "default": "view", - "required": false - }, - "page": { - "description": "Current page of the collection.", - "type": "integer", - "default": 1, - "minimum": 1, - "required": false - }, - "per_page": { - "description": "Maximum number of items to be returned in result set.", - "type": "integer", - "minimum": 1, - "maximum": 100, - "required": false - }, - "offset": { - "description": "Offset the result set by a specific number of items.", - "type": "integer", - "required": false - } - } - } - ] - }, - "/wp/v2/global-styles/(?P[\\d]+)/revisions/(?P[\\d]+)": { - "namespace": "wp/v2", - "methods": [ - "GET" - ], - "endpoints": [ - { - "methods": [ - "GET" - ], - "args": { - "parent": { - "description": "The ID for the parent of the global styles revision.", - "type": "integer", - "required": false - }, - "id": { - "description": "Unique identifier for the global styles revision.", - "type": "integer", - "required": false - }, - "context": { - "description": "Scope under which the request is made; determines fields present in response.", - "type": "string", - "enum": [ - "view", - "embed", - "edit" - ], - "default": "view", - "required": false - } - } - } - ] - }, - "/wp/v2/global-styles/themes/(?P[\\/\\s%\\w\\.\\(\\)\\[\\]\\@_\\-]+)/variations": { - "namespace": "wp/v2", - "methods": [ - "GET" - ], - "endpoints": [ - { - "methods": [ - "GET" - ], - "args": { - "stylesheet": { - "description": "The theme identifier", - "type": "string", - "required": false - } - } - } - ] - }, - "/wp/v2/global-styles/themes/(?P[^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)": { - "namespace": "wp/v2", - "methods": [ - "GET" - ], - "endpoints": [ - { - "methods": [ - "GET" - ], - "args": { - "stylesheet": { - "description": "The theme identifier", - "type": "string", - "required": false - } - } - } - ] - }, - "/wp/v2/global-styles/(?P[\\/\\w-]+)": { - "namespace": "wp/v2", - "methods": [ - "GET", - "POST", - "PUT", - "PATCH" - ], - "endpoints": [ - { - "methods": [ - "GET" - ], - "args": { - "id": { - "description": "The id of a template", - "type": "string", - "required": false - } - } - }, - { - "methods": [ - "POST", - "PUT", - "PATCH" - ], - "args": { - "styles": { - "description": "Global styles.", - "type": [ - "object" - ], - "required": false - }, - "settings": { - "description": "Global settings.", - "type": [ - "object" - ], - "required": false - }, - "title": { - "description": "Title of the global styles variation.", - "type": [ - "object", - "string" - ], - "properties": { - "raw": { - "description": "Title for the global styles variation, as it exists in the database.", - "type": "string", - "context": [ - "view", - "edit", - "embed" - ] - }, - "rendered": { - "description": "HTML title for the post, transformed for display.", - "type": "string", - "context": [ - "view", - "edit", - "embed" - ], - "readonly": true - } - }, - "required": false - } - } - } - ] - }, "/wp/v2/settings": { "namespace": "wp/v2", "methods": [ @@ -12511,6 +12512,36 @@ mockedApiResponse.TypesCollection = { ] } }, + "wp_global_styles": { + "description": "Global styles to include in themes.", + "hierarchical": false, + "has_archive": false, + "name": "Global Styles", + "slug": "wp_global_styles", + "icon": null, + "taxonomies": [], + "rest_base": "global-styles", + "rest_namespace": "wp/v2", + "_links": { + "collection": [ + { + "href": "http://example.org/index.php?rest_route=/wp/v2/types" + } + ], + "wp:items": [ + { + "href": "http://example.org/index.php?rest_route=/wp/v2/global-styles" + } + ], + "curies": [ + { + "name": "wp", + "href": "https://api.w.org/{rel}", + "templated": true + } + ] + } + }, "wp_navigation": { "description": "Navigation menus that can be inserted into your site.", "hierarchical": false, From acd25903a63357e3a2ba1dc798878b7fc3d163d3 Mon Sep 17 00:00:00 2001 From: ramon Date: Thu, 8 Feb 2024 14:13:49 +1100 Subject: [PATCH 13/25] Implementing latest round of feedback: removing __construct, get_item and update_item in favour of the parent class methods Add $allow_batch property, setting it to false --- ...class-wp-rest-global-styles-controller.php | 70 ++----------------- 1 file changed, 4 insertions(+), 66 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index dd84c2b393c40..4be50bbba11d3 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -12,19 +12,12 @@ */ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { /** - * Constructor. + * Whether the controller supports batching. * - * @since 5.9.0 - * @since 6.5.0 Extends class from WP_REST_Posts_Controller. - * - * @param string $post_type Post type. + * @since 6.5.0 + * @var array */ - public function __construct( $post_type ) { - $this->post_type = $post_type; - $obj = get_post_type_object( $post_type ); - $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; - $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; - } + protected $allow_batch = array( 'v1' => false ); /** * Registers the controllers routes. @@ -194,24 +187,6 @@ public function check_read_permission( $post ) { return current_user_can( 'read_post', $post->ID ); } - /** - * Returns the given global styles config. - * - * @since 5.9.0 - * - * @param WP_REST_Request $request The request instance. - * - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $post = $this->get_post( $request['id'] ); - if ( is_wp_error( $post ) ) { - return $post; - } - - return $this->prepare_item_for_response( $post, $request ); - } - /** * Checks if a given request has access to write a single global styles config. * @@ -237,43 +212,6 @@ public function update_item_permissions_check( $request ) { return true; } - /** - * Updates a single global style config. - * - * @since 5.9.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function update_item( $request ) { - $post_before = $this->get_post( $request['id'] ); - if ( is_wp_error( $post_before ) ) { - return $post_before; - } - - $changes = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $changes ) ) { - return $changes; - } - - $result = wp_update_post( wp_slash( (array) $changes ), true, false ); - if ( is_wp_error( $result ) ) { - return $result; - } - - $post = get_post( $request['id'] ); - $fields_update = $this->update_additional_fields_for_object( $post, $request ); - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - wp_after_insert_post( $post, true, $post_before ); - - $response = $this->prepare_item_for_response( $post, $request ); - - return rest_ensure_response( $response ); - } - /** * Prepares a single global styles config for update. * From dfa02f86cfebd43b240d0ee0e7475e8b08bef1dd Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 13:28:55 +0000 Subject: [PATCH 14/25] Apply suggestions from code review Co-authored-by: Jonny Harris <148061917+jonnynews@users.noreply.github.com> --- .../endpoints/class-wp-rest-global-styles-controller.php | 3 +++ .../class-wp-rest-global-styles-revisions-controller.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 4be50bbba11d3..2fe5fa2f804ca 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -379,7 +379,10 @@ protected function prepare_links( $id ) { * * @since 5.9.0 * @since 6.2.0 Added 'edit-css' action. + * @since 6.5.0 Add $post and $request parameters. * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. * @return array List of link relations. */ protected function get_available_actions( $post, $request ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index ce484f3880161..de64c68c5030c 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -36,6 +36,8 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr * * @since 6.3.0 * @since 6.5.0 Extends class from WP_REST_Revisions_Controller. + * + * @param string $parent_post_type Post type of the parent. */ public function __construct( $parent_post_type ) { parent::__construct( $parent_post_type ); From f6f45e377664f4e0f7fde1aed342e17d74f285ff Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 13:31:27 +0000 Subject: [PATCH 15/25] Fix lints --- .idea/inspectionProfiles/Project_Default.xml | 9 + .idea/jsLinters/jshint.xml | 16 ++ .idea/php.xml | 69 +++++ .idea/phpunit.xml | 11 + .idea/vcs.xml | 8 + .idea/workspace.xml | 239 ++++++++++++++++++ ...class-wp-rest-global-styles-controller.php | 2 +- ...est-global-styles-revisions-controller.php | 4 +- 8 files changed, 355 insertions(+), 3 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jsLinters/jshint.xml create mode 100644 .idea/php.xml create mode 100644 .idea/phpunit.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000..cab9d50c96f2c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/.idea/jsLinters/jshint.xml b/.idea/jsLinters/jshint.xml new file mode 100644 index 0000000000000..f8edcfafe4ae8 --- /dev/null +++ b/.idea/jsLinters/jshint.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000000000..2d4473c8aa9d5 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml new file mode 100644 index 0000000000000..9f370eb6dfe41 --- /dev/null +++ b/.idea/phpunit.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000..67f6fa11fff0d --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000000000..6f7319c8d6197 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + $PROJECT_DIR$/composer.json + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + "associatedIndex": 5 +} + + + + + + + + + + + + + + + + + + + + + 1701467759769 + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/tests/phpunit/tests/rest-api/rest-posts-controller.php + 4804 + + + + + \ No newline at end of file diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 2fe5fa2f804ca..e2f19e6d9aeb1 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -379,7 +379,7 @@ protected function prepare_links( $id ) { * * @since 5.9.0 * @since 6.2.0 Added 'edit-css' action. - * @since 6.5.0 Add $post and $request parameters. + * @since 6.5.0 Add $post and $request parameters. * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index de64c68c5030c..849f5be5cd2d6 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -41,8 +41,8 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr */ public function __construct( $parent_post_type ) { parent::__construct( $parent_post_type ); - $post_type_object = get_post_type_object( $parent_post_type ); - $parent_controller = $post_type_object->get_rest_controller(); + $post_type_object = get_post_type_object( $parent_post_type ); + $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Global_Styles_Controller( $parent_post_type ); From 038331bc65b92e03e8b1048e976e28683a163b86 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 13:31:43 +0000 Subject: [PATCH 16/25] Remove ideas --- .idea/inspectionProfiles/Project_Default.xml | 9 - .idea/jsLinters/jshint.xml | 16 -- .idea/php.xml | 69 ------ .idea/phpunit.xml | 11 - .idea/vcs.xml | 8 - .idea/workspace.xml | 239 ------------------- 6 files changed, 352 deletions(-) delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/jsLinters/jshint.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/phpunit.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index cab9d50c96f2c..0000000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/jsLinters/jshint.xml b/.idea/jsLinters/jshint.xml deleted file mode 100644 index f8edcfafe4ae8..0000000000000 --- a/.idea/jsLinters/jshint.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index 2d4473c8aa9d5..0000000000000 --- a/.idea/php.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml deleted file mode 100644 index 9f370eb6dfe41..0000000000000 --- a/.idea/phpunit.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 67f6fa11fff0d..0000000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 6f7319c8d6197..0000000000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - - - - - - - $PROJECT_DIR$/composer.json - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - "associatedIndex": 5 -} - - - - - - - - - - - - - - - - - - - - - 1701467759769 - - - - - - - - - - - - - - - - - - - - - - - - - file://$PROJECT_DIR$/tests/phpunit/tests/rest-api/rest-posts-controller.php - 4804 - - - - - \ No newline at end of file From 95db1e9e668861c48ed974dd6562c8d1c63adf7d Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 15:41:36 +0000 Subject: [PATCH 17/25] Fix --- ...lass-wp-rest-global-styles-revisions-controller.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 849f5be5cd2d6..78c933d6fdc29 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -31,6 +31,14 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr */ protected $parent_base; + /** + * Parent post type. + * + * @since 6.5.0 + * @var string + */ + protected $parent_post_type; + /** * Constructor. * @@ -39,7 +47,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr * * @param string $parent_post_type Post type of the parent. */ - public function __construct( $parent_post_type ) { + public function __construct( $parent_post_type = 'wp_global_styles' ) { parent::__construct( $parent_post_type ); $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); From 9fb3e306e8ad39fe19ce0b3678add516ddc3059e Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 20:41:44 +0000 Subject: [PATCH 18/25] Add allow_batch parameter. --- .../endpoints/class-wp-rest-global-styles-controller.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index e2f19e6d9aeb1..eaf62b1eb02a1 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -39,6 +39,7 @@ public function register_routes() { 'type' => 'string', ), ), + 'allow_batch' => $this->allow_batch, ), ) ); @@ -68,6 +69,7 @@ public function register_routes() { 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), ), ), + 'allow_batch' => $this->allow_batch, ), ) ); @@ -95,7 +97,8 @@ public function register_routes() { 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), - 'schema' => array( $this, 'get_public_item_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), + 'allow_batch' => $this->allow_batch, ) ); } From 319bdff1a1a3c4abcd66e5c7604ee80a8fda368b Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 20:45:22 +0000 Subject: [PATCH 19/25] Be overly safe with `__construct` method. --- .../class-wp-rest-global-styles-controller.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index eaf62b1eb02a1..85f9f4da0cec9 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -19,6 +19,17 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { */ protected $allow_batch = array( 'v1' => false ); + /** + * Constructor. + * + * @since 6.5.0 + * + * @param string $post_type Post type. + */ + public function __construct( $post_type = 'wp_global_styles' ) { + parent::__construct( $post_type ); + } + /** * Registers the controllers routes. * From 095c7d007e8c620315847964243bbe12da2767e2 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 20:46:33 +0000 Subject: [PATCH 20/25] Apply suggestions from code review --- .../endpoints/class-wp-rest-global-styles-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 85f9f4da0cec9..41c8d93fce436 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -393,7 +393,7 @@ protected function prepare_links( $id ) { * * @since 5.9.0 * @since 6.2.0 Added 'edit-css' action. - * @since 6.5.0 Add $post and $request parameters. + * @since 6.5.0 Added $post and $request parameters. * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. From 1fef99705eff7fc55ad682f94b9030412cdfd123 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Tue, 13 Feb 2024 21:18:44 +0000 Subject: [PATCH 21/25] Add 'allow_batch' option to API endpoints in WP API This commit adds the 'allow_batch' option to several API endpoints in the WordPress API generated tests fixture. The 'allow_batch' option has been set to false for version 1, effectively disabling batch requests for these endpoints, as a safety measure. --- tests/qunit/fixtures/wp-api-generated.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 5da6a693d4b9e..e00e67289bf32 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -5907,6 +5907,9 @@ mockedApiResponse.Schema = { "methods": [ "GET" ], + "allow_batch": { + "v1": false + }, "args": { "stylesheet": { "description": "The theme identifier", @@ -5927,6 +5930,9 @@ mockedApiResponse.Schema = { "methods": [ "GET" ], + "allow_batch": { + "v1": false + }, "args": { "stylesheet": { "description": "The theme identifier", @@ -5950,6 +5956,9 @@ mockedApiResponse.Schema = { "methods": [ "GET" ], + "allow_batch": { + "v1": false + }, "args": { "id": { "description": "The id of a template", @@ -5964,6 +5973,9 @@ mockedApiResponse.Schema = { "PUT", "PATCH" ], + "allow_batch": { + "v1": false + }, "args": { "styles": { "description": "Global styles.", From 70d68da1fd4ce3a819f81bbe83df5d3ecaa00ac0 Mon Sep 17 00:00:00 2001 From: Jonny Harrus Date: Mon, 20 May 2024 22:45:51 +0100 Subject: [PATCH 22/25] Update version annotations for wp_global_styles related changes Various code documentation version annotations have been updated from 6.5.0 to 6.6.0. This includes adjustments in class-wp-post-type.php and the REST endpoints for global styles and global styles revisions. These changes document accurately in which version these alterations were introduced. --- src/wp-includes/class-wp-post-type.php | 2 +- .../class-wp-rest-global-styles-controller.php | 6 +++--- ...ss-wp-rest-global-styles-revisions-controller.php | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php index 9d22e2617b639..2b05d795bbb90 100644 --- a/src/wp-includes/class-wp-post-type.php +++ b/src/wp-includes/class-wp-post-type.php @@ -913,7 +913,7 @@ public function get_revisions_rest_controller() { * Will only instantiate the controller class once per request. * * @since 6.4.0 - * @since 6.5.0 Prevents autosave class instantiation for wp_global_styles post types. + * @since 6.6.0 Prevents autosave class instantiation for wp_global_styles post types. * * @return WP_REST_Controller|null The controller instance, or null if the post type * is set not to show in rest. diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 41c8d93fce436..e9d5006d53b14 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -14,7 +14,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { /** * Whether the controller supports batching. * - * @since 6.5.0 + * @since 6.6.0 * @var array */ protected $allow_batch = array( 'v1' => false ); @@ -22,7 +22,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { /** * Constructor. * - * @since 6.5.0 + * @since 6.6.0 * * @param string $post_type Post type. */ @@ -393,7 +393,7 @@ protected function prepare_links( $id ) { * * @since 5.9.0 * @since 6.2.0 Added 'edit-css' action. - * @since 6.5.0 Added $post and $request parameters. + * @since 6.6.0 Added $post and $request parameters. * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 78c933d6fdc29..7e5c9af043e31 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -18,7 +18,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr /** * Parent controller. * - * @since 6.5.0 + * @since 6.6.0 * @var WP_REST_Controller */ private $parent_controller; @@ -34,7 +34,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr /** * Parent post type. * - * @since 6.5.0 + * @since 6.6.0 * @var string */ protected $parent_post_type; @@ -43,7 +43,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr * Constructor. * * @since 6.3.0 - * @since 6.5.0 Extends class from WP_REST_Revisions_Controller. + * @since 6.6.0 Extends class from WP_REST_Revisions_Controller. * * @param string $parent_post_type Post type of the parent. */ @@ -66,7 +66,7 @@ public function __construct( $parent_post_type = 'wp_global_styles' ) { * Registers the controller's routes. * * @since 6.3.0 - * @since 6.5.0 Added route to fetch individual global styles revisions. + * @since 6.6.0 Added route to fetch individual global styles revisions. */ public function register_routes() { register_rest_route( @@ -333,7 +333,7 @@ public function prepare_item_for_response( $post, $request ) { * Retrieves the revision's schema, conforming to JSON Schema. * * @since 6.3.0 - * @since 6.5.0 Merged parent and parent controller schema data. + * @since 6.6.0 Merged parent and parent controller schema data. * * @return array Item schema data. */ @@ -361,7 +361,7 @@ public function get_item_schema() { * Retrieves the query params for collections. * Removes params that are not supported by global styles revisions. * - * @since 6.5.0 + * @since 6.6.0 * * @return array Collection parameters. */ From c62fed9b8f8c1403f7ee4c06151d833a9b8fcd3f Mon Sep 17 00:00:00 2001 From: Jonny Harrus Date: Mon, 20 May 2024 22:50:07 +0100 Subject: [PATCH 23/25] Simplify unset function calls in global styles revisions controller The commit transforms multiple unset function calls into single line statements in the WP Rest Global Styles Revisions Controller. This aims to enhance code readability and maintainability, without changing functionality. --- ...ss-wp-rest-global-styles-revisions-controller.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index 7e5c9af043e31..1980650ceb63c 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -346,11 +346,7 @@ public function get_item_schema() { $parent_schema = $this->parent_controller->get_item_schema(); $schema['properties'] = array_merge( $schema['properties'], $parent_schema['properties'] ); - unset( $schema['properties']['guid'] ); - unset( $schema['properties']['slug'] ); - unset( $schema['properties']['meta'] ); - unset( $schema['properties']['content'] ); - unset( $schema['properties']['title'] ); + unset( $schema['properties']['guid'], $schema['properties']['slug'], $schema['properties']['meta'], $schema['properties']['content'], $schema['properties']['title'] ); $this->schema = $schema; @@ -367,11 +363,7 @@ public function get_item_schema() { */ public function get_collection_params() { $query_params = parent::get_collection_params(); - unset( $query_params['exclude'] ); - unset( $query_params['include'] ); - unset( $query_params['search'] ); - unset( $query_params['order'] ); - unset( $query_params['orderby'] ); + unset( $query_params['exclude'], $query_params['include'], $query_params['search'], $query_params['order'], $query_params['orderby'] ); return $query_params; } } From 7c526bd178cde4fa54a7a22dcefeecf0599c971c Mon Sep 17 00:00:00 2001 From: Jonny Harrus Date: Thu, 23 May 2024 15:26:07 +0100 Subject: [PATCH 24/25] Disable autosave for global styles in WordPress The commit disables the autosave endpoints for the global styles in WordPress. Modifications were made to both post.php and class-wp-post-type.php to prevent autosave for the 'wp_global_styles' post type. This ensures that global Styles does not trigger unnecessary autosaves. --- src/wp-includes/class-wp-post-type.php | 2 +- src/wp-includes/post.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php index 2b05d795bbb90..bc4a4ce47d3be 100644 --- a/src/wp-includes/class-wp-post-type.php +++ b/src/wp-includes/class-wp-post-type.php @@ -923,7 +923,7 @@ public function get_autosave_rest_controller() { return null; } - if ( in_array( $this->name, array( 'attachment', 'wp_global_styles' ), true ) ) { + if ( 'attachment' === $this->name ) { return null; } diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index f177a1b7674b7..32b2b7c610d4b 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -487,6 +487,8 @@ function create_initial_post_types() { 'rest_base' => 'global-styles', 'rest_controller_class' => 'WP_REST_Global_Styles_Controller', 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller', + // Disable autosave endpoints for global styles. + 'autosave_rest_controller_class' => 'stdClass', 'late_route_registration' => true, 'capabilities' => array( 'read' => 'edit_theme_options', From fe4fc659603616b917345a96e6f94097ad7df555 Mon Sep 17 00:00:00 2001 From: Jonny Harrus Date: Thu, 23 May 2024 15:28:37 +0100 Subject: [PATCH 25/25] Remove redundant comment in wp-post-type.php This commit removes a comment line in the class-wp-post-type.php file. The deleted comment was linked to the autosave instantiation for the 'wp_global_styles' post types, which is no longer relevant within the current context. --- src/wp-includes/class-wp-post-type.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php index bc4a4ce47d3be..7a2769ed88327 100644 --- a/src/wp-includes/class-wp-post-type.php +++ b/src/wp-includes/class-wp-post-type.php @@ -913,7 +913,6 @@ public function get_revisions_rest_controller() { * Will only instantiate the controller class once per request. * * @since 6.4.0 - * @since 6.6.0 Prevents autosave class instantiation for wp_global_styles post types. * * @return WP_REST_Controller|null The controller instance, or null if the post type * is set not to show in rest.