[wp-trac] [WordPress Trac] #60618: REST API: Meta update fails if unrelated unchanged field is a multi-item array

WordPress Trac noreply at wordpress.org
Fri Aug 9 13:49:01 UTC 2024


#60618: REST API: Meta update fails if unrelated unchanged field is a multi-item
array
-------------------------------------------------+-------------------------
 Reporter:  kadamwhite                           |       Owner:  (none)
     Type:  defect (bug)                         |      Status:  new
 Priority:  normal                               |   Milestone:  Awaiting
                                                 |  Review
Component:  REST API                             |     Version:  4.7
 Severity:  normal                               |  Resolution:
 Keywords:  has-patch has-unit-tests has-        |     Focuses:  rest-api
  testing-info                                   |
-------------------------------------------------+-------------------------
Changes (by antonvlasenko):

 * keywords:  has-patch has-unit-tests => has-patch has-unit-tests has-
     testing-info


Comment:

 The [https://github.com/WordPress/wordpress-develop/pull/7149 PR] I've
 submitted addresses the issue of updating meta values with duplicate
 entries.

 === Current behavior ===

 The current implementation of the `update_metadata()` function can lead to
 three possible outcomes:

 # '''Invalid ID or data:'''
    * If the ID, type, or other data related to the metadata entity being
 updated is not valid, the function returns `false`.
    * This results in a `rest_meta_database_error` REST response code and a
 500 HTTP status returned by `WP_REST_Meta_Fields::update_meta_value()
 method`.

 # '''No rows affected:'''
    * If the ID and data are valid, but no rows in the database are updated
 or inserted (i.e., the number of affected rows is 0), the function still
 returns `false`.
    * This outcome also results in a `rest_meta_database_error` REST
 response code and a 500 HTTP status, even though no actual database error
 occurs.

 # '''Successful update:'''
    * If the ID and data are valid and the number of affected rows in the
 database is greater than 0, the function results in a success response.

 === Issue with current implementation ===

 The second outcome is problematic because it incorrectly signals a
 database error when no rows are affected, despite no actual error
 occurring. This leads to misleading error responses, which can be
 confusing and unhelpful for users and developers.

 === Proposed solution ===

 To address this issue, my PR introduces a new parameter, `$is_failure`, to
 the `update_metadata()` function. This parameter allows the function to
 differentiate between a true database error and a situation where no rows
 are affected. With this change:

 * The function can accurately determine when a database error occurs.
 * The REST API can return more precise response codes and HTTP statuses.
 * The misleading signaling of errors in the second outcome is resolved.

 === Steps to test this PR ===

 1. Create a new post in WordPress and note the post ID (`$post_id`) for
 reference.
 2. Add three identical meta values to the newly created post:
 {{{
 add_post_meta( $post_id, 'foo_meta_key', 'bar' );
 add_post_meta( $post_id, 'foo_meta_key', 'bar' );
 add_post_meta( $post_id, 'foo_meta_key', 'bar' );
 }}}

 3. Register your custom post meta:
 {{{
 register_post_meta(
     'YOUR_POST_TYPE',
     'foo_meta_key',
     array(
         'show_in_rest'  => true,
         'single'        => true,
         'type'          => 'string',
         'auth_callback' => function () {
             return current_user_can( 'edit_posts' );
         },
     )
 );
 }}}

 4. Send a POST request to the `/wp/v2/<your_post_type>/ . $post_id`
 endpoint to update the meta value. Ensure the meta value used matches the
 value added initially (e.g., `'bar'`).
 (very general) example that uses `curl`:
 {{{
 curl -X POST https://your-wordpress-site.com/wp-
 json/wp/v2/<your_post_type>/<post_id> \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
           "meta": {
               "foo_meta_key": "bar"
           }
       }'
 }}}

 5. Ensure that the request is successful by checking for a `200` response
 code.

 *Note:* This test case is covered by the
 `WP_Test_REST_Post_Meta_Fields::test_update_meta_should_not_fail_with_duplicate_values_for_single_registered_post_meta`
 test, ensuring that updating meta values with duplicate entries does not
 result in errors.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/60618#comment:5>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list