WordPress.org

Make WordPress Core

Opened 5 months ago

Closed 4 weeks ago

Last modified 4 weeks ago

#49339 closed defect (bug) (fixed)

Issue when comparing old and new meta of type integer on update_multi_meta_value

Reported by: renathoc Owned by: TimothyBlynJacobs
Milestone: 5.5 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: has-patch has-unit-tests commit
Focuses: rest-api Cc:

Description

Hi there!

I found an issue when updating a meta through JS (REST API). I'm using a plugin sidebar to update a post meta with the type integer.

When I update the meta value, the WP_REST_Meta_Fields::update_multi_meta_value method tries to compare the old and the new values to remove and add only the necessary.

But the $current = get_metadata( $meta_type, $object_id, $meta_key, false ); line always return an array of string and the $values is correctly an array of integer. So any value doesn't match, and all old post metas are deleted and all new post metas are added.

The line that tries to compare is: $remove_keys = array_keys( $to_remove, $value, true );

Example:

  • We have as a post metas: [ 1, 2 ] and try to update for [ 2, 3 ]
  • It's removing the 1 and 2. And after that it's adding the 2 and 3
  • It should remove the 1 and add the 3

Workaround:

As a workaround, I'm thinking to use temporarily get_post_metadata to return the value correctly (as integer).

The steps to reproduce:

I created a clean repo with the scenario to make it easier to simulate: https://github.com/renatho/meta-type-test-plugin/tree/master

  • Clone the repo
  • Run npm i && npm run build.
  • Add the plugin to a WP env.
  • Go to a post.
  • Click on the smile on the top right.
  • Change between the options clicking on the buttons and saving the post.
  • Check the post comments to see the result.

Change History (7)

#2 @TimothyBlynJacobs
7 weeks ago

  • Keywords has-patch has-unit-tests dev-feedback added
  • Milestone changed from Awaiting Review to 5.5
  • Owner set to TimothyBlynJacobs
  • Status changed from new to assigned
  • Version changed from 5.4 to 4.7

Hi @renathoc,

Thanks for reporting this and welcome to trac!

As far as I can tell, this is the same underlying cause as #42069 but for multi meta.

I've attached a preliminary patch which applies the same sanitization we use when updating a single value. Needs more unit tests covering the different meta types.

Could you try applying the change to see if it fixes your issue @renathoc?

Looping in @kadamwhite.

#3 @renathoc
7 weeks ago

Hey @TimothyBlynJacobs!

Sure! I tested and it's working with the change. Thank you for fixing!

#4 @SergeyBiryukov
4 weeks ago

  • Keywords commit added; dev-feedback removed

Took a quick look at the patch. The proposed changes and the tests make sense to me.

#5 @TimothyBlynJacobs
4 weeks ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 47943:

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.

#6 @renathoc
4 weeks ago

Thank you for the fix, @TimothyBlynJacobs and @SergeyBiryukov!

#7 @TimothyBlynJacobs
4 weeks ago

No problem, thanks for reporting the issue @renathoc!

Note: See TracTickets for help on using tickets.