Make WordPress Core

Ticket #48885: 48885.diff

File 48885.diff, 8.8 KB (added by pento, 5 years ago)
  • src/wp-includes/option.php

    diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php
    index fbe1eda4a4..38dd6527b6 100644
    a b function register_initial_settings() { 
    19071907                'blogname',
    19081908                array(
    19091909                        'show_in_rest' => array(
    1910                                 'name' => 'title',
     1910                                'name'   => 'title',
     1911                                'public' => true,
    19111912                        ),
    19121913                        'type'         => 'string',
    19131914                        'description'  => __( 'Site title.' ),
    function register_initial_settings() { 
    19191920                'blogdescription',
    19201921                array(
    19211922                        'show_in_rest' => array(
    1922                                 'name' => 'description',
     1923                                'name'   => 'description',
     1924                                'public' => true,
    19231925                        ),
    19241926                        'type'         => 'string',
    19251927                        'description'  => __( 'Site tagline.' ),
    function register_initial_settings() { 
    20912093 *
    20922094 * @since 2.7.0
    20932095 * @since 4.7.0 `$args` can be passed to set flags on the setting, similar to `register_meta()`.
     2096 * @since 5.4.0 Added the `$public` parameter to the `$show_in_rest` member of `$args`.
    20942097 *
    20952098 * @global array $new_whitelist_options
    20962099 * @global array $wp_registered_settings
    function register_initial_settings() { 
    21012104 * @param array  $args {
    21022105 *     Data used to describe the setting when registered.
    21032106 *
    2104  *     @type string   $type              The type of data associated with this setting.
    2105  *                                       Valid values are 'string', 'boolean', 'integer', and 'number'.
    2106  *     @type string   $description       A description of the data attached to this setting.
    2107  *     @type callable $sanitize_callback A callback function that sanitizes the option's value.
    2108  *     @type bool     $show_in_rest      Whether data associated with this setting should be included in the REST API.
    2109  *     @type mixed    $default           Default value when calling `get_option()`.
     2107 *     @type string     $type              The type of data associated with this setting.
     2108 *                                         Valid values are 'string', 'boolean', 'integer', and 'number'.
     2109 *     @type string     $description       A description of the data attached to this setting.
     2110 *     @type callable   $sanitize_callback A callback function that sanitizes the option's value.
     2111 *     @type bool|array $show_in_rest {
     2112 *         Whether data associated with this setting should be included in the REST API. Optionally passing
     2113 *         an array will include the setting in the REST API, with additional optional configuration.
     2114 *
     2115 *         @type string $name   The name to display this setting in the REST API as. Default `$option_name`.
     2116 *         @type array  $schema Additional schema data to be included for this option.
     2117 *         @type bool   $public Whether this option can be shown to all users. Default false.
     2118 *     }
     2119 *     @type mixed      $default           Default value when calling `get_option()`.
    21102120 * }
    21112121 */
    21122122function register_setting( $option_group, $option_name, $args = array() ) {
  • src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php
    index c5cf1a7a4b..2342178cac 100644
    a b class WP_REST_Settings_Controller extends WP_REST_Controller { 
    4040                        '/' . $this->rest_base,
    4141                        array(
    4242                                array(
    43                                         'methods'             => WP_REST_Server::READABLE,
    44                                         'callback'            => array( $this, 'get_item' ),
    45                                         'args'                => array(),
    46                                         'permission_callback' => array( $this, 'get_item_permissions_check' ),
     43                                        'methods'  => WP_REST_Server::READABLE,
     44                                        'callback' => array( $this, 'get_item' ),
     45                                        'args'     => array(),
    4746                                ),
    4847                                array(
    4948                                        'methods'             => WP_REST_Server::EDITABLE,
    5049                                        'callback'            => array( $this, 'update_item' ),
    5150                                        'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
    52                                         'permission_callback' => array( $this, 'get_item_permissions_check' ),
     51                                        'permission_callback' => array( $this, 'update_item_permissions_check' ),
    5352                                ),
    5453                                'schema' => array( $this, 'get_public_item_schema' ),
    5554                        )
    class WP_REST_Settings_Controller extends WP_REST_Controller { 
    5857        }
    5958
    6059        /**
    61          * Checks if a given request has access to read and manage settings.
     60         * Checks if a given request has access to manage settings.
    6261         *
    63          * @since 4.7.0
     62         * @since 5.4.0
    6463         *
    6564         * @param WP_REST_Request $request Full details about the request.
    66          * @return bool True if the request has read access for the item, otherwise false.
     65         * @return bool True if the request has write access for the item, otherwise false.
    6766         */
    68         public function get_item_permissions_check( $request ) {
     67        public function update_item_permissions_check( $request ) {
    6968                return current_user_can( 'manage_options' );
    7069        }
    7170
    class WP_REST_Settings_Controller extends WP_REST_Controller { 
    212211         *
    213212         * @since 4.7.0
    214213         *
     214         * @param bool $return_non_public Optional. Returns options that are set with `show_in_rest`,
     215         *                                but aren't marked public. Default false.
    215216         * @return array Array of registered options.
    216217         */
    217         protected function get_registered_options() {
     218        protected function get_registered_options( $return_non_public = false ) {
    218219                $rest_options = array();
    219220
    220221                foreach ( get_registered_settings() as $name => $args ) {
    class WP_REST_Settings_Controller extends WP_REST_Controller { 
    228229                                $rest_args = $args['show_in_rest'];
    229230                        }
    230231
     232                        // Users without manage_options can only see settings marked public.
     233                        if ( ! $return_non_public && ! current_user_can( 'manage_options' ) && empty( $rest_args['public'] ) ) {
     234                                continue;
     235                        }
     236
    231237                        $defaults = array(
    232238                                'name'   => ! empty( $rest_args['name'] ) ? $rest_args['name'] : $name,
    233239                                'schema' => array(),
    class WP_REST_Settings_Controller extends WP_REST_Controller { 
    277283                        return $this->add_additional_fields_schema( $this->schema );
    278284                }
    279285
    280                 $options = $this->get_registered_options();
     286                $options = $this->get_registered_options( true );
    281287
    282288                $schema = array(
    283289                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
  • tests/phpunit/tests/rest-api/rest-settings-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-settings-controller.php b/tests/phpunit/tests/rest-api/rest-settings-controller.php
    index 73805b4d38..d944af3e1e 100644
    a b class WP_Test_REST_Settings_Controller extends WP_Test_REST_Controller_Testcase 
    5454        public function test_context_param() {
    5555        }
    5656
    57         public function test_get_item_is_not_public_not_authenticated() {
     57        public function test_get_item_shows_public_items_not_authenticated() {
    5858                $request  = new WP_REST_Request( 'GET', '/wp/v2/settings' );
    5959                $response = rest_get_server()->dispatch( $request );
    60                 $this->assertEquals( 401, $response->get_status() );
     60                $data     = $response->get_data();
     61                $actual   = array_keys( $data );
     62
     63                $expected = array(
     64                        'title',
     65                        'description',
     66                );
     67
     68                sort( $expected );
     69                sort( $actual );
     70
     71                $this->assertEquals( 200, $response->get_status() );
     72                $this->assertEquals( $expected, $actual );
    6173        }
    6274
    63         public function test_get_item_is_not_public_no_permission() {
     75        public function test_get_item_shows_public_items_no_permission() {
    6476                wp_set_current_user( self::$author );
    6577                $request  = new WP_REST_Request( 'GET', '/wp/v2/settings' );
    6678                $response = rest_get_server()->dispatch( $request );
    67                 $this->assertEquals( 403, $response->get_status() );
     79                $data     = $response->get_data();
     80                $actual   = array_keys( $data );
     81
     82                $expected = array(
     83                        'title',
     84                        'description',
     85                );
     86
     87                sort( $expected );
     88                sort( $actual );
     89
     90                $this->assertEquals( 200, $response->get_status() );
     91                $this->assertEquals( $expected, $actual );
    6892        }
    6993
    7094        public function test_get_items() {
    class WP_Test_REST_Settings_Controller extends WP_Test_REST_Controller_Testcase 
    377401                $this->assertEquals( get_option( 'blogname' ), $data['title'] );
    378402        }
    379403
     404        public function test_update_item_fails_not_authenticated() {
     405                $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     406                $request->set_param( 'title', 'The new title!' );
     407                $response = rest_get_server()->dispatch( $request );
     408                $this->assertEquals( 401, $response->get_status() );
     409        }
     410
     411        public function test_update_item_fails_no_permission() {
     412                wp_set_current_user( self::$author );
     413                $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     414                $request->set_param( 'title', 'The new title!' );
     415                $response = rest_get_server()->dispatch( $request );
     416                $this->assertEquals( 403, $response->get_status() );
     417        }
     418
    380419        public function update_setting_custom_callback( $result, $name, $value, $args ) {
    381420                if ( 'title' === $name && 'The new title!' === $value ) {
    382421                        // Do not allow changing the title in this case