Make WordPress Core


Ignore:
Timestamp:
09/25/2023 04:23:52 PM (10 months 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.