Make WordPress Core

Changeset 54080

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

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-network-query.php

    r53376 r54080  
    9090     *     Optional. Array or query string of network query parameters. Default empty.
    9191     *
    92      *     @type int[]        $network__in          Array of network IDs to include. Default empty.
    93      *     @type int[]        $network__not_in      Array of network IDs to exclude. Default empty.
    94      *     @type bool         $count                Whether to return a network count (true) or array of network objects.
    95      *                                              Default false.
    96      *     @type string       $fields               Network fields to return. Accepts 'ids' (returns an array of network IDs)
    97      *                                              or empty (returns an array of complete network objects). Default empty.
    98      *     @type int          $number               Maximum number of networks to retrieve. Default empty (no limit).
    99      *     @type int          $offset               Number of networks to offset the query. Used to build LIMIT clause.
    100      *                                              Default 0.
    101      *     @type bool         $no_found_rows        Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
    102      *     @type string|array $orderby              Network status or array of statuses. Accepts 'id', 'domain', 'path',
    103      *                                              'domain_length', 'path_length' and 'network__in'. Also accepts false,
    104      *                                              an empty array, or 'none' to disable `ORDER BY` clause. Default 'id'.
    105      *     @type string       $order                How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'.
    106      *     @type string       $domain               Limit results to those affiliated with a given domain. Default empty.
    107      *     @type string[]     $domain__in           Array of domains to include affiliated networks for. Default empty.
    108      *     @type string[]     $domain__not_in       Array of domains to exclude affiliated networks for. Default empty.
    109      *     @type string       $path                 Limit results to those affiliated with a given path. Default empty.
    110      *     @type string[]     $path__in             Array of paths to include affiliated networks for. Default empty.
    111      *     @type string[]     $path__not_in         Array of paths to exclude affiliated networks for. Default empty.
    112      *     @type string       $search               Search term(s) to retrieve matching networks for. Default empty.
    113      *     @type bool         $update_network_cache Whether to prime the cache for found networks. Default true.
     92     *     @type int[]        $network__in                Array of network IDs to include. Default empty.
     93     *     @type int[]        $network__not_in            Array of network IDs to exclude. Default empty.
     94     *     @type bool         $count                      Whether to return a network count (true) or array of network objects.
     95     *                                                    Default false.
     96     *     @type string       $fields                     Network fields to return. Accepts 'ids' (returns an array of network IDs)
     97     *                                                    or empty (returns an array of complete network objects). Default empty.
     98     *     @type int          $number                     Maximum number of networks to retrieve. Default empty (no limit).
     99     *     @type int          $offset                     Number of networks to offset the query. Used to build LIMIT clause.
     100     *                                                    Default 0.
     101     *     @type bool         $no_found_rows              Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
     102     *     @type string|array $orderby                    Network status or array of statuses. Accepts 'id', 'domain', 'path',
     103     *                                                    'domain_length', 'path_length' and 'network__in'. Also accepts false,
     104     *                                                    an empty array, or 'none' to disable `ORDER BY` clause. Default 'id'.
     105     *     @type string       $order                      How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'.
     106     *     @type string       $domain                     Limit results to those affiliated with a given domain. Default empty.
     107     *     @type string[]     $domain__in                 Array of domains to include affiliated networks for. Default empty.
     108     *     @type string[]     $domain__not_in             Array of domains to exclude affiliated networks for. Default empty.
     109     *     @type string       $path                       Limit results to those affiliated with a given path. Default empty.
     110     *     @type string[]     $path__in                   Array of paths to include affiliated networks for. Default empty.
     111     *     @type string[]     $path__not_in               Array of paths to exclude affiliated networks for. Default empty.
     112     *     @type string       $search                     Search term(s) to retrieve matching networks for. Default empty.
     113     *     @type bool         $update_network_cache       Whether to prime the cache for found networks. Default true.
     114     *     @type bool         $update_network_meta_cache  Whether to prime the metadata (option) cache for found networks.
     115     *                                                    Default true.
    114116     * }
    115117     */
    116118    public function __construct( $query = '' ) {
    117119        $this->query_var_defaults = array(
    118             'network__in'          => '',
    119             'network__not_in'      => '',
    120             'count'                => false,
    121             'fields'               => '',
    122             'number'               => '',
    123             'offset'               => '',
    124             'no_found_rows'        => true,
    125             'orderby'              => 'id',
    126             'order'                => 'ASC',
    127             'domain'               => '',
    128             'domain__in'           => '',
    129             'domain__not_in'       => '',
    130             'path'                 => '',
    131             'path__in'             => '',
    132             'path__not_in'         => '',
    133             'search'               => '',
    134             'update_network_cache' => true,
     120            'network__in'               => '',
     121            'network__not_in'           => '',
     122            'count'                     => false,
     123            'fields'                    => '',
     124            'number'                    => '',
     125            'offset'                    => '',
     126            'no_found_rows'             => true,
     127            'orderby'                   => 'id',
     128            'order'                     => 'ASC',
     129            'domain'                    => '',
     130            'domain__in'                => '',
     131            'domain__not_in'            => '',
     132            'path'                      => '',
     133            'path__in'                  => '',
     134            'path__not_in'              => '',
     135            'search'                    => '',
     136            'update_network_cache'      => true,
     137            'update_network_meta_cache' => true,
    135138        );
    136139
     
    243246        $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) );
    244247
    245         // Ignore the $fields, $update_network_cache arguments as the queried result will be the same regardless.
    246         unset( $_args['fields'], $_args['update_network_cache'] );
     248        // Ignore the $fields, $update_network_cache arguments as the queried result will be the same regardless.
     249        unset( $_args['fields'], $_args['update_network_cache'] );
    247250
    248251        $key          = md5( serialize( $_args ) );
     
    286289
    287290        if ( $this->query_vars['update_network_cache'] ) {
    288             _prime_network_caches( $network_ids );
     291            _prime_network_caches( $network_ids );
    289292        }
    290293
  • trunk/src/wp-includes/load.php

    r53915 r54080  
    744744                'site-options',
    745745                'site-transient',
     746
    746747                'rss',
    747748                'users',
  • trunk/src/wp-includes/ms-blogs.php

    r53878 r54080  
    565565                        'site-options',
    566566                        'site-transient',
     567
    567568                        'rss',
    568569                        'users',
     
    656657                        'site-options',
    657658                        'site-transient',
     659
    658660                        'rss',
    659661                        'users',
  • trunk/src/wp-includes/ms-functions.php

    r53251 r54080  
    114114 */
    115115function get_blog_count( $network_id = null ) {
    116     return get_network_option( $network_id, 'blog_count' );
     116    return get_network_option( $network_id, 'blog_count' );
    117117}
    118118
     
    26552655     * @param int $space_allowed Upload quota in megabytes for the current blog.
    26562656     */
    2657     return apply_filters( 'get_space_allowed', $space_allowed );
     2657    return apply_filters( 'get_space_allowed', $space_allowed );
    26582658}
    26592659
  • trunk/src/wp-includes/ms-network.php

    r53944 r54080  
    8585    $network_ids = (array) $ids;
    8686    wp_cache_delete_multiple( $network_ids, 'networks' );
     87
    8788
    8889    foreach ( $network_ids as $id ) {
     
    108109 *
    109110 * @since 4.6.0
     111
    110112 *
    111  * @param array $networks Array of network row objects.
     113 * @param array $networks          Array of network row objects.
     114 * @param bool  $update_meta_cache Whether to update site meta cache. Default true.
    112115 */
    113 function update_network_cache( $networks ) {
     116function update_network_cache( $networks ) {
    114117    $data = array();
    115118    foreach ( (array) $networks as $network ) {
    116119        $data[ $network->id ] = $network;
    117120    }
     121
    118122    wp_cache_add_multiple( $data, 'networks' );
     123
     124
     125
     126
    119127}
    120128
     
    123131 *
    124132 * @since 4.6.0
     133
    125134 * @since 6.1.0 This function is no longer marked as "private".
    126135 *
     
    128137 * @global wpdb $wpdb WordPress database abstraction object.
    129138 *
    130  * @param array $network_ids Array of network IDs.
     139 * @param array $network_ids       Array of network IDs.
     140 * @param bool  $update_meta_cache Whether to update site meta cache. Default true.
    131141 */
    132 function _prime_network_caches( $network_ids ) {
     142function _prime_network_caches( $network_ids ) {
    133143    global $wpdb;
    134144
     
    137147        $fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    138148
    139         update_network_cache( $fresh_networks );
     149        update_network_cache( $fresh_networks );
    140150    }
    141151}
  • 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
    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
    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
    16241540 *
    16251541 * @see delete_option()
     1542
    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
    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
  • trunk/tests/phpunit/tests/ajax/Compression.php

    r53561 r54080  
    155155
    156156        // Check the site option is not changed due to lack of nonce.
    157         $this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
     157        $this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
    158158
    159159        // Add a nonce.
     
    168168
    169169        // Check the site option is changed.
    170         $this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
     170        $this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
    171171    }
    172172
     
    195195
    196196        // Check the site option is not changed due to lack of nonce.
    197         $this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
     197        $this->assertSame( 1, get_site_option( 'can_compress_scripts' ) );
    198198
    199199        // Add a nonce.
     
    208208
    209209        // Check the site option is changed.
    210         $this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
     210        $this->assertSame( 0, get_site_option( 'can_compress_scripts' ) );
    211211    }
    212212
  • trunk/tests/phpunit/tests/option/multisite.php

    r53865 r54080  
    151151            $this->assertFalse( get_blog_option( $blog_id, $key2 ) );
    152152            // $this->assertFalse( get_option( $key2 ) );                        // Check get_option().
    153         }
    154 
    155         /**
    156          * @group multisite
    157          *
    158          * @covers ::get_site_option
    159          */
    160         public function test_site_notoptions() {
    161             $network_id     = get_current_network_id();
    162             $notoptions_key = "{$network_id}:notoptions";
    163 
    164             $_notoptions = wp_cache_get( 'notoptions', 'site-options' );
    165             $this->assertEmpty( $_notoptions );
    166             $_notoptions1 = wp_cache_get( $notoptions_key, 'site-options' );
    167             $this->assertEmpty( $_notoptions1 );
    168 
    169             get_site_option( 'burrito' );
    170 
    171             $notoptions = wp_cache_get( 'notoptions', 'site-options' );
    172             $this->assertEmpty( $notoptions );
    173             $notoptions1 = wp_cache_get( $notoptions_key, 'site-options' );
    174             $this->assertNotEmpty( $notoptions1 );
    175153        }
    176154
  • trunk/tests/phpunit/tests/option/networkOption.php

    r53865 r54080  
    138138
    139139    /**
    140      * @ticket 43506
     140     * @ticket 37181
     141     *
    141142     * @group ms-required
    142143     *
     
    145146     * @covers ::wp_cache_delete
    146147     */
    147     public function test_get_network_option_sets_notoptions_if_option_found() {
    148         $network_id     = get_current_network_id();
    149         $notoptions_key = "$network_id:notoptions";
    150 
    151         $original_cache = wp_cache_get( $notoptions_key, 'site-options' );
    152         if ( false !== $original_cache ) {
    153             wp_cache_delete( $notoptions_key, 'site-options' );
    154         }
    155 
    156         // Retrieve any existing option.
    157         get_network_option( $network_id, 'site_name' );
    158 
    159         $cache = wp_cache_get( $notoptions_key, 'site-options' );
    160         if ( false !== $original_cache ) {
    161             wp_cache_set( $notoptions_key, $original_cache, 'site-options' );
    162         }
    163 
    164         $this->assertSame( array(), $cache );
    165     }
    166 
    167     /**
    168      * @ticket 43506
     148    public function test_meta_api_use_values_in_network_option() {
     149        $network_id = self::factory()->network->create();
     150        $option     = __FUNCTION__;
     151        $value      = __FUNCTION__;
     152
     153        add_metadata( 'site', $network_id, $option, $value, true );
     154        $this->assertEqualSets( get_metadata( 'site', $network_id, $option ), array( get_network_option( $network_id, $option, true ) ) );
     155    }
     156
     157    /**
     158     * @ticket 37181
     159     *
     160     * @group ms-required
     161     */
     162    function test_funky_network_meta() {
     163        $network_id      = self::factory()->network->create();
     164        $option          = __FUNCTION__;
     165        $classy          = new StdClass();
     166        $classy->ID      = 1;
     167        $classy->stringy = 'I love slashes\\\\';
     168        $funky_meta[]    = $classy;
     169
     170        $classy          = new StdClass();
     171        $classy->ID      = 2;
     172        $classy->stringy = 'I love slashes\\\\ more';
     173        $funky_meta[]    = $classy;
     174
     175        // Add a network meta item.
     176        $this->assertIsInt( add_metadata( 'site', $network_id, $option, $funky_meta, true ) );
     177
     178        // Check they exists.
     179        $this->assertEquals( $funky_meta, get_network_option( $network_id, $option ) );
     180    }
     181
     182    /**
     183     * @ticket 37181
     184     *
     185     * @group ms-required
     186     */
     187    public function test_meta_api_multiple_values_in_network_option() {
     188        $network_id = self::factory()->network->create();
     189        $option     = __FUNCTION__;
     190        add_metadata( 'site', $network_id, $option, 'monday', true );
     191        add_metadata( 'site', $network_id, $option, 'tuesday', true );
     192        add_metadata( 'site', $network_id, $option, 'wednesday', true );
     193        $this->assertEquals( 'monday', get_network_option( $network_id, $option, true ) );
     194    }
     195
     196    /**
     197     * @ticket 37181
     198     *
    169199     * @group ms-required
    170200     *
     
    172202     * @covers ::wp_cache_get
    173203     */
    174     public function test_get_network_option_sets_notoptions_if_option_not_found() {
    175         $network_id     = get_current_network_id();
    176         $notoptions_key = "$network_id:notoptions";
    177 
    178         $original_cache = wp_cache_get( $notoptions_key, 'site-options' );
    179         if ( false !== $original_cache ) {
    180             wp_cache_delete( $notoptions_key, 'site-options' );
    181         }
    182 
    183         // Retrieve any non-existing option.
    184         get_network_option( $network_id, 'this_does_not_exist' );
    185 
    186         $cache = wp_cache_get( $notoptions_key, 'site-options' );
    187         if ( false !== $original_cache ) {
    188             wp_cache_set( $notoptions_key, $original_cache, 'site-options' );
    189         }
    190 
    191         $this->assertSame( array( 'this_does_not_exist' => true ), $cache );
     204    public function test_network_option_count_queries_on_non_existing() {
     205        $network_id = self::factory()->network->create();
     206        $option     = __FUNCTION__;
     207        add_network_option( $network_id, $option, 'monday' );
     208        get_network_option( $network_id, $option );
     209        $num_queries_pre_get = get_num_queries();
     210        get_network_option( $network_id, 'do_not_exist' );
     211        $num_queries_after_get = get_num_queries();
     212
     213        $this->assertSame( $num_queries_pre_get, $num_queries_after_get );
     214    }
     215
     216    /**
     217     * @ticket 37181
     218     *
     219     * @group ms-required
     220     */
     221    public function test_register_meta_network_option_single_false() {
     222        $network_id = self::factory()->network->create();
     223        $option     = __FUNCTION__;
     224        $value      = __FUNCTION__;
     225        register_meta(
     226            'site',
     227            $option,
     228            array(
     229                'type'    => 'string',
     230                'default' => $value,
     231                'single'  => false,
     232            )
     233        );
     234
     235        $this->assertSame( $value, get_network_option( $network_id, $option ) );
     236    }
     237
     238    /**
     239     * @ticket 37181
     240     *
     241     * @group ms-required
     242     */
     243    public function test_register_meta_network_option_single_true() {
     244        $network_id = self::factory()->network->create();
     245        $option     = __FUNCTION__;
     246        $value      = __FUNCTION__;
     247        register_meta(
     248            'site',
     249            $option,
     250            array(
     251                'type'    => 'string',
     252                'default' => $value,
     253                'single'  => true,
     254            )
     255        );
     256
     257        $this->assertSame( $value, get_network_option( $network_id, $option ) );
    192258    }
    193259
     
    197263     * @ticket 44956
    198264     *
     265
     266
    199267     * @covers ::update_network_option
    200268     */
    201269    public function test_update_network_option_array_with_object() {
     270
     271
    202272        $array_w_object = array(
    203273            'url'       => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
     
    209279        );
    210280
    211         $array_w_object_2 = array(
    212             'url'       => 'http://src.wordpress-develop.dev/wp-content/uploads/2016/10/cropped-Blurry-Lights.jpg',
    213             'meta_data' => (object) array(
    214                 'attachment_id' => 292,
    215                 'height'        => 708,
    216                 'width'         => 1260,
    217             ),
    218         );
    219 
    220         // Add the option, it did not exist before this.
    221         add_network_option( null, 'array_w_object', $array_w_object );
    222 
    223         $num_queries_pre_update = get_num_queries();
    224 
    225         // Update the option using the same array with an object for the value.
    226         $this->assertFalse( update_network_option( null, 'array_w_object', $array_w_object_2 ) );
    227 
    228         // Check that no new database queries were performed.
    229         $this->assertSame( $num_queries_pre_update, get_num_queries() );
     281        add_metadata( 'site', $network_id, $option, $array_w_object, true );
     282        $this->assertEquals( $array_w_object, get_network_option( $network_id, $option ) );
     283    }
     284
     285    /**
     286     * @ticket 37181
     287     *
     288     * @group ms-required
     289     *
     290     * @covers ::add_network_option
     291     *
     292     * @dataProvider data_types_options
     293     */
     294    public function test_type_add_network_option( $name, $value, $expected ) {
     295        $result = add_network_option( null, $name, $value );
     296        $this->assertTrue( $result, 'Network option was not added' );
     297
     298        $test_value = get_network_option( null, $name );
     299        $this->assertSame( $expected, $test_value, 'Values do not match' );
     300    }
     301
     302    /**
     303     * @ticket 37181
     304     *
     305     * @covers ::add_network_option
     306     *
     307     * @dataProvider data_slashed_options
     308     */
     309    public function test_slash_add_network_option( $name, $value ) {
     310        $result = add_network_option( null, $name, $value );
     311        $this->assertTrue( $result, 'Network option was not added' );
     312        $this->assertSame( $value, get_network_option( null, $name ), 'Values do not match' );
     313    }
     314
     315    /**
     316     * @ticket 37181
     317     *
     318     * @covers ::update_network_option
     319     *
     320     * @dataProvider data_slashed_options
     321     */
     322    public function test_slash_update_network_option( $name, $value ) {
     323        $result = update_network_option( null, $name, $value );
     324        $this->assertTrue( $result, 'Network option was not updated' );
     325        $this->assertSame( $value, get_network_option( null, $name ), 'Values do not match' );
     326    }
     327
     328    /**
     329     * @ticket 37181
     330     *
     331     * @covers ::delete_network_option()
     332     *
     333     * @dataProvider data_slashed_options
     334     */
     335    public function test_slash_delete_network_option( $name, $value ) {
     336        $result = add_network_option( null, $name, $value );
     337        $this->assertTrue( $result, 'Network option was not added' );
     338        $this->assertSame( $value, get_network_option( null, $name ) );
     339        $result = delete_network_option( null, $name );
     340        $this->assertTrue( $result, 'Network option was not deleted' );
     341        $this->assertFalse( get_network_option( null, $name ), 'Network option was not deleted' );
     342    }
     343
     344    public function data_slashed_options() {
     345        return array(
     346            'slashed option name'                   => array(
     347                'option' => 'String with 1 slash \\',
     348                'value'  => 'foo',
     349            ),
     350            'slashed in middle option name'         => array(
     351                'option' => 'String\\thing',
     352                'value'  => 'foo',
     353            ),
     354            'slashed option value'                  => array(
     355                'option' => 'bar',
     356                'value'  => 'String with 1 slash \\',
     357            ),
     358            'slashed option name and value'         => array(
     359                'option' => 'String with 1 slash \\',
     360                'value'  => 'String with 1 slash \\',
     361            ),
     362            'slashed 4 times option name and value' => array(
     363                'option' => 'String with 4 slashes \\\\\\\\',
     364                'value'  => 'String with 4 slashes \\\\\\\\',
     365            ),
     366            'slashed 7 times option name and value' => array(
     367                'option' => 'String with 7 slashes \\\\\\\\\\\\\\',
     368                'value'  => 'String with 7 slashes \\\\\\\\\\\\\\',
     369            ),
     370        );
     371    }
     372
     373    public function data_types_options() {
     374        return array(
     375            'array'       => array(
     376                'option'   => 'array',
     377                'value'    => array(),
     378                'expected' => array(),
     379            ),
     380            'array_keys'  => array(
     381                'option'   => 'array',
     382                'value'    => array( 'key' => 'value' ),
     383                'expected' => array( 'key' => 'value' ),
     384            ),
     385            'int'         => array(
     386                'option'   => 'int',
     387                'value'    => 33,
     388                'expected' => '33',
     389            ),
     390            'string'      => array(
     391                'option'   => 'string',
     392                'value'    => 'foo',
     393                'expected' => 'foo',
     394            ),
     395            'string_bool' => array(
     396                'option'   => 'string',
     397                'value'    => 'true',
     398                'expected' => 'true',
     399            ),
     400            'float'       => array(
     401                'option'   => 'float',
     402                'value'    => 33.5555,
     403                'expected' => '33.5555',
     404            ),
     405            'bool'        => array(
     406                'option'   => 'bool',
     407                'value'    => true,
     408                'expected' => '1',
     409            ),
     410            'null'        => array(
     411                'option'   => 'null',
     412                'value'    => null,
     413                'expected' => null,
     414            ),
     415        );
    230416    }
    231417}
Note: See TracChangeset for help on using the changeset viewer.