Make WordPress Core


Ignore:
Timestamp:
11/05/2021 02:14:07 AM (5 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Allow sidebars and their widgets to be public.

By default, only users with the edit_theme_options capability can access the sidebars and widgets REST API endpoints. In this commit, A new show_in_rest parameter is added to the register_sidebar function. When enabled, all users will be able to access that sidebar and any widgets belonging to that sidebar.

This commit reduces the context for a widget's instance information to only edit. This is to ensure that internal widget data is not inadvertently exposed to the public. A future ticket may expose additional APIs to allow widget authors to indicate that their instance data can be safely exposed. REST API consumers intending to access this instance information should take care to explicitly set the context parameter to edit.

Props spacedmonkey, zieladam.
Fixes #53915.

File:
1 edited

Legend:

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

    r51791 r52016  
    1818 */
    1919class 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;
    2028
    2129        /**
     
    8795         */
    8896        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();
    10498                foreach ( wp_get_sidebars_widgets() as $id => $widgets ) {
    10599                        $sidebar = $this->get_sidebar( $id );
     
    109103                        }
    110104
     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
    111138                        $data[] = $this->prepare_response_for_collection(
    112139                                $this->prepare_item_for_response( $sidebar, $request )
     
    126153         */
    127154        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
    128162                return $this->do_permissions_check();
    129163        }
    130164
    131165        /**
     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        /**
    132178         * Retrieves one sidebar from the collection.
    133179         *
     
    138184         */
    139185        public function get_item( $request ) {
    140                 retrieve_widgets();
     186                $this->retrieve_widgets();
    141187
    142188                $sidebar = $this->get_sidebar( $request['id'] );
    143 
    144189                if ( ! $sidebar ) {
    145190                        return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) );
     
    235280         * @since 5.8.0
    236281         *
    237          * @global array $wp_registered_sidebars The registered sidebars.
    238          *
    239282         * @param string|int $id ID of the sidebar.
    240283         * @return array|null The discovered sidebar, or null if it is not registered.
    241284         */
    242285        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                }
    259301        }
    260302
Note: See TracChangeset for help on using the changeset viewer.