WordPress.org

Make WordPress Core

Ticket #38531: 38531.7.diff

File 38531.7.diff, 8.9 KB (added by joehoyle, 5 years ago)
  • src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php

     
    319319                        $default_args = array(
    320320                                'name'             => $name,
    321321                                'single'           => $args['single'],
     322                                'type'             => ! empty( $args['type'] ) ? $args['type'] : null,
    322323                                'schema'           => array(),
    323324                                'prepare_callback' => array( $this, 'prepare_value' ),
    324325                        );
     
    332333                        $rest_args = array_merge( $default_args, $rest_args );
    333334                        $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] );
    334335
     336                        $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null;
     337                        $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type;
     338
     339                        if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number' ) ) ) {
     340                                continue;
     341                        }
     342
    335343                        if ( empty( $rest_args['schema']['type'] ) ) {
    336344                                // Skip over meta fields that don't have a defined type.
    337345                                if ( empty( $args['type'] ) ) {
  • src/wp-includes/rest-api.php

     
    998998                if ( ! is_array( $value ) ) {
    999999                        $value = preg_split( '/[\s,]+/', $value );
    10001000                }
     1001                if ( ! wp_is_numeric_array( $value ) ) {
     1002                        return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $param, 'array' ) );
     1003                }
    10011004                foreach ( $value as $index => $v ) {
    10021005                        $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
    10031006                        if ( is_wp_error( $is_valid ) ) {
     
    11071110                foreach ( $value as $index => $v ) {
    11081111                        $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'] );
    11091112                }
     1113                // Normalize to numeric array so nothing unexpected
     1114                // is in the keys.
     1115                $value = array_values( $value );
    11101116                return $value;
    11111117        }
    11121118        if ( 'integer' === $args['type'] ) {
     
    11401146                }
    11411147        }
    11421148
     1149        if ( 'string' === $args['type'] ) {
     1150                return strval( $value );
     1151        }
     1152
    11431153        return $value;
    11441154}
  • tests/phpunit/tests/rest-api/rest-post-meta-fields.php

     
    2626                register_meta( 'post', 'test_single', array(
    2727                        'show_in_rest' => true,
    2828                        'single' => true,
     29                        'type' => 'string',
    2930                ));
    3031                register_meta( 'post', 'test_multi', array(
    3132                        'show_in_rest' => true,
    3233                        'single' => false,
     34                        'type' => 'string',
    3335                ));
    3436                register_meta( 'post', 'test_bad_auth', array(
    3537                        'show_in_rest' => true,
    3638                        'single' => true,
    3739                        'auth_callback' => '__return_false',
     40                        'type' => 'string',
    3841                ));
    3942                register_meta( 'post', 'test_bad_auth_multi', array(
    4043                        'show_in_rest' => true,
    4144                        'single' => false,
    4245                        'auth_callback' => '__return_false',
     46                        'type' => 'string',
    4347                ));
    4448                register_meta( 'post', 'test_no_rest', array() );
    4549                register_meta( 'post', 'test_rest_disabled', array(
    4650                        'show_in_rest' => false,
     51                        'type' => 'string',
    4752                ));
    4853                register_meta( 'post', 'test_custom_schema', array(
    4954                        'single' => true,
     
    5661                ));
    5762                register_meta( 'post', 'test_invalid_type', array(
    5863                        'single' => true,
    59                         'type' => false,
     64                        'type' => 'lalala',
     65                        'show_in_rest' => true,
     66                ));
     67                register_meta( 'post', 'test_no_type', array(
     68                        'single' => true,
     69                        'type' => null,
    6070                        'show_in_rest' => true,
    6171                ));
    6272
     
    240250                $this->assertEquals( 'test_value', $meta['test_single'] );
    241251        }
    242252
     253
     254
    243255        /**
    244256         * @depends test_get_value
    245257         */
     
    341353                $wpdb->show_errors = true;
    342354        }
    343355
     356        public function test_set_value_invalid_type() {
     357                $values = get_post_meta( self::$post_id, 'test_invalid_type', false );
     358                $this->assertEmpty( $values );
     359
     360                $this->grant_write_permission();
     361
     362                $data = array(
     363                        'meta' => array(
     364                                'test_invalid_type' => 'test_value',
     365                        ),
     366                );
     367                $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     368                $request->set_body_params( $data );
     369
     370                $response = $this->server->dispatch( $request );
     371                $this->assertEmpty( get_post_meta( self::$post_id, 'test_invalid_type', false ) );
     372        }
     373
    344374        public function test_set_value_multiple() {
    345375                // Ensure no data exists currently.
    346376                $values = get_post_meta( self::$post_id, 'test_multi', false );
     
    515545                $this->assertErrorResponse( 'rest_meta_database_error', $response, 500 );
    516546        }
    517547
     548
    518549        public function test_delete_value() {
    519550                add_post_meta( self::$post_id, 'test_single', 'val1' );
    520551                $current = get_post_meta( self::$post_id, 'test_single', true );
     
    618649                $this->assertArrayNotHasKey( 'test_no_rest', $meta_schema );
    619650                $this->assertArrayNotHasKey( 'test_rest_disabled', $meta_schema );
    620651                $this->assertArrayNotHasKey( 'test_invalid_type', $meta_schema );
     652                $this->assertArrayNotHasKey( 'test_no_type', $meta_schema );
    621653        }
    622654
    623655        /**
  • tests/phpunit/tests/rest-api/rest-schema-sanitization.php

     
    7676                $this->assertEquals( array( 1 ), rest_sanitize_value_from_schema( array( '1' ), $schema ) );
    7777        }
    7878
     79        public function test_type_array_nested() {
     80                $schema = array(
     81                        'type' => 'array',
     82                        'items' => array(
     83                                'type' => 'array',
     84                                'items' => array(
     85                                        'type' => 'number',
     86                                ),
     87                        ),
     88                );
     89                $this->assertEquals( array( array( 1 ), array( 2 ) ), rest_sanitize_value_from_schema( array( array( 1 ), array( 2 ) ), $schema ) );
     90                $this->assertEquals( array( array( 1 ), array( 2 ) ), rest_sanitize_value_from_schema( array( array( '1' ), array( '2' ) ), $schema ) );
     91        }
     92
    7993        public function test_type_array_as_csv() {
    8094                $schema = array(
    8195                        'type' => 'array',
     
    110124                $this->assertEquals( array( 'ribs', 'chicken' ), rest_sanitize_value_from_schema( 'ribs,chicken', $schema ) );
    111125                $this->assertEquals( array( 'chicken', 'coleslaw' ), rest_sanitize_value_from_schema( 'chicken,coleslaw', $schema ) );
    112126        }
     127
     128        public function test_type_array_is_associative() {
     129                $schema = array(
     130                        'type' => 'array',
     131                        'items' => array(
     132                                'type' => 'string',
     133                        ),
     134                );
     135                $this->assertEquals( array( '1', '2' ), rest_sanitize_value_from_schema( array( 'first' => '1', 'second' => '2' ), $schema ) );
     136        }
     137
     138        public function test_type_unknown() {
     139                $schema = array(
     140                        'type' => 'lalala',
     141                );
     142                $this->assertEquals( 'Best lyrics', rest_sanitize_value_from_schema( 'Best lyrics', $schema ) );
     143                $this->assertEquals( 1.10, rest_sanitize_value_from_schema( 1.10, $schema ) );
     144                $this->assertEquals( 1, rest_sanitize_value_from_schema( 1, $schema ) );
     145        }
     146
     147        public function test_no_type() {
     148                $schema = array(
     149                        'type' => null,
     150                );
     151                $this->assertEquals( 'Nothing', rest_sanitize_value_from_schema( 'Nothing', $schema ) );
     152                $this->assertEquals( 1.10, rest_sanitize_value_from_schema( 1.10, $schema ) );
     153                $this->assertEquals( 1, rest_sanitize_value_from_schema( 1, $schema ) );
     154        }
    113155}
  • tests/phpunit/tests/rest-api/rest-schema-validation.php

     
    104104                $this->assertWPError( rest_validate_value_from_schema( array( true ), $schema ) );
    105105        }
    106106
     107        public function test_type_array_nested() {
     108                $schema = array(
     109                        'type' => 'array',
     110                        'items' => array(
     111                                'type' => 'array',
     112                                'items' => array(
     113                                        'type' => 'number',
     114                                ),
     115                        ),
     116                );
     117                $this->assertTrue( rest_validate_value_from_schema( array( array( 1 ), array( 2 ) ), $schema ) );
     118        }
     119
    107120        public function test_type_array_as_csv() {
    108121                $schema = array(
    109122                        'type' => 'array',
     
    139152                $this->assertTrue( rest_validate_value_from_schema( 'ribs,chicken', $schema ) );
    140153                $this->assertWPError( rest_validate_value_from_schema( 'chicken,coleslaw', $schema ) );
    141154        }
     155
     156        public function test_type_array_is_associative() {
     157                $schema = array(
     158                        'type'  => 'array',
     159                        'items' => array(
     160                                'type' => 'string',
     161                        ),
     162                );
     163                $this->assertWPError( rest_validate_value_from_schema( array( 'first' => '1', 'second' => '2' ), $schema ) );
     164        }
     165
     166        public function test_type_unknown() {
     167                $schema = array(
     168                        'type'  => 'lalala',
     169                );
     170                $this->assertTrue( rest_validate_value_from_schema( 'Best lyrics', $schema ) );
     171                $this->assertTrue( rest_validate_value_from_schema( 1, $schema ) );
     172                $this->assertTrue( rest_validate_value_from_schema( array(), $schema ) );
     173        }
    142174}