WordPress.org

Make WordPress Core

Ticket #48885: 48885.2.patch

File 48885.2.patch, 8.7 KB (added by scruffian, 5 months ago)

new patch with context

  • src/wp-includes/option.php

     
    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.' ),
     
    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.' ),
     
    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
     
    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

     
    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(
     46                                                'context' => $this->get_context_param( array( 'default' => 'view' ) ),
     47                                        ),
    4748                                ),
    4849                                array(
    4950                                        'methods'             => WP_REST_Server::EDITABLE,
    5051                                        'callback'            => array( $this, 'update_item' ),
    5152                                        'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
    52                                         'permission_callback' => array( $this, 'get_item_permissions_check' ),
     53                                        'permission_callback' => array( $this, 'update_item_permissions_check' ),
    5354                                ),
    5455                                'schema' => array( $this, 'get_public_item_schema' ),
    5556                        )
     
    5859        }
    5960
    6061        /**
    61          * Checks if a given request has access to read and manage settings.
     62         * Checks if a given request has access to manage settings.
    6263         *
    63          * @since 4.7.0
     64         * @since 5.4.0
    6465         *
    6566         * @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.
     67         * @return bool True if the request has write access for the item, otherwise false.
    6768         */
    68         public function get_item_permissions_check( $request ) {
     69        public function update_item_permissions_check( $request ) {
    6970                return current_user_can( 'manage_options' );
    7071        }
    7172
     
    100101
    101102                        if ( is_null( $response[ $name ] ) ) {
    102103                                // Default to a null value as "null" in the response means "not set".
    103                                 $response[ $name ] = get_option( $args['option_name'], $args['schema']['default'] );
     104                                $filter = ( 'edit' === $request['context'] ) ? 'raw' : 'display';
     105                                $response[ $name ] = get_bloginfo( $args['name'], $filter );
    104106                        }
    105107
    106108                        /*
     
    212214         *
    213215         * @since 4.7.0
    214216         *
     217         * @param bool $return_non_public Optional. Returns options that are set with `show_in_rest`,
     218         *                                but aren't marked public. Default false.
    215219         * @return array Array of registered options.
    216220         */
    217         protected function get_registered_options() {
     221        protected function get_registered_options( $return_non_public = false ) {
    218222                $rest_options = array();
    219223
    220224                foreach ( get_registered_settings() as $name => $args ) {
     
    228232                                $rest_args = $args['show_in_rest'];
    229233                        }
    230234
     235                        // Users without manage_options can only see settings marked public.
     236                        if ( ! $return_non_public && ! current_user_can( 'manage_options' ) && empty( $rest_args['public'] ) ) {
     237                                continue;
     238                        }
     239
    231240                        $defaults = array(
    232241                                'name'   => ! empty( $rest_args['name'] ) ? $rest_args['name'] : $name,
    233242                                'schema' => array(),
     
    277286                        return $this->add_additional_fields_schema( $this->schema );
    278287                }
    279288
    280                 $options = $this->get_registered_options();
     289                $options = $this->get_registered_options( true );
    281290
    282291                $schema = array(
    283292                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
  • tests/phpunit/tests/rest-api/rest-settings-controller.php

     
    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() {
     
    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