[wp-trac] [WordPress Trac] #48264: Item type of 'integer' fails to save unchanged values with 'array' type in register_meta()

WordPress Trac noreply at wordpress.org
Wed Oct 9 14:04:40 UTC 2019


#48264: Item type of 'integer' fails to save unchanged values with 'array' type in
register_meta()
--------------------------+-----------------------------
 Reporter:  augustuswm    |      Owner:  (none)
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  General       |    Version:  trunk
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 We have something like the following in our 5.3 based test environment:
 {{{#!php
 <?php
 register_meta('post', 'items',
   [
     'single' => true,
     'type' => 'array',
     'show_in_rest' => [
       'schema' => [
         'type' => 'array',
         'items' => [
           'type' => 'integer'
         ]
       ]
     ]
   ]
 );
 }}}
  This is mirrored by a Gutenberg block with the attributes:
 {{{
 items: {
   type: 'array',
   source: 'meta',
   meta: 'items'
 },
 }}}

 We are running into an issue where saving that meta data when no changes
 have occured results in a 500 (Updating failed. Error message: Could not
 update the meta value of items in database.)

 It looks like it might be related to the early return check in class-wp-
 rest-meta-fields.php at update_meta_value

 For the early return check the $old_value is fetched from the db which
 will always be an array of strings due to meta storage, the new value
 coming in though is an array of integers.
 This causes the early return check to not pass and send the data along to
 update_metadata.

 The update_metadata call though passes in wp_slash($value) which casts all
 of the array elements to strings. So when update_metadata performs its
 check against the old value in the db it sees two string arrays. These
 values being equal it returns false and the REST API identifies it as a
 failure.

 ----------

 From class-wp-rest-meta-fields.php at update_meta_value with incoming $value
 of [1, 2, 3] and a stored db value of ["1", "2", "3"]

 {{{#!php
 <?php
 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); // [["1",
 "2", "3"]]
 ...
 $sanitized = sanitize_meta( $meta_key, $value, $meta_type, $subtype ); //
 [1, 2, 3]
 ...
 if ( $sanitized === $old_value[0] ) { // Check fails
   return true
 }
 ...
 if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ),
 wp_slash( $value ) ) ) { // wp_slash([1, 2, 3]) = ["1", "2", "3"]
   ...
 }
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/48264>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list