Changeset 52342
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php
r52332 r52342 12 12 */ 13 13 class WP_REST_Global_Styles_Controller extends WP_REST_Controller { 14 15 /** 16 * Post type. 17 * 18 * @since 5.9.0 19 * @var string 20 */ 21 protected $post_type; 22 14 23 /** 15 24 * Constructor. … … 19 28 $this->namespace = 'wp/v2'; 20 29 $this->rest_base = 'global-styles'; 30 $this->post_type = 'wp_global_styles'; 21 31 } 22 32 … … 76 86 77 87 /** 78 * Checks if the user has permissions to make the request. 79 * 80 * @since 5.9.0 81 * 88 * Checks if a given request has access to read a single global style. 89 * 90 * @since 5.9.0 91 * 92 * @param WP_REST_Request $request Full details about the request. 82 93 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 83 94 */ 84 protected function permissions_check() { 85 // Verify if the current user has edit_theme_options capability. 86 // This capability is required to edit/view/delete templates. 87 if ( ! current_user_can( 'edit_theme_options' ) ) { 95 public function get_item_permissions_check( $request ) { 96 $post = $this->get_post( $request['id'] ); 97 if ( is_wp_error( $post ) ) { 98 return $post; 99 } 100 101 if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { 88 102 return new WP_Error( 89 'rest_cannot_manage_global_styles', 90 __( 'Sorry, you are not allowed to access the global styles on this site.' ), 91 array( 92 'status' => rest_authorization_required_code(), 93 ) 103 'rest_forbidden_context', 104 __( 'Sorry, you are not allowed to edit this global style.' ), 105 array( 'status' => rest_authorization_required_code() ) 94 106 ); 95 107 } 96 108 109 if ( ! $this->check_read_permission( $post ) ) { 110 return new WP_Error( 111 'rest_cannot_view', 112 __( 'Sorry, you are not allowed to view this global style.' ), 113 array( 'status' => rest_authorization_required_code() ) 114 ); 115 } 116 97 117 return true; 98 118 } 99 119 100 120 /** 101 * Checks if a given request has access to read a single global styles config. 102 * 103 * @param WP_REST_Request $request Full details about the request. 104 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. 105 */ 106 public function get_item_permissions_check( $request ) { 107 return $this->permissions_check( $request ); 121 * Checks if a global style can be read. 122 * 123 * @since 5.9.0 124 * 125 * @param WP_Post $post Post object. 126 * @return bool Whether the post can be read. 127 */ 128 protected function check_read_permission( $post ) { 129 return current_user_can( 'read_post', $post->ID ); 108 130 } 109 131 … … 118 140 */ 119 141 public function get_item( $request ) { 120 $post = get_post( $request['id'] );121 if ( ! $post || 'wp_global_styles' !== $post->post_type) {122 return new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exist with that id.' ), array( 'status' => 404 ) );142 $post = $this->get_post( $request['id'] ); 143 if ( is_wp_error( $post ) ) { 144 return $post; 123 145 } 124 146 … … 135 157 */ 136 158 public function update_item_permissions_check( $request ) { 137 return $this->permissions_check( $request ); 159 $post = $this->get_post( $request['id'] ); 160 if ( is_wp_error( $post ) ) { 161 return $post; 162 } 163 164 if ( $post && ! $this->check_update_permission( $post ) ) { 165 return new WP_Error( 166 'rest_cannot_edit', 167 __( 'Sorry, you are not allowed to edit this global style.' ), 168 array( 'status' => rest_authorization_required_code() ) 169 ); 170 } 171 172 return true; 173 } 174 175 /** 176 * Checks if a global style can be edited. 177 * 178 * @since 5.9.0 179 * 180 * @param WP_Post $post Post object. 181 * @return bool Whether the post can be edited. 182 */ 183 protected function check_update_permission( $post ) { 184 return current_user_can( 'edit_post', $post->ID ); 138 185 } 139 186 … … 147 194 */ 148 195 public function update_item( $request ) { 149 $post_before = get_post( $request['id'] );150 if ( ! $post_before || 'wp_global_styles' !== $post_before->post_type) {151 return new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exist with that id.' ), array( 'status' => 404 ) );196 $post_before = $this->get_post( $request['id'] ); 197 if ( is_wp_error( $post_before ) ) { 198 return $post_before; 152 199 } 153 200 … … 290 337 } 291 338 339 /** 340 * Get the post, if the ID is valid. 341 * 342 * @since 5.9.0 343 * 344 * @param int $id Supplied ID. 345 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. 346 */ 347 protected function get_post( $id ) { 348 $error = new WP_Error( 349 'rest_global_styles_not_found', 350 __( 'No global styles config exist with that id.' ), 351 array( 'status' => 404 ) 352 ); 353 354 $id = (int) $id; 355 if ( $id <= 0 ) { 356 return $error; 357 } 358 359 $post = get_post( $id ); 360 if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { 361 return $error; 362 } 363 364 return $post; 365 } 366 292 367 293 368 /** … … 324 399 $rels = array(); 325 400 326 $post_type = get_post_type_object( 'wp_global_styles');401 $post_type = get_post_type_object( $this->post_type ); 327 402 if ( current_user_can( $post_type->cap->publish_posts ) ) { 328 403 $rels[] = 'https://api.w.org/action-publish'; … … 372 447 $schema = array( 373 448 '$schema' => 'http://json-schema.org/draft-04/schema#', 374 'title' => 'wp_global_styles',449 'title' => $this->post_type, 375 450 'type' => 'object', 376 451 'properties' => array( … … 427 502 */ 428 503 public function get_theme_item_permissions_check( $request ) { 429 return $this->permissions_check( $request ); 504 // Verify if the current user has edit_theme_options capability. 505 // This capability is required to edit/view/delete templates. 506 if ( ! current_user_can( 'edit_theme_options' ) ) { 507 return new WP_Error( 508 'rest_cannot_manage_global_styles', 509 __( 'Sorry, you are not allowed to access the global styles on this site.' ), 510 array( 511 'status' => rest_authorization_required_code(), 512 ) 513 ); 514 } 515 516 return true; 430 517 } 431 518 -
trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php
r52282 r52342 8 8 9 9 /** 10 * @covers WP_REST_Global_Styles_Controller 10 11 * @group restapi-global-styles 11 12 * @group restapi … … 20 21 * @var int 21 22 */ 23 protected static $subscriber_id; 24 25 /** 26 * @var int 27 */ 22 28 protected static $global_styles_id; 29 30 /** 31 * @var int 32 */ 33 protected static $post_id; 23 34 24 35 private function find_and_normalize_global_styles_by_id( $global_styles, $id ) { … … 49 60 ) 50 61 ); 62 63 self::$subscriber_id = $factory->user->create( 64 array( 65 'role' => 'subscriber', 66 ) 67 ); 68 51 69 // This creates the global styles for the current theme. 52 self::$global_styles_id = wp_insert_post(70 self::$global_styles_id = $factory->post->create( 53 71 array( 54 72 'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', … … 60 78 'wp_theme' => 'tt1-blocks', 61 79 ), 62 ), 63 true 64 ); 65 } 66 80 ) 81 ); 82 83 self::$post_id = $factory->post->create(); 84 } 85 86 /** 87 * 88 */ 89 public static function wpTearDownAfterClass() { 90 self::delete_user( self::$admin_id ); 91 self::delete_user( self::$subscriber_id ); 92 } 93 94 /** 95 * @covers WP_REST_Global_Styles_Controller::register_routes 96 */ 67 97 public function test_register_routes() { 68 98 $routes = rest_get_server()->get_routes(); 69 99 $this->assertArrayHasKey( '/wp/v2/global-styles/(?P<id>[\/\w-]+)', $routes ); 100 $this->assertCount( 2, $routes['/wp/v2/global-styles/(?P<id>[\/\w-]+)'] ); 101 $this->assertArrayHasKey( '/wp/v2/global-styles/themes/(?P<stylesheet>[^.\/]+(?:\/[^.\/]+)?)', $routes ); 102 $this->assertCount( 1, $routes['/wp/v2/global-styles/themes/(?P<stylesheet>[^.\/]+(?:\/[^.\/]+)?)'] ); 70 103 } 71 104 72 105 public function test_context_param() { 73 // TODO: Implement test_context_param() method. 74 $this->markTestIncomplete(); 106 $this->markTestSkipped( 'Controller does not implement context_param().' ); 75 107 } 76 108 77 109 public function test_get_items() { 78 $this->markTestIncomplete(); 79 } 80 110 $this->markTestSkipped( 'Controller does not implement get_items().' ); 111 } 112 113 /** 114 * @covers WP_REST_Global_Styles_Controller::get_theme_item 115 * @ticket 54516 116 */ 117 public function test_get_theme_item_no_user() { 118 wp_set_current_user( 0 ); 119 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 120 $response = rest_get_server()->dispatch( $request ); 121 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 401 ); 122 } 123 124 /** 125 * @covers WP_REST_Global_Styles_Controller::get_theme_item 126 * @ticket 54516 127 */ 128 public function test_get_theme_item_permission_check() { 129 wp_set_current_user( self::$subscriber_id ); 130 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 131 $response = rest_get_server()->dispatch( $request ); 132 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 403 ); 133 } 134 135 136 /** 137 * @covers WP_REST_Global_Styles_Controller::get_theme_item 138 * @ticket 54516 139 */ 140 public function test_get_theme_item_invalid() { 141 wp_set_current_user( self::$admin_id ); 142 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/invalid' ); 143 $response = rest_get_server()->dispatch( $request ); 144 $this->assertErrorResponse( 'rest_theme_not_found', $response, 404 ); 145 } 146 147 /** 148 * @covers WP_REST_Global_Styles_Controller::get_theme_item 149 */ 150 public function test_get_theme_item() { 151 wp_set_current_user( self::$admin_id ); 152 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 153 $response = rest_get_server()->dispatch( $request ); 154 $data = $response->get_data(); 155 unset( $data['_links'] ); 156 157 $this->assertArrayHasKey( 'settings', $data ); 158 $this->assertArrayHasKey( 'styles', $data ); 159 } 160 161 /** 162 * @covers WP_REST_Global_Styles_Controller::get_item 163 * @ticket 54516 164 */ 165 public function test_get_item_no_user() { 166 wp_set_current_user( 0 ); 167 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 168 $response = rest_get_server()->dispatch( $request ); 169 $this->assertErrorResponse( 'rest_cannot_view', $response, 401 ); 170 } 171 172 /** 173 * @covers WP_REST_Global_Styles_Controller::get_item 174 * @ticket 54516 175 */ 176 public function test_get_item_invalid_post() { 177 wp_set_current_user( self::$admin_id ); 178 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$post_id ); 179 $response = rest_get_server()->dispatch( $request ); 180 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 ); 181 } 182 183 /** 184 * @covers WP_REST_Global_Styles_Controller::get_item 185 * @ticket 54516 186 */ 187 public function test_get_item_permission_check() { 188 wp_set_current_user( self::$subscriber_id ); 189 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 190 $response = rest_get_server()->dispatch( $request ); 191 $this->assertErrorResponse( 'rest_cannot_view', $response, 403 ); 192 } 193 194 /** 195 * @covers WP_REST_Global_Styles_Controller::get_item 196 * @ticket 54516 197 */ 198 public function test_get_item_no_user_edit() { 199 wp_set_current_user( 0 ); 200 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 201 $request->set_param( 'context', 'edit' ); 202 $response = rest_get_server()->dispatch( $request ); 203 $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 ); 204 } 205 206 /** 207 * @covers WP_REST_Global_Styles_Controller::get_item 208 * @ticket 54516 209 */ 210 public function test_get_item_permission_check_edit() { 211 wp_set_current_user( self::$subscriber_id ); 212 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 213 $request->set_param( 'context', 'edit' ); 214 $response = rest_get_server()->dispatch( $request ); 215 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 ); 216 } 217 218 /** 219 * @covers WP_REST_Global_Styles_Controller::get_item 220 */ 81 221 public function test_get_item() { 82 222 wp_set_current_user( self::$admin_id ); … … 101 241 102 242 public function test_create_item() { 103 $this->markTestIncomplete(); 104 } 105 243 $this->markTestSkipped( 'Controller does not implement create_item().' ); 244 } 245 246 /** 247 * @covers WP_REST_Global_Styles_Controller::update_item 248 * @ticket 54516 249 */ 106 250 public function test_update_item() { 107 251 wp_set_current_user( self::$admin_id ); … … 117 261 } 118 262 263 264 /** 265 * @covers WP_REST_Global_Styles_Controller::update_item 266 * @ticket 54516 267 */ 268 public function test_update_item_no_user() { 269 wp_set_current_user( 0 ); 270 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 271 $response = rest_get_server()->dispatch( $request ); 272 $this->assertErrorResponse( 'rest_cannot_edit', $response, 401 ); 273 } 274 275 /** 276 * @covers WP_REST_Global_Styles_Controller::update_item 277 * @ticket 54516 278 */ 279 public function test_update_item_invalid_post() { 280 wp_set_current_user( self::$admin_id ); 281 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$post_id ); 282 $response = rest_get_server()->dispatch( $request ); 283 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 ); 284 } 285 286 /** 287 * @covers WP_REST_Global_Styles_Controller::update_item 288 * @ticket 54516 289 */ 290 public function test_update_item_permission_check() { 291 wp_set_current_user( self::$subscriber_id ); 292 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 293 $response = rest_get_server()->dispatch( $request ); 294 $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 ); 295 } 296 119 297 public function test_delete_item() { 120 $this->markTest Incomplete();298 $this->markTestSkipped( 'Controller does not implement delete_item().' ); 121 299 } 122 300 123 301 public function test_prepare_item() { 124 // TODO: Implement test_prepare_item() method. 125 $this->markTestIncomplete(); 126 } 127 302 $this->markTestSkipped( 'Controller does not implement prepare_item().' ); 303 } 304 305 /** 306 * @covers WP_REST_Global_Styles_Controller::get_item_schema 307 * @ticket 54516 308 */ 128 309 public function test_get_item_schema() { 129 // TODO: Implement test_get_item_schema() method. 130 $this->markTestIncomplete(); 310 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/global-styles/' . self::$global_styles_id ); 311 $response = rest_get_server()->dispatch( $request ); 312 $data = $response->get_data(); 313 $properties = $data['schema']['properties']; 314 $this->assertCount( 4, $properties, 'Schema properties array does not have exactly 4 elements' ); 315 $this->assertArrayHasKey( 'id', $properties, 'Schema properties array does not have "id" key' ); 316 $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array does not have "styles" key' ); 317 $this->assertArrayHasKey( 'settings', $properties, 'Schema properties array does not have "settings" key' ); 318 $this->assertArrayHasKey( 'title', $properties, 'Schema properties array does not have "title" key' ); 131 319 } 132 320 }
Note: See TracChangeset
for help on using the changeset viewer.