Make WordPress Core

Changeset 58782


Ignore:
Timestamp:
07/23/2024 12:25:19 AM (6 months ago)
Author:
peterwilsoncc
Message:

Options, Meta APIs: Prime notoptions cache when deleting options.

Prime the notoptions cache within delete_option and delete_network_option to avoid the need for a database query if get_option or get_network_option is subsequently called.

Adds some associated tests to ensure that an option is cleared from the notoptions cache when an option is added either via add_option, update_option or their network option equivalent.

Props pbearne, mukesh27.
Fixes #61484.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/option.php

    r58416 r58782  
    12181218            wp_cache_delete( $option, 'options' );
    12191219        }
     1220
     1221        $notoptions = wp_cache_get( 'notoptions', 'options' );
     1222
     1223        if ( ! is_array( $notoptions ) ) {
     1224            $notoptions = array();
     1225        }
     1226        $notoptions[ $option ] = true;
     1227
     1228        wp_cache_set( 'notoptions', $notoptions, 'options' );
    12201229    }
    12211230
     
    22852294        do_action( 'delete_site_option', $option, $network_id );
    22862295
     2296        $notoptions_key = "$network_id:notoptions";
     2297        $notoptions     = wp_cache_get( $notoptions_key, 'site-options' );
     2298
     2299        if ( ! is_array( $notoptions ) ) {
     2300            $notoptions = array();
     2301        }
     2302        $notoptions[ $option ] = true;
     2303        wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
     2304
    22872305        return true;
    22882306    }
  • trunk/tests/phpunit/tests/option/networkOption.php

    r56946 r58782  
    5858
    5959    /**
     60     * Tests that calling delete_network_option() updates nooptions when option deleted.
     61     *
     62     * @ticket 61484
     63     *
     64     * @covers ::delete_network_option
     65     */
     66    public function test_check_delete_network_option_updates_notoptions() {
     67        add_network_option( 1, 'foo', 'value1' );
     68
     69        delete_network_option( 1, 'foo' );
     70        $cache_key   = is_multisite() ? '1:notoptions' : 'notoptions';
     71        $cache_group = is_multisite() ? 'site-options' : 'options';
     72        $notoptions  = wp_cache_get( $cache_key, $cache_group );
     73        $this->assertIsArray( $notoptions, 'The notoptions cache is expected to be an array.' );
     74        $this->assertTrue( $notoptions['foo'], 'The deleted options is expected to be in notoptions.' );
     75
     76        $before = get_num_queries();
     77        get_network_option( 1, 'foo' );
     78        $queries = get_num_queries() - $before;
     79
     80        $this->assertSame( 0, $queries, 'get_network_option should not make any database queries.' );
     81    }
     82
     83    /**
    6084     * @ticket 22846
    6185     * @group ms-excluded
     
    229253        $this->assertSame( $num_queries_pre_update, get_num_queries() );
    230254    }
     255
     256    /**
     257     * Tests that calling update_network_option() clears the notoptions cache.
     258     *
     259     * @ticket 61484
     260     *
     261     * @covers ::update_network_option
     262     */
     263    public function test_update_network_option_clears_the_notoptions_cache() {
     264        $option_name = 'ticket_61484_option_to_be_created';
     265        $cache_key   = is_multisite() ? '1:notoptions' : 'notoptions';
     266        $cache_group = is_multisite() ? 'site-options' : 'options';
     267        $notoptions  = wp_cache_get( $cache_key, $cache_group );
     268        if ( ! is_array( $notoptions ) ) {
     269            $notoptions = array();
     270        }
     271        $notoptions[ $option_name ] = true;
     272        wp_cache_set( $cache_key, $notoptions, $cache_group );
     273        $this->assertArrayHasKey( $option_name, wp_cache_get( $cache_key, $cache_group ), 'The "foobar" option should be in the notoptions cache.' );
     274
     275        update_network_option( 1, $option_name, 'baz' );
     276
     277        $updated_notoptions = wp_cache_get( $cache_key, $cache_group );
     278        $this->assertArrayNotHasKey( $option_name, $updated_notoptions, 'The "foobar" option should not be in the notoptions cache after updating it.' );
     279    }
     280
     281    /**
     282     * Tests that calling add_network_option() clears the notoptions cache.
     283     *
     284     * @ticket 61484
     285     *
     286     * @covers ::add_network_option
     287     */
     288    public function test_add_network_option_clears_the_notoptions_cache() {
     289        $option_name = 'ticket_61484_option_to_be_created';
     290        $cache_key   = is_multisite() ? '1:notoptions' : 'notoptions';
     291        $cache_group = is_multisite() ? 'site-options' : 'options';
     292        $notoptions  = wp_cache_get( $cache_key, $cache_group );
     293        if ( ! is_array( $notoptions ) ) {
     294            $notoptions = array();
     295        }
     296        $notoptions[ $option_name ] = true;
     297        wp_cache_set( $cache_key, $notoptions, $cache_group );
     298        $this->assertArrayHasKey( $option_name, wp_cache_get( $cache_key, $cache_group ), 'The "foobar" option should be in the notoptions cache.' );
     299
     300        add_network_option( 1, $option_name, 'baz' );
     301
     302        $updated_notoptions = wp_cache_get( $cache_key, $cache_group );
     303        $this->assertArrayNotHasKey( $option_name, $updated_notoptions, 'The "foobar" option should not be in the notoptions cache after updating it.' );
     304    }
    231305}
  • trunk/tests/phpunit/tests/option/option.php

    r57920 r58782  
    479479        $this->assertFalse( get_option( 'foo' ) );
    480480    }
     481
     482    /**
     483     * Tests that calling delete_option() updates notoptions when option deleted.
     484     *
     485     * @ticket 61484
     486     *
     487     * @covers ::delete_option
     488     */
     489    public function test_check_delete_option_updates_notoptions() {
     490        add_option( 'foo', 'value1' );
     491
     492        delete_option( 'foo' );
     493        $notoptions = wp_cache_get( 'notoptions', 'options' );
     494        $this->assertIsArray( $notoptions, 'The notoptions cache is expected to be an array.' );
     495        $this->assertTrue( $notoptions['foo'], 'The deleted options is expected to be in notoptions.' );
     496
     497        $before = get_num_queries();
     498        get_option( 'foo' );
     499        $queries = get_num_queries() - $before;
     500
     501        $this->assertSame( 0, $queries, 'get_option should not make any database queries.' );
     502    }
     503
     504    /**
     505     * Tests that calling update_option() clears the notoptions cache.
     506     *
     507     * @ticket 61484
     508     *
     509     * @covers ::update_option
     510     */
     511    public function test_update_option_clears_the_notoptions_cache() {
     512        $option_name = 'ticket_61484_option_to_be_created';
     513        $notoptions  = wp_cache_get( 'notoptions', 'options' );
     514        if ( ! is_array( $notoptions ) ) {
     515            $notoptions = array();
     516        }
     517        $notoptions[ $option_name ] = true;
     518        wp_cache_set( 'notoptions', $notoptions, 'options' );
     519        $this->assertArrayHasKey( $option_name, wp_cache_get( 'notoptions', 'options' ), 'The "foobar" option should be in the notoptions cache.' );
     520
     521        update_option( $option_name, 'baz' );
     522
     523        $updated_notoptions = wp_cache_get( 'notoptions', 'options' );
     524        $this->assertArrayNotHasKey( $option_name, $updated_notoptions, 'The "foobar" option should not be in the notoptions cache after updating it.' );
     525    }
     526
     527    /**
     528     * Tests that calling add_option() clears the notoptions cache.
     529     *
     530     * @ticket 61484
     531     *
     532     * @covers ::add_option
     533     */
     534    public function test_add_option_clears_the_notoptions_cache() {
     535        $option_name = 'ticket_61484_option_to_be_created';
     536        $notoptions  = wp_cache_get( 'notoptions', 'options' );
     537        if ( ! is_array( $notoptions ) ) {
     538            $notoptions = array();
     539        }
     540        $notoptions[ $option_name ] = true;
     541        wp_cache_set( 'notoptions', $notoptions, 'options' );
     542        $this->assertArrayHasKey( $option_name, wp_cache_get( 'notoptions', 'options' ), 'The "foobar" option should be in the notoptions cache.' );
     543
     544        add_option( $option_name, 'baz' );
     545
     546        $updated_notoptions = wp_cache_get( 'notoptions', 'options' );
     547        $this->assertArrayNotHasKey( $option_name, $updated_notoptions, 'The "foobar" option should not be in the notoptions cache after adding it.' );
     548    }
    481549}
Note: See TracChangeset for help on using the changeset viewer.