Skip to content

Commit

Permalink
Handle multiple duplicate values correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
rmccue committed Oct 6, 2016
1 parent 42a0904 commit eb73e62
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
31 changes: 25 additions & 6 deletions lib/fields/class-wp-rest-meta-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,39 @@ protected function update_multi_meta_value( $object, $name, $values ) {
}

$current = get_metadata( $this->get_meta_type(), $object, $name, false );
$to_add = array_diff( $values, $current );
$to_remove = array_diff( $current, $values );

foreach ( $to_add as $value ) {
if ( ! add_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
$to_remove = $current;
$to_add = $values;
foreach ( $to_add as $add_key => $value ) {
$remove_keys = array_keys( $to_remove, $value, true );
if ( empty( $remove_keys ) ) {
continue;
}

if ( count( $remove_keys ) > 1 ) {
// To remove, we need to remove first, then add, so don't touch.
continue;
}

$remove_key = $remove_keys[0];
unset( $to_remove[ $remove_key ] );
unset( $to_add[ $add_key ] );
}

// `delete_metadata` removes _all_ instances of the value, so only call
// once.
$to_remove = array_unique( $to_remove );
foreach ( $to_remove as $value ) {
if ( ! delete_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
return new WP_Error(
'rest_meta_database_error',
__( 'Could not update meta value in database.' ),
array( 'key' => $name, 'status' => WP_HTTP::INTERNAL_SERVER_ERROR )
);
}
}
foreach ( $to_remove as $value ) {
if ( ! delete_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
foreach ( $to_add as $value ) {
if ( ! add_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
return new WP_Error(
'rest_meta_database_error',
__( 'Could not update meta value in database.' ),
Expand Down
28 changes: 28 additions & 0 deletions tests/test-rest-post-meta-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,34 @@ public function test_set_value_multiple() {
$this->assertContains( 'val2', $meta );
}

/**
* Test removing only one item with duplicate items.
*/
public function test_set_value_remove_one() {
add_post_meta( $this->post_id, 'test_multi', 'c' );
add_post_meta( $this->post_id, 'test_multi', 'n' );
add_post_meta( $this->post_id, 'test_multi', 'n' );

$this->grant_write_permission();

$data = array(
'meta' => array(
'test_multi' => array( 'c', 'n' ),
),
);
$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', $this->post_id ) );
$request->set_body_params( $data );

$response = $this->server->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );

$meta = get_post_meta( $this->post_id, 'test_multi', false );
$this->assertNotEmpty( $meta );
$this->assertCount( 2, $meta );
$this->assertContains( 'c', $meta );
$this->assertContains( 'n', $meta );
}

/**
* @depends test_set_value_multiple
*/
Expand Down

0 comments on commit eb73e62

Please sign in to comment.