Make WordPress Core


Ignore:
Timestamp:
06/10/2020 02:20:18 AM (6 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Fix updating "multiple" meta keys with non-string values.

Previously, the REST API would end up deleting each row of metadata and recreating it unnecessarily. This was caused by a type mismatch where the metadata API would always return a string value, and the REST API operated on a typed value.

The REST API now applies the same sanitization and type casting for "multiple" meta keys and "single" meta keys.

Fixes #49339.
Props renathoc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r47122 r47943  
    26572657
    26582658        /**
     2659         * @ticket 49339
     2660         */
     2661        public function test_update_multi_meta_value_handles_integer_types() {
     2662                $this->grant_write_permission();
     2663
     2664                register_post_meta(
     2665                        'post',
     2666                        'multi_integer',
     2667                        array(
     2668                                'type'         => 'integer',
     2669                                'show_in_rest' => true,
     2670                        )
     2671                );
     2672
     2673                $mid1 = add_post_meta( self::$post_id, 'multi_integer', 1 );
     2674                $mid2 = add_post_meta( self::$post_id, 'multi_integer', 2 );
     2675
     2676                $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2677                $request->set_body_params(
     2678                        array(
     2679                                'meta' => array(
     2680                                        'multi_integer' => array( 2, 3 ),
     2681                                ),
     2682                        )
     2683                );
     2684
     2685                $response = rest_get_server()->dispatch( $request );
     2686
     2687                $this->assertEquals( 200, $response->get_status() );
     2688                $this->assertEquals( array( 2, 3 ), $response->get_data()['meta']['multi_integer'] );
     2689
     2690                $this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
     2691                $this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
     2692        }
     2693
     2694        /**
     2695         * @ticket 49339
     2696         */
     2697        public function test_update_multi_meta_value_handles_boolean_types() {
     2698                $this->grant_write_permission();
     2699
     2700                register_post_meta(
     2701                        'post',
     2702                        'multi_boolean',
     2703                        array(
     2704                                'type'              => 'boolean',
     2705                                'sanitize_callback' => 'absint',
     2706                                'show_in_rest'      => true,
     2707                        )
     2708                );
     2709
     2710                $mid1 = add_post_meta( self::$post_id, 'multi_boolean', 1 );
     2711                $mid2 = add_post_meta( self::$post_id, 'multi_boolean', 0 );
     2712
     2713                $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2714                $request->set_body_params(
     2715                        array(
     2716                                'meta' => array(
     2717                                        'multi_boolean' => array( 0 ),
     2718                                ),
     2719                        )
     2720                );
     2721
     2722                $response = rest_get_server()->dispatch( $request );
     2723
     2724                $this->assertEquals( 200, $response->get_status() );
     2725                $this->assertEquals( array( 0 ), $response->get_data()['meta']['multi_boolean'] );
     2726
     2727                $this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
     2728                $this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
     2729        }
     2730
     2731        /**
     2732         * @ticket 49339
     2733         */
     2734        public function test_update_multi_meta_value_handles_object_types() {
     2735                $this->grant_write_permission();
     2736
     2737                register_post_meta(
     2738                        'post',
     2739                        'multi_object',
     2740                        array(
     2741                                'type'         => 'object',
     2742                                'show_in_rest' => array(
     2743                                        'schema' => array(
     2744                                                'type'       => 'object',
     2745                                                'properties' => array(
     2746                                                        'a' => array(
     2747                                                                'type' => 'string',
     2748                                                        ),
     2749                                                ),
     2750                                        ),
     2751                                ),
     2752                        )
     2753                );
     2754
     2755                $mid1 = add_post_meta( self::$post_id, 'multi_object', array( 'a' => 'ant' ) );
     2756                $mid2 = add_post_meta( self::$post_id, 'multi_object', array( 'a' => 'anaconda' ) );
     2757
     2758                $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2759                $request->set_body_params(
     2760                        array(
     2761                                'meta' => array(
     2762                                        'multi_object' => array(
     2763                                                array( 'a' => 'anaconda' ),
     2764                                                array( 'a' => 'alpaca' ),
     2765                                        ),
     2766                                ),
     2767                        )
     2768                );
     2769
     2770                $response = rest_get_server()->dispatch( $request );
     2771
     2772                $this->assertEquals( 200, $response->get_status() );
     2773                $this->assertEquals(
     2774                        array(
     2775                                array( 'a' => 'anaconda' ),
     2776                                array( 'a' => 'alpaca' ),
     2777                        ),
     2778                        $response->get_data()['meta']['multi_object']
     2779                );
     2780
     2781                $this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
     2782                $this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
     2783        }
     2784
     2785        /**
    26592786         * Internal function used to disable an insert query which
    26602787         * will trigger a wpdb error for testing purposes.
Note: See TracChangeset for help on using the changeset viewer.