Skip to content

Commit

Permalink
Options, Meta APIs: Fix minor compatibility issue with `update_option…
Browse files Browse the repository at this point in the history
…()` change.

When calling `update_option()` with value `false` on a non-existent option, prior to [56681] the function would have returned `false` and not stored the value in the database, since the given value was the same as the default.

The aforementioned changeset broke that promise with good intention, however this particular change was a backward compatibility break and therefore is resolved here.

Props mukesh27, costdev.
Fixes #22192.


git-svn-id: https://develop.svn.wordpress.org/trunk@56788 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
felixarntz committed Oct 5, 2023
1 parent 23c811e commit b77b8fd
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
8 changes: 7 additions & 1 deletion src/wp-includes/option.php
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,13 @@ function update_option( $option, $value, $autoload = null ) {
*
* See https://core.trac.wordpress.org/ticket/38903 and https://core.trac.wordpress.org/ticket/22192.
*/
if ( $raw_old_value !== $default_value && _is_equal_database_value( $raw_old_value, $value ) ) {
if (
$value === $raw_old_value ||
(
$raw_old_value !== $default_value &&
_is_equal_database_value( $raw_old_value, $value )
)
) {
return false;
}

Expand Down
15 changes: 10 additions & 5 deletions tests/phpunit/tests/option/option.php
Original file line number Diff line number Diff line change
Expand Up @@ -639,10 +639,11 @@ public function data_strictly_equal_values() {
'(int) 0' => array( 0, 0 ),
'(float) 0.0' => array( 0.0, 0.0 ),
'empty array' => array( array(), array() ),
'false' => array( false, false ),

/*
* false and null are not included in these datasets
* because false is the default value, which triggers
* null is not included in these datasets because
* false is the default value, which triggers
* a call to add_option().
*
* See data_stored_as_empty_string() and its related test.
Expand Down Expand Up @@ -679,7 +680,6 @@ public function test_update_option_should_add_option_when_the_new_value_is_store
*/
public function data_stored_as_empty_string() {
return array(
'false' => array( false ),
'empty string' => array( '' ),
'null' => array( null ),
);
Expand All @@ -705,7 +705,12 @@ static function () use ( $default_value ) {
}
);

$this->assertTrue( update_option( $option, $default_value ), 'update_option() should have returned true.' );
/*
* For a non existing option with the unfiltered default of false, passing false here wouldn't work.
* Because the default is different than false here though, passing false is expected to result in
* a database update.
*/
$this->assertTrue( update_option( $option, false ), 'update_option() should have returned true.' );

$actual = $wpdb->get_row(
$wpdb->prepare(
Expand All @@ -716,7 +721,7 @@ static function () use ( $default_value ) {

$this->assertIsObject( $actual, 'The option was not added to the database.' );
$this->assertObjectHasProperty( 'option_value', $actual, 'The "option_value" property was not included.' );
$this->assertSame( $default_value, $actual->option_value, 'The value was not stored as an empty string.' );
$this->assertSame( '', $actual->option_value, 'The new value was not stored in the database.' );
}

/**
Expand Down

0 comments on commit b77b8fd

Please sign in to comment.