Make WordPress Core


Ignore:
Timestamp:
09/06/2022 11:26:45 AM (2 years ago)
Author:
spacedmonkey
Message:

Networks and Sites: Use metadata api in *_network_options` functions.

Replace logic found in get_network_option, update_network_option and delete_network_option to use the metadata api. Using the metadata api has a number of benefits, such as consistency, default values and useful filters. This change also improves performance by priming the caches of all network options in a single database request.

Props spacedmonkey, swissspidy, sc0ttkclark, johnjamesjacoby, flixos90, jeremyfelt, pento, peterwilsoncc, mukesh27, desrosj.
Fixes #37181

File:
1 edited

Legend:

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

    r53914 r54080  
    325325 *
    326326 * @since 3.0.0
    327  *
    328  * @global wpdb $wpdb WordPress database abstraction object.
     327 * @since 6.1.0 Uses update_meta_cache
    329328 *
    330329 * @param int $network_id Optional site ID for which to query the options. Defaults to the current site.
    331330 */
    332331function wp_load_core_site_options( $network_id = null ) {
    333     global $wpdb;
    334 
    335     if ( ! is_multisite() || wp_using_ext_object_cache() || wp_installing() ) {
     332    if ( ! is_multisite() || wp_installing() ) {
    336333        return;
    337334    }
     
    341338    }
    342339
    343     $core_options = array( 'site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled', 'ms_files_rewriting' );
    344 
    345     $core_options_in = "'" . implode( "', '", $core_options ) . "'";
    346     $options         = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d", $network_id ) );
    347 
    348     $data = array();
    349     foreach ( $options as $option ) {
    350         $key                = $option->meta_key;
    351         $cache_key          = "{$network_id}:$key";
    352         $option->meta_value = maybe_unserialize( $option->meta_value );
    353 
    354         $data[ $cache_key ] = $option->meta_value;
    355     }
    356     wp_cache_set_multiple( $data, 'site-options' );
     340    update_meta_cache( 'site', $network_id );
    357341}
    358342
     
    13631347 *
    13641348 * @since 4.4.0
     1349 * @since 6.1.0 Now uses get_metadata().
    13651350 *
    13661351 * @see get_option()
    1367  *
    1368  * @global wpdb $wpdb WordPress database abstraction object.
     1352 * @see get_metadata()
    13691353 *
    13701354 * @param int    $network_id ID of the network. Can be null to default to the current network ID.
     
    13741358 */
    13751359function get_network_option( $network_id, $option, $default = false ) {
    1376     global $wpdb;
    1377 
    13781360    if ( $network_id && ! is_numeric( $network_id ) ) {
    13791361        return false;
     
    14161398    }
    14171399
    1418     // Prevent non-existent options from triggering multiple queries.
    1419     $notoptions_key = "$network_id:notoptions";
    1420     $notoptions     = wp_cache_get( $notoptions_key, 'site-options' );
    1421 
    1422     if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
    1423 
     1400    if ( ! is_multisite() ) {
    14241401        /**
    14251402         * Filters the value of a specific default network option.
     
    14361413         * @param int    $network_id ID of the network.
    14371414         */
    1438         return apply_filters( "default_site_option_{$option}", $default, $option, $network_id );
    1439     }
    1440 
    1441     if ( ! is_multisite() ) {
    1442         /** This filter is documented in wp-includes/option.php */
    1443         $default = apply_filters( 'default_site_option_' . $option, $default, $option, $network_id );
     1415        $default = apply_filters( "default_site_option_{$option}", $default, $option, $network_id );
    14441416        $value   = get_option( $option, $default );
    14451417    } else {
    1446         $cache_key = "$network_id:$option";
    1447         $value     = wp_cache_get( $cache_key, 'site-options' );
    1448 
    1449         if ( ! isset( $value ) || false === $value ) {
    1450             $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
    1451 
    1452             // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values.
    1453             if ( is_object( $row ) ) {
    1454                 $value = $row->meta_value;
    1455                 $value = maybe_unserialize( $value );
    1456                 wp_cache_set( $cache_key, $value, 'site-options' );
    1457             } else {
    1458                 if ( ! is_array( $notoptions ) ) {
    1459                     $notoptions = array();
    1460                 }
    1461 
    1462                 $notoptions[ $option ] = true;
    1463                 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
    1464 
    1465                 /** This filter is documented in wp-includes/option.php */
    1466                 $value = apply_filters( 'default_site_option_' . $option, $default, $option, $network_id );
    1467             }
    1468         }
    1469     }
    1470 
    1471     if ( ! is_array( $notoptions ) ) {
    1472         $notoptions = array();
    1473         wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
     1418        $meta = get_metadata_raw( 'site', $network_id, $option );
     1419        if ( is_array( $meta ) && ! empty( $meta ) ) {
     1420            $value = array_shift( $meta );
     1421        } else {
     1422            /** This filter is documented in wp-includes/option.php */
     1423            $value = apply_filters( "default_site_option_{$option}", $default, $option, $network_id );
     1424
     1425            /** This action is documented in wp-includes/meta.php */
     1426            $value = apply_filters( 'default_site_metadata', $value, $network_id, $option, true, 'site' );
     1427        }
    14741428    }
    14751429
     
    14971451 *
    14981452 * @since 4.4.0
     1453 * @since 6.1.0 Now uses add_metadata().
    14991454 *
    15001455 * @see add_option()
    1501  *
    1502  * @global wpdb $wpdb WordPress database abstraction object.
     1456 * @see add_metadata()
    15031457 *
    15041458 * @param int    $network_id ID of the network. Can be null to default to the current network ID.
     
    15081462 */
    15091463function add_network_option( $network_id, $option, $value ) {
    1510     global $wpdb;
    1511 
    15121464    if ( $network_id && ! is_numeric( $network_id ) ) {
    15131465        return false;
     
    15391491    $value = apply_filters( "pre_add_site_option_{$option}", $value, $option, $network_id );
    15401492
    1541     $notoptions_key = "$network_id:notoptions";
    1542 
    15431493    if ( ! is_multisite() ) {
    15441494        $result = add_option( $option, $value, '', 'no' );
    15451495    } else {
    1546         $cache_key = "$network_id:$option";
    1547 
    1548         // Make sure the option doesn't already exist.
    1549         // We can check the 'notoptions' cache before we ask for a DB query.
    1550         $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
    1551 
    1552         if ( ! is_array( $notoptions ) || ! isset( $notoptions[ $option ] ) ) {
    1553             if ( false !== get_network_option( $network_id, $option, false ) ) {
    1554                 return false;
    1555             }
    1556         }
    1557 
    1558         $value = sanitize_option( $option, $value );
    1559 
    1560         $serialized_value = maybe_serialize( $value );
    1561         $result           = $wpdb->insert(
    1562             $wpdb->sitemeta,
    1563             array(
    1564                 'site_id'    => $network_id,
    1565                 'meta_key'   => $option,
    1566                 'meta_value' => $serialized_value,
    1567             )
    1568         );
    1569 
    1570         if ( ! $result ) {
    1571             return false;
    1572         }
    1573 
    1574         wp_cache_set( $cache_key, $value, 'site-options' );
    1575 
    1576         // This option exists now.
    1577         $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); // Yes, again... we need it to be fresh.
    1578 
    1579         if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
    1580             unset( $notoptions[ $option ] );
    1581             wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
    1582         }
     1496        $value  = sanitize_option( $option, $value );
     1497        $result = add_metadata( 'site', $network_id, wp_slash( $option ), wp_slash( $value ), true );
    15831498    }
    15841499
     
    16221537 *
    16231538 * @since 4.4.0
     1539 * @since 6.1.0 Now uses delete_metadata().
    16241540 *
    16251541 * @see delete_option()
     1542 * @see delete_metadata()
    16261543 *
    16271544 * @global wpdb $wpdb WordPress database abstraction object.
     
    16321549 */
    16331550function delete_network_option( $network_id, $option ) {
    1634     global $wpdb;
    1635 
    16361551    if ( $network_id && ! is_numeric( $network_id ) ) {
    16371552        return false;
     
    16621577        $result = delete_option( $option );
    16631578    } else {
    1664         $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->sitemeta} WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
    1665         if ( is_null( $row ) || ! $row->meta_id ) {
    1666             return false;
    1667         }
    1668         $cache_key = "$network_id:$option";
    1669         wp_cache_delete( $cache_key, 'site-options' );
    1670 
    1671         $result = $wpdb->delete(
    1672             $wpdb->sitemeta,
    1673             array(
    1674                 'meta_key' => $option,
    1675                 'site_id'  => $network_id,
    1676             )
    1677         );
     1579        $result = delete_metadata( 'site', $network_id, wp_slash( $option ), '' );
    16781580    }
    16791581
     
    17151617 *
    17161618 * @since 4.4.0
     1619 * @since 6.1.0 Now uses update_metadata().
    17171620 *
    17181621 * @see update_option()
    1719  *
    1720  * @global wpdb $wpdb WordPress database abstraction object.
     1622 * @see update_metadata()
    17211623 *
    17221624 * @param int    $network_id ID of the network. Can be null to default to the current network ID.
     
    17261628 */
    17271629function update_network_option( $network_id, $option, $value ) {
    1728     global $wpdb;
    1729 
    17301630    if ( $network_id && ! is_numeric( $network_id ) ) {
    17311631        return false;
     
    17771677    }
    17781678
    1779     $notoptions_key = "$network_id:notoptions";
    1780     $notoptions     = wp_cache_get( $notoptions_key, 'site-options' );
    1781 
    1782     if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
    1783         unset( $notoptions[ $option ] );
    1784         wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
    1785     }
    1786 
    17871679    if ( ! is_multisite() ) {
    17881680        $result = update_option( $option, $value, 'no' );
    17891681    } else {
    1790         $value = sanitize_option( $option, $value );
    1791 
    1792         $serialized_value = maybe_serialize( $value );
    1793         $result           = $wpdb->update(
    1794             $wpdb->sitemeta,
    1795             array( 'meta_value' => $serialized_value ),
    1796             array(
    1797                 'site_id'  => $network_id,
    1798                 'meta_key' => $option,
    1799             )
    1800         );
    1801 
    1802         if ( $result ) {
    1803             $cache_key = "$network_id:$option";
    1804             wp_cache_set( $cache_key, $value, 'site-options' );
    1805         }
     1682        $value  = sanitize_option( $option, $value );
     1683        $result = update_metadata( 'site', $network_id, wp_slash( $option ), wp_slash( $value ) );
    18061684    }
    18071685
Note: See TracChangeset for help on using the changeset viewer.