Make WordPress Core

Changeset 39328


Ignore:
Timestamp:
11/21/2016 05:40:46 AM (8 years ago)
Author:
rmccue
Message:

REST API: Correctly map meta keys to field names.

This accidentally assumed $name was the same as $meta_key, which ruined the whole point of $name.

Props tharsheblows, joehoyle.
Fixes #38786.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php

    r39251 r39328  
    6666        $response = array();
    6767
    68         foreach ( $fields as $name => $args ) {
    69             $all_values = get_metadata( $this->get_meta_type(), $object_id, $name, false );
     68        foreach ( $fields as $meta_key => $args ) {
     69            $name = $args['name'];
     70            $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false );
    7071            if ( $args['single'] ) {
    7172                if ( empty( $all_values ) ) {
     
    123124    public function update_value( $request, $object_id ) {
    124125        $fields = $this->get_registered_fields();
    125         foreach ( $fields as $name => $args ) {
     126        foreach ( $fields as $meta_key => $args ) {
     127            $name = $args['name'];
    126128            if ( ! array_key_exists( $name, $request ) ) {
    127129                continue;
     
    133135             */
    134136            if ( is_null( $request[ $name ] ) ) {
    135                 $result = $this->delete_meta_value( $object_id, $name );
     137                $result = $this->delete_meta_value( $object_id, $meta_key, $name );
    136138                if ( is_wp_error( $result ) ) {
    137139                    return $result;
     
    149151
    150152            if ( $args['single'] ) {
    151                 $result = $this->update_meta_value( $object_id, $name, $value );
     153                $result = $this->update_meta_value( $object_id, $meta_key, $name, $value );
    152154            } else {
    153                 $result = $this->update_multi_meta_value( $object_id, $name, $value );
     155                $result = $this->update_multi_meta_value( $object_id, $meta_key, $name, $value );
    154156            }
    155157
     
    169171     *
    170172     * @param int    $object_id Object ID the field belongs to.
    171      * @param string $name      Key for the field.
     173     * @param string $meta_key  Key for the field.
     174     * @param string $name      Name for the field that is exposed in the REST API.
    172175     * @return bool|WP_Error True if meta field is deleted, WP_Error otherwise.
    173176     */
    174     protected function delete_meta_value( $object_id, $name ) {
     177    protected function delete_meta_value( $object_id, $meta_key, $name ) {
    175178        $meta_type = $this->get_meta_type();
    176         if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $name ) ) {
     179        if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) {
    177180            return new WP_Error(
    178181                'rest_cannot_delete',
     
    183186        }
    184187
    185         if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $name ) ) ) {
     188        if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
    186189            return new WP_Error(
    187190                'rest_meta_database_error',
     
    203206     *
    204207     * @param int    $object_id Object ID to update.
    205      * @param string $name      Key for the custom field.
     208     * @param string $meta_key  Key for the custom field.
     209     * @param string $name      Name for the field that is exposed in the REST API.
    206210     * @param array  $values    List of values to update to.
    207211     * @return bool|WP_Error True if meta fields are updated, WP_Error otherwise.
    208212     */
    209     protected function update_multi_meta_value( $object_id, $name, $values ) {
     213    protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) {
    210214        $meta_type = $this->get_meta_type();
    211         if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $name ) ) {
     215        if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) {
    212216            return new WP_Error(
    213217                'rest_cannot_update',
     
    218222        }
    219223
    220         $current = get_metadata( $meta_type, $object_id, $name, false );
     224        $current = get_metadata( $meta_type, $object_id, $meta_key, false );
    221225
    222226        $to_remove = $current;
     
    245249
    246250        foreach ( $to_remove as $value ) {
    247             if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $name ), wp_slash( $value ) ) ) {
     251            if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
    248252                return new WP_Error(
    249253                    'rest_meta_database_error',
     
    255259
    256260        foreach ( $to_add as $value ) {
    257             if ( ! add_metadata( $meta_type, $object_id, wp_slash( $name ), wp_slash( $value ) ) ) {
     261            if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
    258262                return new WP_Error(
    259263                    'rest_meta_database_error',
     
    274278     *
    275279     * @param int    $object_id Object ID to update.
    276      * @param string $name      Key for the custom field.
     280     * @param string $meta_key  Key for the custom field.
     281     * @param string $name      Name for the field that is exposed in the REST API.
    277282     * @param mixed  $value     Updated value.
    278283     * @return bool|WP_Error True if the meta field was updated, WP_Error otherwise.
    279284     */
    280     protected function update_meta_value( $object_id, $name, $value ) {
     285    protected function update_meta_value( $object_id, $meta_key, $name, $value ) {
    281286        $meta_type = $this->get_meta_type();
    282         if ( ! current_user_can(  "edit_{$meta_type}_meta", $object_id, $name ) ) {
     287        if ( ! current_user_can(  "edit_{$meta_type}_meta", $object_id, $meta_key ) ) {
    283288            return new WP_Error(
    284289                'rest_cannot_update',
     
    289294        }
    290295
    291         $meta_key   = wp_slash( $name );
     296        $meta_key   = wp_slash( $meta_key );
    292297        $meta_value = wp_slash( $value );
    293298
     
    365370            }
    366371
    367             $registered[ $rest_args['name'] ] = $rest_args;
     372            $registered[ $name ] = $rest_args;
    368373        }
    369374
     
    389394        );
    390395
    391         foreach ( $fields as $key => $args ) {
    392             $schema['properties'][ $key ] = $args['schema'];
     396        foreach ( $fields as $args ) {
     397            $schema['properties'][ $args['name'] ] = $args['schema'];
    393398        }
    394399
  • trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r39222 r39328  
    8080        ));
    8181
     82        register_meta( 'post', 'test_custom_name', array(
     83            'single' => true,
     84            'type' => 'string',
     85            'show_in_rest' => array(
     86                'name'  => 'new_name',
     87            ),
     88        ));
     89
     90        register_meta( 'post', 'test_custom_name_multi', array(
     91            'single' => false,
     92            'type' => 'string',
     93            'show_in_rest' => array(
     94                'name'  => 'new_name_multi',
     95            ),
     96        ));
     97
    8298        /** @var WP_REST_Server $wp_rest_server */
    8399        global $wp_rest_server;
     
    226242        $this->assertInternalType( 'boolean', $meta['test_bool'] );
    227243        $this->assertSame( true, $meta['test_bool'] );
     244    }
     245
     246    public function test_get_value_custom_name() {
     247        add_post_meta( self::$post_id, 'test_custom_name', 'janet' );
     248
     249        $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     250        $response = $this->server->dispatch( $request );
     251
     252        $this->assertEquals( 200, $response->get_status() );
     253
     254        $data = $response->get_data();
     255        $this->assertArrayHasKey( 'meta', $data );
     256
     257        $meta = (array) $data['meta'];
     258        $this->assertArrayHasKey( 'new_name', $meta );
     259        $this->assertEquals( 'janet', $meta['new_name'] );
    228260    }
    229261
     
    682714    }
    683715
     716    /**
     717     * @depends test_get_value_custom_name
     718     */
     719    public function test_set_value_custom_name() {
     720        // Ensure no data exists currently.
     721        $values = get_post_meta( self::$post_id, 'test_custom_name', false );
     722        $this->assertEmpty( $values );
     723
     724        $this->grant_write_permission();
     725
     726        $data = array(
     727            'meta' => array(
     728                'new_name' => 'janet',
     729            ),
     730        );
     731        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     732        $request->set_body_params( $data );
     733
     734        $response = $this->server->dispatch( $request );
     735        $this->assertEquals( 200, $response->get_status() );
     736
     737        $meta = get_post_meta( self::$post_id, 'test_custom_name', false );
     738        $this->assertNotEmpty( $meta );
     739        $this->assertCount( 1, $meta );
     740        $this->assertEquals( 'janet', $meta[0] );
     741
     742        $data = $response->get_data();
     743        $meta = (array) $data['meta'];
     744        $this->assertArrayHasKey( 'new_name', $meta );
     745        $this->assertEquals( 'janet', $meta['new_name'] );
     746    }
     747
     748    public function test_set_value_custom_name_multiple() {
     749        // Ensure no data exists currently.
     750        $values = get_post_meta( self::$post_id, 'test_custom_name_multi', false );
     751        $this->assertEmpty( $values );
     752
     753        $this->grant_write_permission();
     754
     755        $data = array(
     756            'meta' => array(
     757                'new_name_multi' => array( 'janet' ),
     758            ),
     759        );
     760        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     761        $request->set_body_params( $data );
     762
     763        $response = $this->server->dispatch( $request );
     764        $this->assertEquals( 200, $response->get_status() );
     765
     766        $meta = get_post_meta( self::$post_id, 'test_custom_name_multi', false );
     767        $this->assertNotEmpty( $meta );
     768        $this->assertCount( 1, $meta );
     769        $this->assertEquals( 'janet', $meta[0] );
     770
     771        // Add another value.
     772        $data = array(
     773            'meta' => array(
     774                'new_name_multi' => array( 'janet', 'graeme' ),
     775            ),
     776        );
     777        $request->set_body_params( $data );
     778
     779        $response = $this->server->dispatch( $request );
     780        $this->assertEquals( 200, $response->get_status() );
     781
     782        $meta = get_post_meta( self::$post_id, 'test_custom_name_multi', false );
     783        $this->assertNotEmpty( $meta );
     784        $this->assertCount( 2, $meta );
     785        $this->assertContains( 'janet', $meta );
     786        $this->assertContains( 'graeme', $meta );
     787    }
     788
    684789    public function test_remove_multi_value_db_error() {
    685790        add_post_meta( self::$post_id, 'test_multi', 'val1' );
     
    792897    }
    793898
     899    public function test_delete_value_custom_name() {
     900        add_post_meta( self::$post_id, 'test_custom_name', 'janet' );
     901        $current = get_post_meta( self::$post_id, 'test_custom_name', true );
     902        $this->assertEquals( 'janet', $current );
     903
     904        $this->grant_write_permission();
     905
     906        $data = array(
     907            'meta' => array(
     908                'new_name' => null,
     909            ),
     910        );
     911        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     912        $request->set_body_params( $data );
     913
     914        $response = $this->server->dispatch( $request );
     915        $this->assertEquals( 200, $response->get_status() );
     916
     917        $meta = get_post_meta( self::$post_id, 'test_custom_name', false );
     918        $this->assertEmpty( $meta );
     919    }
     920
    794921    public function test_get_schema() {
    795922        $request = new WP_REST_Request( 'OPTIONS', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
Note: See TracChangeset for help on using the changeset viewer.