Make WordPress Core


Ignore:
Timestamp:
10/05/2017 12:18:44 AM (7 years ago)
Author:
kadamwhite
Message:

REST API: Support objects in settings schema.

Enables register_setting to accept an object as its schema value, allowing settings to accept non-scalar values through the REST API.
This whitelists the added type in the settings controller, and passes properties from argument registration into the validation functions.

Props joehoyle.
See #38583.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-settings-controller.php

    r41228 r41758  
    128128    }
    129129
     130    public function test_get_item_with_custom_array_setting() {
     131        wp_set_current_user( self::$administrator );
     132
     133        register_setting( 'somegroup', 'mycustomsetting', array(
     134            'show_in_rest' => array(
     135                'schema' => array(
     136                    'type'    => 'array',
     137                    'items'   => array(
     138                        'type' => 'integer',
     139                    ),
     140                ),
     141            ),
     142            'type'         => 'array',
     143        ) );
     144
     145        // Array is cast to correct types.
     146        update_option( 'mycustomsetting', array( '1', '2' ) );
     147        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     148        $response = $this->server->dispatch( $request );
     149        $data = $response->get_data();
     150        $this->assertEquals( array( 1, 2 ), $data['mycustomsetting'] );
     151
     152        // Empty array works as expected.
     153        update_option( 'mycustomsetting', array() );
     154        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     155        $response = $this->server->dispatch( $request );
     156        $data = $response->get_data();
     157        $this->assertEquals( array(), $data['mycustomsetting'] );
     158
     159        // Invalid value
     160        update_option( 'mycustomsetting', array( array( 1 ) ) );
     161        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     162        $response = $this->server->dispatch( $request );
     163        $data = $response->get_data();
     164        $this->assertEquals( null, $data['mycustomsetting'] );
     165
     166        // No option value
     167        delete_option( 'mycustomsetting' );
     168        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     169        $response = $this->server->dispatch( $request );
     170        $data = $response->get_data();
     171        $this->assertEquals( null, $data['mycustomsetting'] );
     172
     173        unregister_setting( 'somegroup', 'mycustomsetting' );
     174    }
     175
     176    public function test_get_item_with_custom_object_setting() {
     177        wp_set_current_user( self::$administrator );
     178
     179        register_setting( 'somegroup', 'mycustomsetting', array(
     180            'show_in_rest' => array(
     181                'schema' => array(
     182                    'type'    => 'object',
     183                    'properties' => array(
     184                        'a' => array(
     185                            'type' => 'integer',
     186                        ),
     187                    ),
     188                ),
     189            ),
     190            'type'         => 'object',
     191        ) );
     192
     193        // Object is cast to correct types.
     194        update_option( 'mycustomsetting', array( 'a' => '1' ) );
     195        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     196        $response = $this->server->dispatch( $request );
     197        $data = $response->get_data();
     198        $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] );
     199
     200        // Empty array works as expected.
     201        update_option( 'mycustomsetting', array() );
     202        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     203        $response = $this->server->dispatch( $request );
     204        $data = $response->get_data();
     205        $this->assertEquals( array(), $data['mycustomsetting'] );
     206
     207        // Invalid value
     208        update_option( 'mycustomsetting', array( 'a' => 1, 'b' => 2 ) );
     209        $request = new WP_REST_Request( 'GET', '/wp/v2/settings' );
     210        $response = $this->server->dispatch( $request );
     211        $data = $response->get_data();
     212        $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] );
     213
     214        unregister_setting( 'somegroup', 'mycustomsetting' );
     215    }
     216
    130217    public function get_setting_custom_callback( $result, $name, $args ) {
    131218        switch ( $name ) {
     
    216303        $data = $response->get_data();
    217304        $this->assertEquals( null, $data['mycustomsettinginrest'] );
     305        unregister_setting( 'somegroup', 'mycustomsetting' );
    218306    }
    219307
     
    243331    }
    244332
     333    public function test_update_item_with_array() {
     334        register_setting( 'somegroup', 'mycustomsetting', array(
     335            'show_in_rest' => array(
     336                'schema' => array(
     337                    'type'  => 'array',
     338                    'items' => array(
     339                        'type' => 'integer',
     340                    ),
     341                ),
     342            ),
     343            'type'         => 'array',
     344        ) );
     345
     346        // We have to re-register the route, as the args changes based off registered settings.
     347        $this->server->override_by_default = true;
     348        $this->endpoint->register_routes();
     349        wp_set_current_user( self::$administrator );
     350
     351        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     352        $request->set_param( 'mycustomsetting', array( '1', '2' ) );
     353        $response = $this->server->dispatch( $request );
     354        $data = $response->get_data();
     355        $this->assertEquals( array( 1, 2 ), $data['mycustomsetting'] );
     356        $this->assertEquals( array( 1, 2 ), get_option( 'mycustomsetting' ) );
     357
     358        // Setting an empty array.
     359        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     360        $request->set_param( 'mycustomsetting', array() );
     361        $response = $this->server->dispatch( $request );
     362        $data = $response->get_data();
     363        $this->assertEquals( array(), $data['mycustomsetting'] );
     364        $this->assertEquals( array(), get_option( 'mycustomsetting' ) );
     365
     366        // Setting an invalid array.
     367        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     368        $request->set_param( 'mycustomsetting', array( 'invalid' ) );
     369        $response = $this->server->dispatch( $request );
     370
     371        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     372        unregister_setting( 'somegroup', 'mycustomsetting' );
     373    }
     374
     375    public function test_update_item_with_object() {
     376        register_setting( 'somegroup', 'mycustomsetting', array(
     377            'show_in_rest' => array(
     378                'schema' => array(
     379                    'type'       => 'object',
     380                    'properties' => array(
     381                        'a' => array(
     382                            'type' => 'integer',
     383                        ),
     384                    ),
     385                ),
     386            ),
     387            'type'         => 'object',
     388        ) );
     389
     390        // We have to re-register the route, as the args changes based off registered settings.
     391        $this->server->override_by_default = true;
     392        $this->endpoint->register_routes();
     393        wp_set_current_user( self::$administrator );
     394
     395        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     396        $request->set_param( 'mycustomsetting', array( 'a' => 1 ) );
     397        $response = $this->server->dispatch( $request );
     398        $data = $response->get_data();
     399        $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] );
     400        $this->assertEquals( array( 'a' => 1 ), get_option( 'mycustomsetting' ) );
     401
     402        // Setting an empty object.
     403        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     404        $request->set_param( 'mycustomsetting', array() );
     405        $response = $this->server->dispatch( $request );
     406        $data = $response->get_data();
     407        $this->assertEquals( array(), $data['mycustomsetting'] );
     408        $this->assertEquals( array(), get_option( 'mycustomsetting' ) );
     409
     410        // Setting an invalid object.
     411        $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
     412        $request->set_param( 'mycustomsetting', array( 'a' => 'invalid' ) );
     413        $response = $this->server->dispatch( $request );
     414        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     415        unregister_setting( 'somegroup', 'mycustomsetting' );
     416    }
     417
    245418    public function test_update_item_with_filter() {
    246419        wp_set_current_user( self::$administrator );
Note: See TracChangeset for help on using the changeset viewer.