Make WordPress Core


Ignore:
Timestamp:
11/05/2021 02:14:07 AM (3 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.