[wp-trac] [WordPress Trac] #42069: Saving metadata fails (randomly) if equal value already exists
WordPress Trac
noreply at wordpress.org
Mon Aug 6 21:25:26 UTC 2018
#42069: Saving metadata fails (randomly) if equal value already exists
-------------------------------------+-----------------------
Reporter: JVel | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: 5.0
Component: REST API | Version: 4.8.2
Severity: normal | Resolution:
Keywords: has-patch needs-testing | Focuses: rest-api
-------------------------------------+-----------------------
Comment (by dcavins):
Hi @MattGeri-
Thanks for your interest in this problem. I took a minute to test your
patch, and meta of the type `boolean` or `integer` is still failing.
Example meta definitions:
{{{#!php
// Boolean
register_meta( 'post', 'featured_item', array(
'sanitize_callback' => 'absint',
'type' => 'boolean',
'description' => 'test',
'single' => true,
'show_in_rest' => true,
) );
// Integer
register_meta( 'post', 'post_order', array(
'sanitize_callback' => 'absint',
'type' => 'integer',
'description' => 'test',
'single' => true,
'show_in_rest' => true,
) );
}}}
The way-down-deep issue for this case is that if you pass in an integer,
like `1`, and the strictly equal check doesn't catch the equivalency, it
will also pass the check in `update_metadata()` (so at least it won't
return `false` at that point) and be passed to `$wpdb->update()`.
`$wpdb->update()` relies on `$wpdb->query()` for the actual insert, and
the returned value is the number of rows affected, which is `0`. This
causes `update_metadata()` to return `false` at this point:
https://core.trac.wordpress.org/browser/tags/4.9.8/src/wp-
includes/meta.php#L251
My patch catches this case because both the old value and new value are
cast to be the same type by the sanitization functions. Now that I know
where the integer/boolean case is failing, I see that there are more ways
to achieve this result, like relaxing the strictness of the check in
`WP_REST_Meta_Fields::update_meta_value()`:
{{{#!php
if ( sanitize_meta( $meta_key, wp_unslash( $meta_value ), $meta_type ) ==
$old_value[0] ) {
return true;
}
}}}
Alternatively, we could cast the incoming value as a string, because we
know all meta values retrieved by `get_metadata()` are strings:
{{{#!php
if ( (string) sanitize_meta( $meta_key, wp_unslash( $meta_value ),
$meta_type ) === $old_value[0] ) {
return true;
}
}}}
Thanks again for your thoughts on this problem.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/42069#comment:15>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list