From a353d968a7867d10aede8176dc36a70a1e9c4920 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 5 Mar 2018 11:44:57 +0530 Subject: [PATCH 1/2] Add test cases for object modification behavior --- features/option-pluck-patch.feature | 30 +++++++++++++++++++ tests/RecursiveDataStructureTraverserTest.php | 13 ++++++++ 2 files changed, 43 insertions(+) diff --git a/features/option-pluck-patch.feature b/features/option-pluck-patch.feature index fa790e406..1d80a52aa 100644 --- a/features/option-pluck-patch.feature +++ b/features/option-pluck-patch.feature @@ -269,3 +269,33 @@ Feature: Option commands have pluck and patch. """ [ "new", "bar" ] """ + + @patch @pluck + Scenario: An object value can be updated + Given a WP install + And a setup.php file: + """ + test_mode = 0; + $ret = update_option( 'wp_cli_test', $option ); + """ + And I run `wp eval-file setup.php` + + When I run `wp option pluck wp_cli_test test_mode` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp option patch update wp_cli_test test_mode 1` + Then STDOUT should be: + """ + Success: Updated 'wp_cli_test' option. + """ + + When I run `wp option pluck wp_cli_test test_mode` + Then STDOUT should be: + """ + 1 + """ diff --git a/tests/RecursiveDataStructureTraverserTest.php b/tests/RecursiveDataStructureTraverserTest.php index 635e57ba4..b08b38f03 100644 --- a/tests/RecursiveDataStructureTraverserTest.php +++ b/tests/RecursiveDataStructureTraverserTest.php @@ -86,6 +86,19 @@ function it_can_set_a_nested_object_value() { $this->assertEquals( 'new', $object->foo->bar ); } + /** @test */ + function it_can_update_an_integer_object_value() { + $object = (object) array( + 'test_mode' => 0, + ); + $this->assertEquals( 0, $object->test_mode ); + + $traverser = new RecursiveDataStructureTraverser( $object ); + $traverser->update( array( 'test_mode' ), 1 ); + + $this->assertEquals( 1, $object->test_mode ); + } + /** @test */ function it_can_delete_a_nested_array_value() { $array = array( From fa6389a25f57ddda668b956495bb70ce0f0012c9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 5 Mar 2018 11:47:42 +0530 Subject: [PATCH 2/2] Properly clone objects for comparison Otherwise, they're handled by reference and transformed on update --- src/Option_Command.php | 3 +++ src/Site_Option_Command.php | 3 +++ src/WP_CLI/CommandWithMeta.php | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/Option_Command.php b/src/Option_Command.php index cfe11d10d..42aca0ffb 100644 --- a/src/Option_Command.php +++ b/src/Option_Command.php @@ -543,6 +543,9 @@ public function patch( $args, $assoc_args ) { /* Need to make a copy of $current_value here as it is modified by reference */ $old_value = $current_value = sanitize_option( $key, get_option( $key ) ); + if ( is_object( $current_value ) ) { + $old_value = clone $current_value; + } $traverser = new RecursiveDataStructureTraverser( $current_value ); diff --git a/src/Site_Option_Command.php b/src/Site_Option_Command.php index 3822631b8..2c4d39e5e 100644 --- a/src/Site_Option_Command.php +++ b/src/Site_Option_Command.php @@ -372,6 +372,9 @@ public function patch( $args, $assoc_args ) { /* Need to make a copy of $current_value here as it is modified by reference */ $old_value = $current_value = sanitize_option( $key, get_site_option( $key ) ); + if ( is_object( $current_value ) ) { + $old_value = clone $current_value; + } $traverser = new RecursiveDataStructureTraverser( $current_value ); diff --git a/src/WP_CLI/CommandWithMeta.php b/src/WP_CLI/CommandWithMeta.php index d69e6f986..4f383ed54 100644 --- a/src/WP_CLI/CommandWithMeta.php +++ b/src/WP_CLI/CommandWithMeta.php @@ -390,6 +390,9 @@ public function patch( $args, $assoc_args ) { /* Need to make a copy of $current_meta_value here as it is modified by reference */ $current_meta_value = $old_meta_value = sanitize_meta( $meta_key, get_metadata( $this->meta_type, $object_id, $meta_key, true ), $this->meta_type ); + if ( is_object( $current_meta_value ) ) { + $old_meta_value = clone $current_meta_value; + } $traverser = new RecursiveDataStructureTraverser( $current_meta_value );