Changeset 52016
- Timestamp:
- 11/05/2021 02:14:07 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php
r51791 r52016 18 18 */ 19 19 class WP_REST_Sidebars_Controller extends WP_REST_Controller { 20 21 /** 22 * Tracks whether {@see retrieve_widgets()} has been called in the current request. 23 * 24 * @since 5.9.0 25 * @var bool 26 */ 27 protected $widgets_retrieved = false; 20 28 21 29 /** … … 87 95 */ 88 96 public function get_items_permissions_check( $request ) { 89 return $this->do_permissions_check(); 90 } 91 92 /** 93 * Retrieves the list of sidebars (active or inactive). 94 * 95 * @since 5.8.0 96 * 97 * @param WP_REST_Request $request Full details about the request. 98 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 99 */ 100 public function get_items( $request ) { 101 retrieve_widgets(); 102 103 $data = array(); 97 $this->retrieve_widgets(); 104 98 foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { 105 99 $sidebar = $this->get_sidebar( $id ); … … 109 103 } 110 104 105 if ( $this->check_read_permission( $sidebar ) ) { 106 return true; 107 } 108 } 109 110 return $this->do_permissions_check(); 111 } 112 113 /** 114 * Retrieves the list of sidebars (active or inactive). 115 * 116 * @since 5.8.0 117 * 118 * @param WP_REST_Request $request Full details about the request. 119 * @return WP_REST_Response Response object on success. 120 */ 121 public function get_items( $request ) { 122 $this->retrieve_widgets(); 123 124 $data = array(); 125 $permissions_check = $this->do_permissions_check(); 126 127 foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { 128 $sidebar = $this->get_sidebar( $id ); 129 130 if ( ! $sidebar ) { 131 continue; 132 } 133 134 if ( is_wp_error( $permissions_check ) && ! $this->check_read_permission( $sidebar ) ) { 135 continue; 136 } 137 111 138 $data[] = $this->prepare_response_for_collection( 112 139 $this->prepare_item_for_response( $sidebar, $request ) … … 126 153 */ 127 154 public function get_item_permissions_check( $request ) { 155 $this->retrieve_widgets(); 156 157 $sidebar = $this->get_sidebar( $request['id'] ); 158 if ( $sidebar && $this->check_read_permission( $sidebar ) ) { 159 return true; 160 } 161 128 162 return $this->do_permissions_check(); 129 163 } 130 164 131 165 /** 166 * Checks if a sidebar can be read publicly. 167 * 168 * @since 5.9.0 169 * 170 * @param array $sidebar The registered sidebar configuration. 171 * @return bool Whether the side can be read. 172 */ 173 protected function check_read_permission( $sidebar ) { 174 return ! empty( $sidebar['show_in_rest'] ); 175 } 176 177 /** 132 178 * Retrieves one sidebar from the collection. 133 179 * … … 138 184 */ 139 185 public function get_item( $request ) { 140 retrieve_widgets();186 $this->retrieve_widgets(); 141 187 142 188 $sidebar = $this->get_sidebar( $request['id'] ); 143 144 189 if ( ! $sidebar ) { 145 190 return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) ); … … 235 280 * @since 5.8.0 236 281 * 237 * @global array $wp_registered_sidebars The registered sidebars.238 *239 282 * @param string|int $id ID of the sidebar. 240 283 * @return array|null The discovered sidebar, or null if it is not registered. 241 284 */ 242 285 protected function get_sidebar( $id ) { 243 global $wp_registered_sidebars; 244 245 foreach ( (array) $wp_registered_sidebars as $sidebar ) { 246 if ( $sidebar['id'] === $id ) { 247 return $sidebar; 248 } 249 } 250 251 if ( 'wp_inactive_widgets' === $id ) { 252 return array( 253 'id' => 'wp_inactive_widgets', 254 'name' => __( 'Inactive widgets' ), 255 ); 256 } 257 258 return null; 286 return wp_get_sidebar( $id ); 287 } 288 289 /** 290 * Looks for "lost" widgets once per request. 291 * 292 * @since 5.9.0 293 * 294 * @see retrieve_widgets() 295 */ 296 protected function retrieve_widgets() { 297 if ( ! $this->widgets_retrieved ) { 298 retrieve_widgets(); 299 $this->widgets_retrieved = true; 300 } 259 301 } 260 302 -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php
r51791 r52016 16 16 */ 17 17 class WP_REST_Widgets_Controller extends WP_REST_Controller { 18 19 /** 20 * Tracks whether {@see retrieve_widgets()} has been called in the current request. 21 * 22 * @since 5.9.0 23 * @var bool 24 */ 25 protected $widgets_retrieved = false; 18 26 19 27 /** … … 98 106 */ 99 107 public function get_items_permissions_check( $request ) { 108 $this->retrieve_widgets(); 109 if ( isset( $request['sidebar'] ) && $this->check_read_sidebar_permission( $request['sidebar'] ) ) { 110 return true; 111 } 112 113 foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { 114 if ( $this->check_read_sidebar_permission( $sidebar_id ) ) { 115 return true; 116 } 117 } 118 100 119 return $this->permissions_check( $request ); 101 120 } … … 110 129 */ 111 130 public function get_items( $request ) { 112 retrieve_widgets(); 113 114 $prepared = array(); 131 $this->retrieve_widgets(); 132 133 $prepared = array(); 134 $permissions_check = $this->permissions_check( $request ); 115 135 116 136 foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { … … 119 139 } 120 140 141 if ( is_wp_error( $permissions_check ) && ! $this->check_read_sidebar_permission( $sidebar_id ) ) { 142 continue; 143 } 144 121 145 foreach ( $widget_ids as $widget_id ) { 122 146 $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); … … 140 164 */ 141 165 public function get_item_permissions_check( $request ) { 166 $this->retrieve_widgets(); 167 168 $widget_id = $request['id']; 169 $sidebar_id = wp_find_widgets_sidebar( $widget_id ); 170 171 if ( $sidebar_id && $this->check_read_sidebar_permission( $sidebar_id ) ) { 172 return true; 173 } 174 142 175 return $this->permissions_check( $request ); 143 176 } 144 177 145 178 /** 179 * Checks if a sidebar can be read publicly. 180 * 181 * @since 5.9.0 182 * 183 * @param string $sidebar_id The sidebar id. 184 * @return bool Whether the sidebar can be read. 185 */ 186 protected function check_read_sidebar_permission( $sidebar_id ) { 187 $sidebar = wp_get_sidebar( $sidebar_id ); 188 189 return ! empty( $sidebar['show_in_rest'] ); 190 } 191 192 /** 146 193 * Gets an individual widget. 147 194 * … … 152 199 */ 153 200 public function get_item( $request ) { 154 retrieve_widgets();201 $this->retrieve_widgets(); 155 202 156 203 $widget_id = $request['id']; … … 248 295 */ 249 296 wp_get_sidebars_widgets(); 250 251 retrieve_widgets(); 297 $this->retrieve_widgets(); 252 298 253 299 $widget_id = $request['id']; … … 324 370 */ 325 371 wp_get_sidebars_widgets(); 326 327 retrieve_widgets(); 372 $this->retrieve_widgets(); 328 373 329 374 $widget_id = $request['id']; … … 438 483 439 484 return true; 485 } 486 487 /** 488 * Looks for "lost" widgets once per request. 489 * 490 * @since 5.9.0 491 * 492 * @see retrieve_widgets() 493 */ 494 protected function retrieve_widgets() { 495 if ( ! $this->widgets_retrieved ) { 496 retrieve_widgets(); 497 $this->widgets_retrieved = true; 498 } 440 499 } 441 500 … … 768 827 'description' => __( 'Instance settings of the widget, if supported.' ), 769 828 'type' => 'object', 770 'context' => array( ' view', 'edit', 'embed' ),829 'context' => array( 'edit' ), 771 830 'default' => null, 772 831 'properties' => array( … … 774 833 'description' => __( 'Base64 encoded representation of the instance settings.' ), 775 834 'type' => 'string', 776 'context' => array( ' view', 'edit', 'embed' ),835 'context' => array( 'edit' ), 777 836 ), 778 837 'hash' => array( 779 838 'description' => __( 'Cryptographic hash of the instance settings.' ), 780 839 'type' => 'string', 781 'context' => array( ' view', 'edit', 'embed' ),840 'context' => array( 'edit' ), 782 841 ), 783 842 'raw' => array( 784 843 'description' => __( 'Unencoded instance settings, if supported.' ), 785 844 'type' => 'object', 786 'context' => array( ' view', 'edit', 'embed' ),845 'context' => array( 'edit' ), 787 846 ), 788 847 ), -
trunk/src/wp-includes/widgets.php
r51850 r52016 221 221 * @since 2.2.0 222 222 * @since 5.6.0 Added the `before_sidebar` and `after_sidebar` arguments. 223 * @since 5.9.0 Added the `show_in_rest` argument. 223 224 * 224 225 * @global array $wp_registered_sidebars Registered sidebars. … … 251 252 * Outputs before the {@see 'dynamic_sidebar_after'} action. 252 253 * Default empty string. 254 * @type bool $show_in_rest Whether to show this sidebar publicly in the REST API. 255 * Defaults to only showing the sidebar to administrator users. 253 256 * } 254 257 * @return string Sidebar ID added to $wp_registered_sidebars global. … … 273 276 'before_sidebar' => '', 274 277 'after_sidebar' => '', 278 'show_in_rest' => false, 275 279 ); 276 280 … … 1037 1041 1038 1042 /** 1043 * Retrieves the registered sidebar with the given id. 1044 * 1045 * @since 5.9.0 1046 * 1047 * @global array $wp_registered_sidebars The registered sidebars. 1048 * 1049 * @param string $id The sidebar id. 1050 * @return array|null The discovered sidebar, or null if it is not registered. 1051 */ 1052 function wp_get_sidebar( $id ) { 1053 global $wp_registered_sidebars; 1054 1055 foreach ( (array) $wp_registered_sidebars as $sidebar ) { 1056 if ( $sidebar['id'] === $id ) { 1057 return $sidebar; 1058 } 1059 } 1060 1061 if ( 'wp_inactive_widgets' === $id ) { 1062 return array( 1063 'id' => 'wp_inactive_widgets', 1064 'name' => __( 'Inactive widgets' ), 1065 ); 1066 } 1067 1068 return null; 1069 } 1070 1071 /** 1039 1072 * Set the sidebar widget option to update sidebars. 1040 1073 * -
trunk/tests/phpunit/tests/rest-api/rest-sidebars-controller.php
r51568 r52016 166 166 167 167 /** 168 * @ticket 53915 169 */ 170 public function test_get_items_no_permission_show_in_rest() { 171 $this->setup_sidebar( 172 'sidebar-1', 173 array( 174 'name' => 'Test sidebar', 175 'show_in_rest' => true, 176 ) 177 ); 178 wp_set_current_user( 0 ); 179 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars' ); 180 $response = rest_get_server()->dispatch( $request ); 181 $data = $response->get_data(); 182 $data = $this->remove_links( $data ); 183 $this->assertSame( 184 array( 185 array( 186 'id' => 'sidebar-1', 187 'name' => 'Test sidebar', 188 'description' => '', 189 'class' => '', 190 'before_widget' => '', 191 'after_widget' => '', 192 'before_title' => '', 193 'after_title' => '', 194 'status' => 'active', 195 'widgets' => array(), 196 ), 197 ), 198 $data 199 ); 200 } 201 202 /** 203 * @ticket 53915 204 */ 205 public function test_get_items_without_show_in_rest_are_removed_from_the_list() { 206 $this->setup_sidebar( 207 'sidebar-1', 208 array( 209 'name' => 'Test sidebar 1', 210 'show_in_rest' => true, 211 ) 212 ); 213 $this->setup_sidebar( 214 'sidebar-2', 215 array( 216 'name' => 'Test sidebar 2', 217 'show_in_rest' => false, 218 ) 219 ); 220 $this->setup_sidebar( 221 'sidebar-3', 222 array( 223 'name' => 'Test sidebar 3', 224 'show_in_rest' => true, 225 ) 226 ); 227 wp_set_current_user( self::$author_id ); 228 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars' ); 229 $response = rest_get_server()->dispatch( $request ); 230 $data = $response->get_data(); 231 $data = $this->remove_links( $data ); 232 $this->assertSame( 233 array( 234 array( 235 'id' => 'sidebar-1', 236 'name' => 'Test sidebar 1', 237 'description' => '', 238 'class' => '', 239 'before_widget' => '', 240 'after_widget' => '', 241 'before_title' => '', 242 'after_title' => '', 243 'status' => 'active', 244 'widgets' => array(), 245 ), 246 array( 247 'id' => 'sidebar-3', 248 'name' => 'Test sidebar 3', 249 'description' => '', 250 'class' => '', 251 'before_widget' => '', 252 'after_widget' => '', 253 'before_title' => '', 254 'after_title' => '', 255 'status' => 'active', 256 'widgets' => array(), 257 ), 258 ), 259 $data 260 ); 261 } 262 263 /** 168 264 * @ticket 41683 169 265 */ … … 193 289 array( 194 290 array( 291 'id' => 'wp_inactive_widgets', 292 'name' => 'Inactive widgets', 293 'description' => '', 294 'class' => '', 295 'before_widget' => '', 296 'after_widget' => '', 297 'before_title' => '', 298 'after_title' => '', 299 'status' => 'inactive', 300 'widgets' => array(), 301 ), 302 array( 195 303 'id' => 'sidebar-1', 196 304 'name' => 'Test sidebar', … … 207 315 $data 208 316 ); 317 209 318 } 210 319 … … 411 520 $response = rest_get_server()->dispatch( $request ); 412 521 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); 522 } 523 524 /** 525 * @ticket 41683 526 */ 527 public function test_get_item_no_permission_public() { 528 wp_set_current_user( 0 ); 529 $this->setup_sidebar( 530 'sidebar-1', 531 array( 532 'name' => 'Test sidebar', 533 'show_in_rest' => true, 534 ) 535 ); 536 537 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars/sidebar-1' ); 538 $response = rest_get_server()->dispatch( $request ); 539 $data = $response->get_data(); 540 $data = $this->remove_links( $data ); 541 $this->assertSame( 542 array( 543 'id' => 'sidebar-1', 544 'name' => 'Test sidebar', 545 'description' => '', 546 'class' => '', 547 'before_widget' => '', 548 'after_widget' => '', 549 'before_title' => '', 550 'after_title' => '', 551 'status' => 'active', 552 'widgets' => array(), 553 ), 554 $data 555 ); 413 556 } 414 557 -
trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php
r51830 r52016 242 242 243 243 /** 244 * @ticket 53915 245 */ 246 public function test_get_items_no_permission_show_in_rest() { 247 $this->setup_widget( 248 'text', 249 1, 250 array( 251 'text' => 'Custom text test', 252 ) 253 ); 254 $this->setup_sidebar( 255 'sidebar-1', 256 array( 257 'name' => 'Test sidebar', 258 'show_in_rest' => true, 259 ), 260 array( 'text-1', 'testwidget' ) 261 ); 262 263 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets' ); 264 $response = rest_get_server()->dispatch( $request ); 265 $data = $response->get_data(); 266 $data = $this->remove_links( $data ); 267 $this->assertSameIgnoreEOL( 268 array( 269 array( 270 'id' => 'text-1', 271 'id_base' => 'text', 272 'sidebar' => 'sidebar-1', 273 'rendered' => '<div class="textwidget">Custom text test</div>', 274 ), 275 array( 276 'id' => 'testwidget', 277 'id_base' => 'testwidget', 278 'sidebar' => 'sidebar-1', 279 'rendered' => '<h1>Default id</h1><span>Default text</span>', 280 ), 281 ), 282 $data 283 ); 284 } 285 286 /** 287 * @ticket 53915 288 */ 289 public function test_get_items_without_show_in_rest_are_removed_from_the_list() { 290 wp_set_current_user( self::$author_id ); 291 $this->setup_widget( 292 'text', 293 1, 294 array( 295 'text' => 'Custom text test', 296 ) 297 ); 298 $this->setup_sidebar( 299 'sidebar-1', 300 array( 301 'name' => 'Test sidebar 1', 302 'show_in_rest' => true, 303 ), 304 array( 'text-1', 'testwidget' ) 305 ); 306 $this->setup_sidebar( 307 'sidebar-2', 308 array( 309 'name' => 'Test sidebar 2', 310 'show_in_rest' => false, 311 ), 312 array( 'text-1', 'testwidget' ) 313 ); 314 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets' ); 315 $response = rest_get_server()->dispatch( $request ); 316 $data = $response->get_data(); 317 $data = $this->remove_links( $data ); 318 $this->assertSameIgnoreEOL( 319 array( 320 array( 321 'id' => 'text-1', 322 'id_base' => 'text', 323 'sidebar' => 'sidebar-1', 324 'rendered' => '<div class="textwidget">Custom text test</div>', 325 ), 326 array( 327 'id' => 'testwidget', 328 'id_base' => 'testwidget', 329 'sidebar' => 'sidebar-1', 330 'rendered' => '<h1>Default id</h1><span>Default text</span>', 331 ), 332 ), 333 $data 334 ); 335 } 336 337 /** 244 338 * @ticket 41683 245 339 */ … … 296 390 'sidebar' => 'sidebar-1', 297 391 'rendered' => '<p>Block test</p>', 298 'instance' => array(299 'encoded' => base64_encode(300 serialize(301 array(302 'content' => $block_content,303 )304 )305 ),306 'hash' => wp_hash(307 serialize(308 array(309 'content' => $block_content,310 )311 )312 ),313 'raw' => array(314 'content' => $block_content,315 ),316 ),317 392 ), 318 393 array( … … 321 396 'sidebar' => 'sidebar-1', 322 397 'rendered' => '<a class="rsswidget" href="https://wordpress.org/news/feed"><img class="rss-widget-icon" style="border:0" width="14" height="14" src="http://example.org/wp-includes/images/rss.png" alt="RSS" /></a> <a class="rsswidget" href="https://wordpress.org/news">RSS test</a><ul><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/12/introducing-learn-wordpress/\'>Introducing Learn WordPress</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/12/simone/\'>WordPress 5.6 “Simone”</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/12/state-of-the-word-2020/\'>State of the Word 2020</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/12/the-month-in-wordpress-november-2020/\'>The Month in WordPress: November 2020</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/12/wordpress-5-6-release-candidate-2/\'>WordPress 5.6 Release Candidate 2</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/11/wordpress-5-6-release-candidate/\'>WordPress 5.6 Release Candidate</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/11/wordpress-5-6-beta-4/\'>WordPress 5.6 Beta 4</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/11/wordpress-5-6-beta-3/\'>WordPress 5.6 Beta 3</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/11/the-month-in-wordpress-october-2020/\'>The Month in WordPress: October 2020</a></li><li><a class=\'rsswidget\' href=\'https://wordpress.org/news/2020/10/wordpress-5-5-3-maintenance-release/\'>WordPress 5.5.3 Maintenance Release</a></li></ul>', 323 'instance' => array(324 'encoded' => base64_encode(325 serialize(326 array(327 'title' => 'RSS test',328 'url' => 'https://wordpress.org/news/feed',329 )330 )331 ),332 'hash' => wp_hash(333 serialize(334 array(335 'title' => 'RSS test',336 'url' => 'https://wordpress.org/news/feed',337 )338 )339 ),340 ),341 398 ), 342 399 array( … … 345 402 'sidebar' => 'sidebar-1', 346 403 'rendered' => '<h1>Default id</h1><span>Default text</span>', 347 'instance' => null,348 404 ), 349 405 ), … … 470 526 'sidebar' => 'sidebar-1', 471 527 'rendered' => '<div class="textwidget">Custom text test</div>', 472 'instance' => array(473 'encoded' => base64_encode(474 serialize(475 array(476 'text' => 'Custom text test',477 )478 )479 ),480 'hash' => wp_hash(481 serialize(482 array(483 'text' => 'Custom text test',484 )485 )486 ),487 'raw' => array(488 'text' => 'Custom text test',489 ),490 ),491 528 ), 492 529 $data … … 542 579 $response = rest_get_server()->dispatch( $request ); 543 580 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); 581 } 582 583 /** 584 * @ticket 53915 585 */ 586 public function test_get_item_no_permission_show_in_rest() { 587 wp_set_current_user( 0 ); 588 589 $this->setup_widget( 590 'text', 591 1, 592 array( 593 'text' => 'Custom text test', 594 ) 595 ); 596 $this->setup_sidebar( 597 'sidebar-1', 598 array( 599 'name' => 'Test sidebar', 600 'show_in_rest' => true, 601 ), 602 array( 'text-1' ) 603 ); 604 605 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets/text-1' ); 606 $response = rest_get_server()->dispatch( $request ); 607 $data = $response->get_data(); 608 $this->assertSameSets( 609 array( 610 'id' => 'text-1', 611 'id_base' => 'text', 612 'sidebar' => 'sidebar-1', 613 'rendered' => '<div class="textwidget">Custom text test</div>', 614 ), 615 $data 616 ); 544 617 } 545 618 -
trunk/tests/qunit/fixtures/wp-api-generated.js
r51973 r52016 7136 7136 "type": "string", 7137 7137 "context": [ 7138 "view", 7139 "edit", 7140 "embed" 7138 "edit" 7141 7139 ] 7142 7140 }, … … 7145 7143 "type": "string", 7146 7144 "context": [ 7147 "view", 7148 "edit", 7149 "embed" 7145 "edit" 7150 7146 ] 7151 7147 }, … … 7154 7150 "type": "object", 7155 7151 "context": [ 7156 "view", 7157 "edit", 7158 "embed" 7152 "edit" 7159 7153 ] 7160 7154 } … … 7236 7230 "type": "string", 7237 7231 "context": [ 7238 "view", 7239 "edit", 7240 "embed" 7232 "edit" 7241 7233 ] 7242 7234 }, … … 7245 7237 "type": "string", 7246 7238 "context": [ 7247 "view", 7248 "edit", 7249 "embed" 7239 "edit" 7250 7240 ] 7251 7241 }, … … 7254 7244 "type": "object", 7255 7245 "context": [ 7256 "view", 7257 "edit", 7258 "embed" 7246 "edit" 7259 7247 ] 7260 7248 }
Note: See TracChangeset
for help on using the changeset viewer.