Make WordPress Core

Changeset 57029

Timestamp:
10/30/2023 10:56:25 PM (9 months ago)
Author:
peterwilsoncc
Message:

Options, Meta APIs: Fast follow fixes for option cache priming functions.

A collection of fixes for wp_prime_option_caches():

  • cache arrays and objects in their serialized form for consistency with get_option() and wp_load_alloptions()
  • prevent repeat database queries for falsey and known non-existent options (notoptions)

Additional tests for wp_prime_option_caches() to ensure:

  • additional database queries are not made repriming options (known, known-unknown and alloptions)
  • cache is primed consistently
  • get_option() returns a consistent value regardless of how it is primed
  • database queries do not contain earlier primed options
  • get_option does not prime the cache when testing the cache has been successfully primed

Fixes a test for wp_prime_option_caches_by_group() to ensure get_option does not prime the cache when testing the cache has been successfully primed.

Follow up to [56445],[56990],[57013].

Props peterwilsoncc, costdev, flixos90, hellofromTonya, mikeschroder, joemcgill.
Fixes #59738. See #58962.

Location:
trunk
Files:
3 edited

Legend:

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

    r57013 r57029  
    262262    $alloptions     = wp_load_alloptions();
    263263    $cached_options = wp_cache_get_multiple( $options, 'options' );
     264
     265
     266
     267
    264268
    265269    // Filter options that are not in the cache.
    266270    $options_to_prime = array();
    267271    foreach ( $options as $option ) {
    268         if ( ( ! isset( $cached_options[ $option ] ) || ! $cached_options[ $option ] ) && ! isset( $alloptions[ $option ] ) ) {
     272        if (
     273            ( ! isset( $cached_options[ $option ] ) || false === $cached_options[ $option ] )
     274            && ! isset( $alloptions[ $option ] )
     275            && ! isset( $notoptions[ $option ] )
     276        ) {
    269277            $options_to_prime[] = $option;
    270278        }
     
    289297    $options_found = array();
    290298    foreach ( $results as $result ) {
    291         $options_found[ $result->option_name ] = maybe_unserialize( $result->option_value );
     299        /*
     300         * The cache is primed with the raw value (i.e. not maybe_unserialized).
     301         *
     302         * `get_option()` will handle unserializing the value as needed.
     303         */
     304        $options_found[ $result->option_name ] = $result->option_value;
    292305    }
    293306    wp_cache_set_multiple( $options_found, 'options' );
     
    299312
    300313    $options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) );
    301 
    302     $notoptions = wp_cache_get( 'notoptions', 'options' );
    303 
    304     if ( ! is_array( $notoptions ) ) {
    305         $notoptions = array();
    306     }
    307314
    308315    // Add the options that were not found to the cache.
  • trunk/tests/phpunit/tests/option/wpPrimeOptionCaches.php

    r57013 r57029  
    4242        foreach ( $options_to_prime as $option ) {
    4343            $this->assertSame(
     44
    4445                wp_cache_get( $option, 'options' ),
    45                 get_option( $option ),
    4646                "$option was not primed in the 'options' cache group."
    4747            );
    4848
    49             $this->assertFalse(
    50                 wp_cache_get( $option, 'notoptions' ),
    51                 get_option( $option ),
    52                 "$option was primed in the 'notoptions' cache group."
     49            $new_notoptions = wp_cache_get( $option, 'notoptions' );
     50            if ( ! is_array( $new_notoptions ) ) {
     51                $new_notoptions = array();
     52            }
     53            $this->assertArrayNotHasKey(
     54                $option,
     55                $new_notoptions,
     56                "$option was primed in the 'notoptions' cache."
    5357            );
    5458        }
     
    6367
    6468    /**
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
    65128     * Tests wp_prime_option_caches() with options that do not exist in the database.
    66129     *
    67130     * @ticket 58962
     131
    68132     */
    69133    public function test_wp_prime_option_caches_with_nonexistent_options() {
     
    97161            $this->assertArrayHasKey( $option, $new_notoptions, "$option was not added to the notoptions cache." );
    98162        }
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
    99181    }
    100182
     
    103185     *
    104186     * @ticket 58962
     187
    105188     */
    106189    public function test_wp_prime_option_caches_with_empty_array() {
     
    108191        $notoptions = wp_cache_get( 'notoptions', 'options' );
    109192
     193
    110194        wp_prime_option_caches( array() );
    111195
    112196        $this->assertSame( $alloptions, wp_cache_get( 'alloptions', 'options' ), 'The alloptions cache was modified.' );
    113197        $this->assertSame( $notoptions, wp_cache_get( 'notoptions', 'options' ), 'The notoptions cache was modified.' );
     198
     199
     200
     201
     202
     203
     204
    114205    }
    115206
     
    118209     *
    119210     * @ticket 58962
     211
    120212     */
    121213    public function test_wp_prime_option_caches_handles_empty_notoptions_cache() {
     
    127219        $this->assertIsArray( $notoptions, 'The notoptions cache should be an array.' );
    128220        $this->assertArrayHasKey( 'nonexistent_option', $notoptions, 'nonexistent_option was not added to notoptions.' );
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
    129460    }
    130461}
  • trunk/tests/phpunit/tests/option/wpPrimeOptionCachesByGroup.php

    r57013 r57029  
    4848        wp_prime_option_caches_by_group( 'group1' );
    4949
    50         // Check that options are now in the cache.
    51         $this->assertSame( get_option( 'option1' ), wp_cache_get( 'option1', 'options' ), 'option1\'s cache was not primed.' );
    52         $this->assertSame( get_option( 'option2' ), wp_cache_get( 'option2', 'options' ), 'option2\'s cache was not primed.' );
     50        /*
     51         * Check that options are now in the cache.
     52         *
     53         * Repeat the string here rather than using get_option as get_option
     54         * will prime the cache before the call to wp_cache_get if the option
     55         * is not in the cache. Thus causing the tests to pass when they should
     56         * fail.
     57         */
     58        $this->assertSame( 'value_option1', wp_cache_get( 'option1', 'options' ), 'option1\'s cache was not primed.' );
     59        $this->assertSame( 'value_option2', wp_cache_get( 'option2', 'options' ), 'option2\'s cache was not primed.' );
    5360
    5461        // Make sure option3 is still not in cache.
Note: See TracChangeset for help on using the changeset viewer.