My particular situation involved updating a user via REST API with a custom registered user meta. The meta updates correctly the first time, and any time there is a change. However an error is thrown if the user update includes the unchanged user meta (i.e. I’m updating the user’s first name, but my solution includes all fields with each update). The user meta value was a quoted JSON object, but this also applies to other serialized values. This also occurs with custom meta for other types besides users, like posts or comments.
The server returns a 500 HTTP status, with the following response:
{“code”:”rest_meta_database_error”,”message”:”Could not update meta value in database.”,”data”:{“key”:”my_custom_meta_key”,”status”:500}}
Credit for identifying this bug goes to Corey Salzano. Corey’s solution is to first pull the data, and if there’s no change, omit it in the update request. I didn’t want to add another request to the server, so I came up with a server-side solution. It is provided below with no guarantees!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Fix for WP REST API meta error when sending updated encoded JSON with no change add_filter( 'update_user_metadata' , function ( $value , $object_id , $meta_key = false , $meta_value, $prev_value ) { $meta_type = 'user'; $serialized_meta_keys = array( 'my_special_custom_key' ); if ( defined('REST_REQUEST') && REST_REQUEST && in_array($meta_key, $serialized_meta_keys) ) { $meta_cache = wp_cache_get($object_id, $meta_type . '_meta'); if ( !$meta_cache ) { $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); $meta_cache = $meta_cache[$object_id]; } if ( isset($meta_cache[$meta_key]) ) { if ( $meta_value === $meta_cache[$meta_key][0] ) return true; } } return $value; }, 10 , 5 ); |
Note that you will have to change the hook update_user_metadata and $meta_type and $serialized_meta_keys for your particular situation.