WordPress.org

Make WordPress Core

Ticket #38786: 38786.2.diff

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

     
    6565                $fields   = $this->get_registered_fields();
    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 ) ) {
    7273                                        $value = $args['schema']['default'];
     
    122123         */
    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;
    128130                        }
     
    132134                         * from the database and then relying on the default value.
    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;
    138140                                }
     
    148150                        $value = rest_sanitize_value_from_schema( $request[ $name ], $args['schema'] );
    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
    156158                        if ( is_wp_error( $result ) ) {
     
    168170         * @access protected
    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',
    179182                                /* translators: %s: custom field key */
     
    182185                        );
    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',
    188191                                __( 'Could not delete meta value from database.' ),
     
    202205         * @access protected
    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',
    214218                                /* translators: %s: custom field key */
     
    217221                        );
    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;
    223227                $to_add    = $values;
     
    244248                $to_remove = array_unique( $to_remove );
    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',
    250254                                        __( 'Could not update meta value in database.' ),
     
    254258                }
    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',
    260264                                        __( 'Could not update meta value in database.' ),
     
    273277         * @access protected
    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',
    285290                                /* translators: %s: custom field key */
     
    288293                        );
    289294                }
    290295
    291                 $meta_key   = wp_slash( $name );
     296                $meta_key   = wp_slash( $meta_key );
    292297                $meta_value = wp_slash( $value );
    293298
    294299                // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
     
    364369                                $rest_args['schema']['type'] = 'array';
    365370                        }
    366371
    367                         $registered[ $rest_args['name'] ] = $rest_args;
     372                        $registered[ $name ] = $rest_args;
    368373                }
    369374
    370375                return $registered;
     
    388393                        'properties'  => array(),
    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
    395400                return $schema;
  • tests/phpunit/tests/rest-api/rest-post-meta-fields.php

     
    7979                        'show_in_rest' => true,
    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;
    84100                $this->server = $wp_rest_server = new Spy_REST_Server;
     
    227243                $this->assertSame( true, $meta['test_bool'] );
    228244        }
    229245
     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'] );
     260        }
     261
    230262        /**
    231263         * @depends test_get_value
    232264         */
     
    681713                $this->assertContains( 8, $meta );
    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' );
    686791                $values = get_post_meta( self::$post_id, 'test_multi', false );
     
    791896                $this->assertErrorResponse( 'rest_meta_database_error', $response, 500 );
    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 ) );
    796923                $response = $this->server->dispatch( $request );