Opened 5 months ago
Last modified 9 hours ago
#60618 new defect (bug)
REST API: Meta update fails if unrelated unchanged field is a multi-item array
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 4.7 |
Component: | REST API | Keywords: | needs-patch |
Focuses: | rest-api | Cc: |
Description
In some plugins there may be code which repeatedly calls add_post_meta
without registration, e.g. calling
<?php add_post_meta( 1, 'example_meta_key', 'A' ); add_post_meta( 1, 'example_meta_key', 'A' ); add_post_meta( 1, 'example_meta_key', 'A' );
In the case where this bug was observed, the meta value was always retrieved as single
, but the add_post_meta()
call never utilized the unique
flag. This results in multiple rows in the database for meta_key example_meta_key
and meta_value A
, for the post 1
.
If the plugin later adds meta registration for this field, and both
- registers the post meta field as
'single' => true
- exposes the post meta field as
'show_in_rest' => true
then subsequent saves to this post through the REST API will fail.
The reason is that the REST API iterates through post meta that is passed back in the REST post, and checks whether the incoming value is the same as the stored value using this check in WP_REST_Meta_Fields::update_meta_value
:
<?php if ( is_array( $old_value ) && 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) { return true; }
In our case the $old_value
will be an array, but the count will be 3, so we never opt in to our similar-data check.
This means that the incoming value will be passed through and will call update_meta
, which will return false
because update_meta returns false
"on failure or if the value passed to the function is the same as the one that is already in the database." (emphasis added)
If a new value is passed for the existing meta, all rows will be updated as expected. It is only unchanged values which fail the comparison.
Summary: Our logic in our update meta function is problematic, and doesn't handle existing arrays of metadata properly when checking for an identical existing value.
Reproduction Report
This report validates that the issue can be reproduced.
Environment
Actual Results
Additional Notes
The issue is consistent with the reporter's description.
Supplemental Artifacts