Make WordPress Core


Ignore:
Timestamp:
09/25/2023 04:23:52 PM (3 years ago)
Author:
flixos90
Message:

Options, Meta APIs: Improve logic to avoid unnecessary database writes in update_option().

Prior to this change, a strict comparison between the old and new database value could lead to a false negative, since database values are generally stored as strings. For example, passing an integer to update_option() would almost always result in an update given any existing database value for that option would be that number cast to a string.

This changeset adjusts the logic to perform an intentional "loose-y" comparison by casting the values to strings. Extensive coverage previously added in [56648] provides additional confidence that this does not introduce any backward compatibility issues.

Props mukesh27, costdev, spacedmonkey, joemcgill, flixos90, nacin, atimmer, duck_, boonebgorges.
Fixes #22192.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/option/option.php

    r56648 r56681  
    525525                );
    526526        }
     527
     528        /**
     529         * Tests that update_option() stores an option that uses
     530         * an unfiltered default value of (bool) false.
     531         *
     532         * @ticket 22192
     533         *
     534         * @covers ::update_option
     535         */
     536        public function test_update_option_should_store_option_with_default_value_false() {
     537                global $wpdb;
     538
     539                $option = 'update_option_default_false';
     540                update_option( $option, false );
     541
     542                $actual = $wpdb->query(
     543                        $wpdb->prepare(
     544                                "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1",
     545                                $option
     546                        )
     547                );
     548
     549                $this->assertSame( 1, $actual );
     550        }
     551
     552        /**
     553         * Tests that update_option() stores an option that uses
     554         * a filtered default value.
     555         *
     556         * @ticket 22192
     557         *
     558         * @covers ::update_option
     559         */
     560        public function test_update_option_should_store_option_with_filtered_default_value() {
     561                global $wpdb;
     562
     563                $option        = 'update_option_custom_default';
     564                $default_value = 'default-value';
     565
     566                add_filter(
     567                        "default_option_{$option}",
     568                        static function () use ( $default_value ) {
     569                                return $default_value;
     570                        }
     571                );
     572
     573                update_option( $option, $default_value );
     574
     575                $actual = $wpdb->query(
     576                        $wpdb->prepare(
     577                                "SELECT option_name FROM $wpdb->options WHERE option_name = %s LIMIT 1",
     578                                $option
     579                        )
     580                );
     581
     582                $this->assertSame( 1, $actual );
     583        }
    527584}
Note: See TracChangeset for help on using the changeset viewer.