diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index 9239f68b5f766..13831898a6835 100644 --- a/src/wp-includes/option.php +++ b/src/wp-includes/option.php @@ -1233,14 +1233,14 @@ function delete_option( $option ) { if ( in_array( $row->autoload, wp_autoload_values_to_autoload(), true ) ) { $alloptions = wp_load_alloptions( true ); - if ( is_array( $alloptions ) && isset( $alloptions[ $option ] ) ) { + if ( is_array( $alloptions ) && array_key_exists( $option, $alloptions ) ) { unset( $alloptions[ $option ] ); wp_cache_set( 'alloptions', $alloptions, 'options' ); } - } else { - wp_cache_delete( $option, 'options' ); } + wp_cache_delete( $option, 'options' ); + $notoptions = wp_cache_get( 'notoptions', 'options' ); if ( ! is_array( $notoptions ) ) { diff --git a/tests/phpunit/tests/option/option.php b/tests/phpunit/tests/option/option.php index 9a2f061aa369c..031f92c08bb4e 100644 --- a/tests/phpunit/tests/option/option.php +++ b/tests/phpunit/tests/option/option.php @@ -613,4 +613,28 @@ public function helper_object_cache_stats_cmd_get() { return $stats['cmd_get']; } + + /** + * Test that delete_option() properly removes options with null values from cache. + * + * @ticket 28701 + * + * @covers ::delete_option + */ + public function test_delete_option_with_null_value_in_cache() { + $option_name = 'test_null_cache_' . wp_rand(); + + add_option( $option_name, 'value', '', true ); + + $alloptions = wp_load_alloptions(); + $alloptions[ $option_name ] = null; + wp_cache_set( 'alloptions', $alloptions, 'options' ); + + delete_option( $option_name ); + + $alloptions_after = wp_load_alloptions(); + $this->assertArrayNotHasKey( $option_name, $alloptions_after ); + + $this->assertSame( 'default', get_option( $option_name, 'default' ) ); + } }