Make WordPress Core

Ticket #37923: 37923.11.diff

File 37923.11.diff, 42.2 KB (added by spacedmonkey, 7 years ago)
  • src/wp-admin/includes/ms.php

     
    127127                        $wpdb->query( "DROP TABLE IF EXISTS `$table`" );
    128128                }
    129129
     130                if ( is_site_meta_supported() ) {
     131                        $blog_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->blogmeta WHERE blog_id = %d ", $blog_id ) );
     132                        foreach ( $blog_meta_ids as $mid ) {
     133                                delete_metadata_by_mid( 'blog', $mid );
     134                        }
     135                }
     136
    130137                $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
    131138
    132139                /**
  • src/wp-admin/includes/schema.php

     
    265265  PRIMARY KEY  (blog_id),
    266266  KEY db_version (db_version)
    267267) $charset_collate;
     268CREATE TABLE $wpdb->blogmeta (
     269  meta_id bigint(20) NOT NULL auto_increment,
     270  blog_id bigint(20) NOT NULL default '0',
     271  meta_key varchar(255) default NULL,
     272  meta_value longtext,
     273  PRIMARY KEY  (meta_id),
     274  KEY meta_key (meta_key($max_index_length)),
     275  KEY blog_id (blog_id)
     276) $charset_collate;
    268277CREATE TABLE $wpdb->registration_log (
    269278  ID bigint(20) NOT NULL auto_increment,
    270279  email varchar(255) NOT NULL default '',
  • src/wp-admin/includes/upgrade.php

     
    18811881                        }
    18821882                }
    18831883        }
     1884
     1885        // 4.9
     1886        if ( $wp_current_db_version < 40001 ) {
     1887                $network_id = get_main_network_id();
     1888                delete_network_option( $network_id, 'site_meta_supported' );
     1889                is_site_meta_supported();
     1890        }
    18841891}
    18851892
    18861893//
  • src/wp-includes/class-wp-site-query.php

     
    9292         *
    9393         * @since 4.6.0
    9494         * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
     95         * @since 4.9.0 Introduced the 'update_site_meta_cache' parameter.
    9596         *
    9697         * @param string|array $query {
    9798         *     Optional. Array or query string of site query parameters. Default empty.
    9899         *
    99          *     @type array        $site__in          Array of site IDs to include. Default empty.
    100          *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
    101          *     @type bool         $count             Whether to return a site count (true) or array of site objects.
    102          *                                           Default false.
    103          *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
    104          *                                           Default null.
    105          *     @type string       $fields            Site fields to return. Accepts 'ids' (returns an array of site IDs)
    106          *                                           or empty (returns an array of complete site objects). Default empty.
    107          *     @type int          $ID                A site ID to only return that site. Default empty.
    108          *     @type int          $number            Maximum number of sites to retrieve. Default 100.
    109          *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
    110          *                                           Default 0.
    111          *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
    112          *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
    113          *                                           'network_id', 'last_updated', 'registered', 'domain_length',
    114          *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
    115          *                                           an empty array, or 'none' to disable `ORDER BY` clause.
    116          *                                           Default 'id'.
    117          *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
    118          *     @type int          $network_id        Limit results to those affiliated with a given network ID. If 0,
    119          *                                           include all networks. Default 0.
    120          *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
    121          *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
    122          *     @type string       $domain            Limit results to those affiliated with a given domain. Default empty.
    123          *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
    124          *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
    125          *     @type string       $path              Limit results to those affiliated with a given path. Default empty.
    126          *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
    127          *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
    128          *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
    129          *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
    130          *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
    131          *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
    132          *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
    133          *     @type int          $lang_id           Limit results to a language ID. Default empty.
    134          *     @type array        $lang__in          Array of language IDs to include affiliated sites for. Default empty.
    135          *     @type array        $lang__not_in      Array of language IDs to exclude affiliated sites for. Default empty.
    136          *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
    137          *     @type array        $search_columns    Array of column names to be searched. Accepts 'domain' and 'path'.
    138          *                                           Default empty array.
    139          *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default false.
     100         *     @type array        $site__in               Array of site IDs to include. Default empty.
     101         *     @type array        $site__not_in           Array of site IDs to exclude. Default empty.
     102         *     @type bool         $count                  Whether to return a site count (true) or array of site objects.
     103         *                                                Default false.
     104         *     @type array        $date_query             Date query clauses to limit sites by. See WP_Date_Query.
     105         *                                                Default null.
     106         *     @type string       $fields                 Site fields to return. Accepts 'ids' (returns an array of site IDs)
     107         *                                                or empty (returns an array of complete site objects). Default empty.
     108         *     @type int          $ID                     A site ID to only return that site. Default empty.
     109         *     @type int          $number                 Maximum number of sites to retrieve. Default 100.
     110         *     @type int          $offset                 Number of sites to offset the query. Used to build LIMIT clause.
     111         *                                                Default 0.
     112         *     @type bool         $no_found_rows          Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
     113         *     @type string|array $orderby                Site status or array of statuses. Accepts 'id', 'domain', 'path',
     114         *                                                'network_id', 'last_updated', 'registered', 'domain_length',
     115         *                                                'path_length', 'site__in' and 'network__in'. Also accepts false,
     116         *                                                an empty array, or 'none' to disable `ORDER BY` clause.
     117         *                                                Default 'id'.
     118         *     @type string       $order                  How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
     119         *     @type int          $network_id             Limit results to those affiliated with a given network ID. If 0,
     120         *                                                include all networks. Default 0.
     121         *     @type array        $network__in            Array of network IDs to include affiliated sites for. Default empty.
     122         *     @type array        $network__not_in        Array of network IDs to exclude affiliated sites for. Default empty.
     123         *     @type string       $domain                 Limit results to those affiliated with a given domain. Default empty.
     124         *     @type array        $domain__in             Array of domains to include affiliated sites for. Default empty.
     125         *     @type array        $domain__not_in         Array of domains to exclude affiliated sites for. Default empty.
     126         *     @type string       $path                   Limit results to those affiliated with a given path. Default empty.
     127         *     @type array        $path__in               Array of paths to include affiliated sites for. Default empty.
     128         *     @type array        $path__not_in           Array of paths to exclude affiliated sites for. Default empty.
     129         *     @type int          $public                 Limit results to public sites. Accepts '1' or '0'. Default empty.
     130         *     @type int          $archived               Limit results to archived sites. Accepts '1' or '0'. Default empty.
     131         *     @type int          $mature                 Limit results to mature sites. Accepts '1' or '0'. Default empty.
     132         *     @type int          $spam                   Limit results to spam sites. Accepts '1' or '0'. Default empty.
     133         *     @type int          $deleted                Limit results to deleted sites. Accepts '1' or '0'. Default empty.
     134         *     @type int          $lang_id                Limit results to a language ID. Default empty.
     135         *     @type array        $lang__in               Array of language IDs to include affiliated sites for. Default empty.
     136         *     @type array        $lang__not_in           Array of language IDs to exclude affiliated sites for. Default empty.
     137         *     @type string       $search                 Search term(s) to retrieve matching sites for. Default empty.
     138         *     @type array        $search_columns         Array of column names to be searched. Accepts 'domain' and 'path'.
     139         *                                                Default empty array.
     140         *     @type bool         $update_site_cache      Whether to prime the cache for found sites. Default false.
     141         *     @type bool         $update_site_meta_cache Whether to prime the metadata cache for found sites.
     142         *                                                Default true.
    140143         * }
    141144         */
    142145        public function __construct( $query = '' ) {
    143146                $this->query_var_defaults = array(
    144                         'fields'            => '',
    145                         'ID'                => '',
    146                         'site__in'          => '',
    147                         'site__not_in'      => '',
    148                         'number'            => 100,
    149                         'offset'            => '',
    150                         'no_found_rows'     => true,
    151                         'orderby'           => 'id',
    152                         'order'             => 'ASC',
    153                         'network_id'        => 0,
    154                         'network__in'       => '',
    155                         'network__not_in'   => '',
    156                         'domain'            => '',
    157                         'domain__in'        => '',
    158                         'domain__not_in'    => '',
    159                         'path'              => '',
    160                         'path__in'          => '',
    161                         'path__not_in'      => '',
    162                         'public'            => null,
    163                         'archived'          => null,
    164                         'mature'            => null,
    165                         'spam'              => null,
    166                         'deleted'           => null,
    167                         'lang_id'           => null,
    168                         'lang__in'          => '',
    169                         'lang__not_in'      => '',
    170                         'search'            => '',
    171                         'search_columns'    => array(),
    172                         'count'             => false,
    173                         'date_query'        => null, // See WP_Date_Query
    174                         'update_site_cache' => true,
     147                        'fields'                 => '',
     148                        'ID'                     => '',
     149                        'site__in'               => '',
     150                        'site__not_in'           => '',
     151                        'number'                 => 100,
     152                        'offset'                 => '',
     153                        'no_found_rows'          => true,
     154                        'orderby'                => 'id',
     155                        'order'                  => 'ASC',
     156                        'network_id'             => 0,
     157                        'network__in'            => '',
     158                        'network__not_in'        => '',
     159                        'domain'                 => '',
     160                        'domain__in'             => '',
     161                        'domain__not_in'         => '',
     162                        'path'                   => '',
     163                        'path__in'               => '',
     164                        'path__not_in'           => '',
     165                        'public'                 => null,
     166                        'archived'               => null,
     167                        'mature'                 => null,
     168                        'spam'                   => null,
     169                        'deleted'                => null,
     170                        'lang_id'                => null,
     171                        'lang__in'               => '',
     172                        'lang__not_in'           => '',
     173                        'search'                 => '',
     174                        'search_columns'         => array(),
     175                        'count'                  => false,
     176                        'date_query'             => null, // See WP_Date_Query
     177                        'update_site_cache'      => true,
     178                        'update_site_meta_cache' => true,
    175179                );
    176180
    177181                if ( ! empty( $query ) ) {
     
    286290
    287291                // Prime site network caches.
    288292                if ( $this->query_vars['update_site_cache'] ) {
    289                         _prime_site_caches( $site_ids );
     293                        _prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] );
    290294                }
    291295
    292296                // Fetch full site objects from the primed cache.
  • src/wp-includes/functions.php

     
    44994499}
    45004500
    45014501/**
     4502 * Determines whether site meta is enabled.
     4503 *
     4504 * This function checks whether the 'blogmeta' database table exists. The result is saved as
     4505 * a setting for the main network, making it essentially a global setting. Subsequent requests
     4506 * will refer to this setting instead of running the query. The $force parameter can be used
     4507 * to bypass the setting, and reset it accordingly, however this is not recommended.
     4508 *
     4509 * The 'is_site_meta_supported' filter can be used to bypass the database checks completely.
     4510 *
     4511 * @since 4.9.0
     4512 *
     4513 * @global wpdb $wpdb WordPress database abstraction object.
     4514 *
     4515 * @return bool True if site meta is supported, false otherwise.
     4516 */
     4517function is_site_meta_supported() {
     4518        global $wpdb;
     4519
     4520        if ( ! is_multisite() ) {
     4521                return false;
     4522        }
     4523
     4524        /**
     4525         * Filters whether site meta is supported.
     4526         *
     4527         * Returning a non-null value here will short-circuit the function
     4528         * and bypass the database checks.
     4529         *
     4530         * @param null $supported The short-circuit value. If anything other than null is returned,
     4531         *                        it is interpreted as a boolean and will short-circuit.
     4532         */
     4533        $supported = apply_filters( 'is_site_meta_supported', null );
     4534        if ( null !== $supported ) {
     4535                return (bool) $supported;
     4536        }
     4537
     4538        $network_id = get_main_network_id();
     4539
     4540        if ( false === ( $supported = get_network_option( $network_id, 'site_meta_supported', false ) ) ) {
     4541                $supported = $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->blogmeta}'" ) ? 1 : 0;
     4542
     4543                update_network_option( $network_id, 'site_meta_supported', $supported );
     4544        }
     4545
     4546        return (bool) $supported;
     4547}
     4548
     4549/**
    45024550 * gmt_offset modification for smart timezone handling.
    45034551 *
    45044552 * Overrides the gmt_offset option if we have a timezone_string available.
  • src/wp-includes/load.php

     
    517517        }
    518518
    519519        if ( function_exists( 'wp_cache_add_global_groups' ) ) {
    520                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'site-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites' ) );
     520                wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'site-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'blog_meta' ) );
    521521                wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    522522        }
    523523}
  • src/wp-includes/ms-blogs.php

     
    465465        wp_cache_delete( $domain_path_key, 'blog-id-cache' );
    466466        wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
    467467        wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
     468        wp_cache_delete( $blog_id, 'blog_meta' );
    468469
    469470        /**
    470471         * Fires immediately after a site has been removed from the object cache.
     
    541542 * Adds any sites from the given ids to the cache that do not already exist in cache.
    542543 *
    543544 * @since 4.6.0
     545 * @since 4.9.0 The $update_meta_cache parameter was added.
    544546 * @access private
    545547 *
    546548 * @see update_site_cache()
     549 * @see update_sitemeta_cache()
     550 *
    547551 * @global wpdb $wpdb WordPress database abstraction object.
    548552 *
    549  * @param array $ids ID list.
     553 * @param array $ids               ID list.
     554 * @param bool  $update_meta_cache Optional. Whether to update the meta cache. Default true.
    550555 */
    551 function _prime_site_caches( $ids ) {
     556function _prime_site_caches( $ids, $update_meta_cache = true ) {
    552557        global $wpdb;
    553558
    554559        $non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
    555560        if ( ! empty( $non_cached_ids ) ) {
    556561                $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
    557562
    558                 update_site_cache( $fresh_sites );
     563                update_site_cache( $fresh_sites, $update_meta_cache );
    559564        }
    560565}
    561566
     
    566571 *
    567572 * @param array $sites Array of site objects.
    568573 */
    569 function update_site_cache( $sites ) {
     574function update_site_cache( $sites, $update_meta_cache = true ) {
    570575        if ( ! $sites ) {
    571576                return;
    572577        }
    573 
     578        $site_ids = array();
    574579        foreach ( $sites as $site ) {
     580                $site_ids[] = $site->blog_id;
    575581                wp_cache_add( $site->blog_id, $site, 'sites' );
    576582                wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
    577583        }
     584
     585        if ( $update_meta_cache ) {
     586                update_sitemeta_cache( $site_ids );
     587        }
     588}
     589
     590/**
     591 * Updates metadata cache for list of site IDs.
     592 *
     593 * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache.
     594 * Subsequent calls to `get_site_meta()` will not need to query the database.
     595 *
     596 * @since 4.9.0
     597 *
     598 * @param array $site_ids List of site IDs.
     599 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
     600 */
     601function update_sitemeta_cache( $site_ids ) {
     602        if ( ! is_site_meta_supported() ) {
     603                return false;
     604        }
     605
     606        return update_meta_cache( 'blog', $site_ids );
    578607}
    579608
    580609/**
     
    638667        return $query->query( $args );
    639668}
    640669
     670
    641671/**
    642672 * Retrieve option value for a given blog id based on name of option.
    643673 *
     
    768798        return $return;
    769799}
    770800
     801
     802
     803/**
     804 * Add meta data field to a site.
     805 *
     806 * Site meta data is called "Custom Fields" on the Administration Screen.
     807 *
     808 * @since 4.9.0
     809 *
     810 * @param int    $site_id    Site ID.
     811 * @param string $meta_key   Metadata name.
     812 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     813 * @param bool   $unique     Optional. Whether the same key should not be added.
     814 *                           Default false.
     815 * @return int|false Meta ID on success, false on failure.
     816 */
     817function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
     818        // Bail if site meta table is not installed.
     819        if ( ! is_site_meta_supported() ) {
     820                return false;
     821        }
     822
     823        $added = add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique );
     824
     825        // Bust site query cache.
     826        if ( $added ) {
     827                wp_cache_set( 'last_changed', microtime(), 'sites' );
     828        }
     829
     830        return $added;
     831}
     832
     833/**
     834 * Remove metadata matching criteria from a site.
     835 *
     836 * You can match based on the key, or key and value. Removing based on key and
     837 * value, will keep from removing duplicate metadata with the same key. It also
     838 * allows removing all metadata matching key, if needed.
     839 *
     840 * @since 4.9.0
     841 *
     842 * @param int    $site_id    Site ID.
     843 * @param string $meta_key   Metadata name.
     844 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if
     845 *                           non-scalar. Default empty.
     846 * @return bool True on success, false on failure.
     847 */
     848function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
     849        // Bail if site meta table is not installed.
     850        if ( ! is_site_meta_supported() ) {
     851                return false;
     852        }
     853
     854        $deleted = delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
     855
     856        // Bust site query cache.
     857        if ( $deleted ) {
     858                wp_cache_set( 'last_changed', microtime(), 'sites' );
     859        }
     860
     861        return $deleted;
     862}
     863
     864/**
     865 * Retrieve site meta field for a site.
     866 *
     867 * @since 4.9.0
     868 *
     869 * @param int    $site_id Site ID.
     870 * @param string $key     Optional. The meta key to retrieve. By default, returns
     871 *                        data for all keys. Default empty.
     872 * @param bool   $single  Optional. Whether to return a single value. Default false.
     873 * @return mixed Will be an array if $single is false. Will be value of meta data
     874 *               field if $single is true.
     875 */
     876function get_site_meta( $site_id, $key = '', $single = false ) {
     877        // Bail if site meta table is not installed.
     878        if ( ! is_site_meta_supported() ) {
     879                return false;
     880        }
     881
     882        return get_metadata( 'blog', $site_id, $key, $single );
     883}
     884
     885/**
     886 * Update site meta field based on site ID.
     887 *
     888 * Use the $prev_value parameter to differentiate between meta fields with the
     889 * same key and site ID.
     890 *
     891 * If the meta field for the site does not exist, it will be added.
     892 *
     893 * @since 4.9.0
     894 *
     895 * @param int    $site_id    Site ID.
     896 * @param string $meta_key   Metadata key.
     897 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     898 * @param mixed  $prev_value Optional. Previous value to check before removing.
     899 *                           Default empty.
     900 * @return int|bool Meta ID if the key didn't exist, true on successful update,
     901 *                  false on failure.
     902 */
     903function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) {
     904        // Bail if site meta table is not installed.
     905        if ( ! is_site_meta_supported() ) {
     906                return false;
     907        }
     908
     909        $updated = update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value );
     910
     911        // Bust site query cache.
     912        if ( $updated ) {
     913                wp_cache_set( 'last_changed', microtime(), 'sites' );
     914        }
     915
     916        return $updated;
     917}
     918
     919/**
     920 * Delete everything from site meta matching meta key.
     921 *
     922 * @since 4.9.0
     923 *
     924 * @param string $meta_key Metadata key to search for when deleting.
     925 * @return bool Whether the site meta key was deleted from the database.
     926 */
     927function delete_site_meta_by_key( $meta_key ) {
     928        // Bail if site meta table is not installed.
     929        if ( ! is_site_meta_supported() ) {
     930                return false;
     931        }
     932
     933        $deleted = delete_metadata( 'blog', null, $meta_key, '', true );
     934
     935        // Bust site query cache.
     936        if ( $deleted ) {
     937                wp_cache_set( 'last_changed', microtime(), 'sites' );
     938        }
     939
     940        return $deleted;
     941}
     942
    771943/**
    772944 * Switch the current blog.
    773945 *
     
    8421014                        if ( is_array( $global_groups ) ) {
    8431015                                wp_cache_add_global_groups( $global_groups );
    8441016                        } else {
    845                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
     1017                                wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details', 'blog_meta' ) );
    8461018                        }
    8471019                        wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    8481020                }
     
    9161088                        if ( is_array( $global_groups ) ) {
    9171089                                wp_cache_add_global_groups( $global_groups );
    9181090                        } else {
    919                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
     1091                                wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details', 'blog_meta' ) );
    9201092                        }
    9211093                        wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    9221094                }
  • src/wp-includes/option.php

     
    225225        if ( empty($network_id) )
    226226                $network_id = get_current_network_id();
    227227
    228         $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' );
     228        $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', 'site_meta_supported' );
    229229
    230230        $core_options_in = "'" . implode("', '", $core_options) . "'";
    231231        $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 ) );
  • src/wp-includes/version.php

     
    1111 *
    1212 * @global int $wp_db_version
    1313 */
    14 $wp_db_version = 38590;
     14$wp_db_version = 40001;
    1515
    1616/**
    1717 * Holds the TinyMCE version
  • src/wp-includes/wp-db.php

     
    271271         * @see wpdb::tables()
    272272         * @var array
    273273         */
    274         var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
     274        var $ms_global_tables = array( 'blogs', 'blogmeta', 'signups', 'site', 'sitemeta',
    275275                'sitecategories', 'registration_log', 'blog_versions' );
    276276
    277277        /**
     
    383383        public $blogs;
    384384
    385385        /**
     386         * Multisite Blog Metadata table
     387         *
     388         * @since 4.9.0
     389         * @var string
     390         */
     391        public $blogmeta;
     392
     393        /**
    386394         * Multisite Blog Versions table
    387395         *
    388396         * @since 3.0.0
  • src/wp-settings.php

     
    9595// Load early WordPress files.
    9696require( ABSPATH . WPINC . '/compat.php' );
    9797require( ABSPATH . WPINC . '/class-wp-list-util.php' );
     98require( ABSPATH . WPINC . '/formatting.php' );
     99require( ABSPATH . WPINC . '/meta.php' );
    98100require( ABSPATH . WPINC . '/functions.php' );
    99101require( ABSPATH . WPINC . '/class-wp-matchesmapregex.php' );
    100102require( ABSPATH . WPINC . '/class-wp.php' );
     
    142144// Load most of WordPress.
    143145require( ABSPATH . WPINC . '/class-wp-walker.php' );
    144146require( ABSPATH . WPINC . '/class-wp-ajax-response.php' );
    145 require( ABSPATH . WPINC . '/formatting.php' );
    146147require( ABSPATH . WPINC . '/capabilities.php' );
    147148require( ABSPATH . WPINC . '/class-wp-roles.php' );
    148149require( ABSPATH . WPINC . '/class-wp-role.php' );
     
    157158require( ABSPATH . WPINC . '/class-wp-user-query.php' );
    158159require( ABSPATH . WPINC . '/class-wp-session-tokens.php' );
    159160require( ABSPATH . WPINC . '/class-wp-user-meta-session-tokens.php' );
    160 require( ABSPATH . WPINC . '/meta.php' );
    161161require( ABSPATH . WPINC . '/class-wp-meta-query.php' );
    162162require( ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php' );
    163163require( ABSPATH . WPINC . '/general-template.php' );
  • tests/phpunit/includes/testcase.php

     
    323323                        $wp_object_cache->__remoteset();
    324324                }
    325325                wp_cache_flush();
    326                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
     326                wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details', 'blog_meta' ) );
    327327                wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
    328328        }
    329329
  • tests/phpunit/tests/multisite/siteMeta.php

     
     1<?php
     2
     3if ( is_multisite() ) :
     4
     5/**
     6 * @group ms-site
     7 * @group multisite
     8 * @group meta
     9 * @ticket 37923
     10 */
     11class Tests_Multisite_Site_Meta extends WP_UnitTestCase {
     12        protected static $site_id;
     13        protected static $site_id2;
     14        protected static $flag_was_set;
     15
     16        public static function wpSetUpBeforeClass( $factory ) {
     17                self::$site_id = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/' ) );
     18                self::$site_id2 = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/foo/' ) );
     19
     20                // Populate the main network flag as necessary.
     21                self::$flag_was_set = true;
     22                if ( false === get_network_option( get_main_network_id(), 'site_meta_supported', false ) ) {
     23                        self::$flag_was_set = false;
     24                        is_site_meta_supported();
     25                }
     26        }
     27
     28        public static function wpTearDownAfterClass() {
     29                // Delete the possibly previously populated main network flag.
     30                if ( ! self::$flag_was_set ) {
     31                        delete_network_option( get_main_network_id(), 'site_meta_supported' );
     32                }
     33
     34                wpmu_delete_blog( self::$site_id, true );
     35                wpmu_delete_blog( self::$site_id2, true );
     36
     37                wp_update_network_site_counts();
     38        }
     39
     40        public function test_is_site_meta_supported() {
     41                remove_all_filters( 'is_site_meta_supported' );
     42
     43                $setting = get_network_option( get_main_network_id(), 'site_meta_supported' );
     44                if ( $setting ) {
     45                        $this->assertTrue( is_site_meta_supported() );
     46                } else {
     47                        $this->assertFalse( is_site_meta_supported() );
     48                }
     49        }
     50
     51        public function test_is_site_meta_supported_with_filter() {
     52                add_filter( 'is_site_meta_supported', '__return_false' );
     53
     54                $this->assertFalse( is_site_meta_supported() );
     55        }
     56
     57        public function test_add() {
     58                if ( ! is_site_meta_supported() ) {
     59                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     60                }
     61
     62                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     63        }
     64
     65        public function test_add_unique() {
     66                if ( ! is_site_meta_supported() ) {
     67                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     68                }
     69
     70                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     71                $this->assertFalse( add_site_meta( self::$site_id, 'foo', 'bar', true ) );
     72        }
     73
     74        public function test_delete() {
     75                if ( ! is_site_meta_supported() ) {
     76                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     77                }
     78
     79                add_site_meta( self::$site_id, 'foo', 'bar' );
     80
     81                $this->assertTrue( delete_site_meta( self::$site_id, 'foo' ) );
     82        }
     83
     84        public function test_delete_with_invalid_meta_key_should_return_false() {
     85                if ( ! is_site_meta_supported() ) {
     86                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     87                }
     88
     89                $this->assertFalse( delete_site_meta( self::$site_id, 'foo' ) );
     90        }
     91
     92        public function test_delete_should_respect_meta_value() {
     93                if ( ! is_site_meta_supported() ) {
     94                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     95                }
     96
     97                add_site_meta( self::$site_id, 'foo', 'bar' );
     98                add_site_meta( self::$site_id, 'foo', 'baz' );
     99
     100                $this->assertTrue( delete_site_meta( self::$site_id, 'foo', 'bar' ) );
     101
     102                $metas = get_site_meta( self::$site_id, 'foo', false );
     103                $this->assertSame( array( 'baz' ), $metas );
     104        }
     105
     106        public function test_get_with_no_key_should_fetch_all_keys() {
     107                if ( ! is_site_meta_supported() ) {
     108                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     109                }
     110
     111                add_site_meta( self::$site_id, 'foo', 'bar' );
     112                add_site_meta( self::$site_id, 'foo1', 'baz' );
     113
     114                $found = get_site_meta( self::$site_id );
     115                $expected = array(
     116                        'foo' => array( 'bar' ),
     117                        'foo1' => array( 'baz' ),
     118                );
     119
     120                $this->assertEqualSets( $expected, $found );
     121        }
     122
     123        public function test_get_with_key_should_fetch_all_for_key() {
     124                if ( ! is_site_meta_supported() ) {
     125                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     126                }
     127
     128                add_site_meta( self::$site_id, 'foo', 'bar' );
     129                add_site_meta( self::$site_id, 'foo', 'baz' );
     130                add_site_meta( self::$site_id, 'foo1', 'baz' );
     131
     132                $found = get_site_meta( self::$site_id, 'foo' );
     133                $expected = array( 'bar', 'baz' );
     134
     135                $this->assertEqualSets( $expected, $found );
     136        }
     137
     138        public function test_get_should_respect_single_true() {
     139                if ( ! is_site_meta_supported() ) {
     140                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     141                }
     142
     143                add_site_meta( self::$site_id, 'foo', 'bar' );
     144                add_site_meta( self::$site_id, 'foo', 'baz' );
     145
     146                $found = get_site_meta( self::$site_id, 'foo', true );
     147                $this->assertEquals( 'bar', $found );
     148        }
     149
     150        public function test_update_should_pass_to_add_when_no_value_exists_for_key() {
     151                if ( ! is_site_meta_supported() ) {
     152                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     153                }
     154
     155                $actual = update_site_meta( self::$site_id, 'foo', 'bar' );
     156                $this->assertInternalType( 'int', $actual );
     157                $this->assertNotEmpty( $actual );
     158
     159                $meta = get_site_meta( self::$site_id, 'foo', true );
     160                $this->assertSame( 'bar', $meta );
     161        }
     162
     163        public function test_update_should_return_true_when_updating_existing_value_for_key() {
     164                if ( ! is_site_meta_supported() ) {
     165                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     166                }
     167
     168                add_site_meta( self::$site_id, 'foo', 'bar' );
     169
     170                $actual = update_site_meta( self::$site_id, 'foo', 'baz' );
     171                $this->assertTrue( $actual );
     172
     173                $meta = get_site_meta( self::$site_id, 'foo', true );
     174                $this->assertSame( 'baz', $meta );
     175        }
     176
     177        public function test_delete_by_key() {
     178                if ( ! is_site_meta_supported() ) {
     179                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     180                }
     181
     182                add_site_meta( self::$site_id, 'unique_delete_by_key', 'value', true );
     183                add_site_meta( self::$site_id2, 'unique_delete_by_key', 'value', true );
     184
     185                $this->assertEquals( 'value', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     186                $this->assertEquals( 'value', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     187
     188                $this->assertTrue( delete_site_meta_by_key( 'unique_delete_by_key' ) );
     189
     190                $this->assertEquals( '', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     191                $this->assertEquals( '', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     192        }
     193
     194        public function test_site_meta_should_be_deleted_when_site_is_deleted() {
     195                if ( ! is_site_meta_supported() ) {
     196                        $this->markTestSkipped( 'Tests only runs with the blogmeta database table installed' );
     197                }
     198
     199                $site_id = self::factory()->blog->create( array( 'domain' => 'foo.org', 'path' => '/' ) );
     200
     201                add_site_meta( $site_id, 'foo', 'bar' );
     202                add_site_meta( $site_id, 'foo1', 'bar' );
     203
     204                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo', true ) );
     205                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo1', true ) );
     206
     207                wpmu_delete_blog( $site_id, true );
     208
     209                $this->assertSame( '', get_site_meta( $site_id, 'foo', true ) );
     210                $this->assertSame( '', get_site_meta( $site_id, 'foo1', true ) );
     211        }
     212}
     213
     214endif;
     215<?php
     216
     217if ( is_multisite() ) :
     218/**
     219 * @group ms-site
     220 * @group multisite
     221 * @group meta
     222 * @ticket 37923
     223 */
     224class Tests_Multisite_Site_Meta extends WP_UnitTestCase {
     225        protected static $site_id;
     226        protected static $site_id2;
     227
     228    function setUp() {
     229        global $wpdb;
     230        parent::setUp();
     231        $this->suppress = $wpdb->suppress_errors();
     232
     233        update_site_option( 'site_meta_supported', 1 );
     234    }
     235
     236    function tearDown() {
     237        global $wpdb;
     238
     239        update_site_option( 'site_meta_supported', 0 );
     240        $wpdb->suppress_errors( $this->suppress );
     241
     242        parent::tearDown();
     243    }
     244
     245        public static function wpSetUpBeforeClass( $factory ) {
     246                self::$site_id = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/' ) );
     247                self::$site_id2 = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/foo/' ) );
     248        }
     249
     250        public static function wpTearDownAfterClass() {
     251                wpmu_delete_blog( self::$site_id, true );
     252                wpmu_delete_blog( self::$site_id2, true );
     253
     254                wp_update_network_site_counts();
     255        delete_site_option( 'site_meta_supported');
     256        }
     257
     258        public function test_add() {
     259                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     260        }
     261
     262        public function test_add_unique() {
     263                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     264                $this->assertFalse( add_site_meta( self::$site_id, 'foo', 'bar', true ) );
     265        }
     266
     267        public function test_delete() {
     268                add_site_meta( self::$site_id, 'foo', 'bar' );
     269
     270                $this->assertTrue( delete_site_meta( self::$site_id, 'foo' ) );
     271        }
     272
     273        public function test_delete_with_invalid_meta_key_should_return_false() {
     274                $this->assertFalse( delete_site_meta( self::$site_id, 'foo' ) );
     275        }
     276
     277        public function test_delete_should_respect_meta_value() {
     278                add_site_meta( self::$site_id, 'foo', 'bar' );
     279                add_site_meta( self::$site_id, 'foo', 'baz' );
     280
     281                $this->assertTrue( delete_site_meta( self::$site_id, 'foo', 'bar' ) );
     282
     283                $metas = get_site_meta( self::$site_id, 'foo', false );
     284                $this->assertSame( array( 'baz' ), $metas );
     285        }
     286
     287        public function test_get_with_no_key_should_fetch_all_keys() {
     288                add_site_meta( self::$site_id, 'foo', 'bar' );
     289                add_site_meta( self::$site_id, 'foo1', 'baz' );
     290
     291                $found = get_site_meta( self::$site_id );
     292                $expected = array(
     293                        'foo' => array( 'bar' ),
     294                        'foo1' => array( 'baz' ),
     295                );
     296
     297                $this->assertEqualSets( $expected, $found );
     298        }
     299
     300        public function test_get_with_key_should_fetch_all_for_key() {
     301                add_site_meta( self::$site_id, 'foo', 'bar' );
     302                add_site_meta( self::$site_id, 'foo', 'baz' );
     303                add_site_meta( self::$site_id, 'foo1', 'baz' );
     304
     305                $found = get_site_meta( self::$site_id, 'foo' );
     306                $expected = array( 'bar', 'baz' );
     307
     308                $this->assertEqualSets( $expected, $found );
     309        }
     310
     311        public function test_get_should_respect_single_true() {
     312                add_site_meta( self::$site_id, 'foo', 'bar' );
     313                add_site_meta( self::$site_id, 'foo', 'baz' );
     314
     315                $found = get_site_meta( self::$site_id, 'foo', true );
     316                $this->assertEquals( 'bar', $found );
     317        }
     318
     319        public function test_update_should_pass_to_add_when_no_value_exists_for_key() {
     320                $actual = update_site_meta( self::$site_id, 'foo', 'bar' );
     321                $this->assertInternalType( 'int', $actual );
     322                $this->assertNotEmpty( $actual );
     323
     324                $meta = get_site_meta( self::$site_id, 'foo', true );
     325                $this->assertSame( 'bar', $meta );
     326        }
     327
     328        public function test_update_should_return_true_when_updating_existing_value_for_key() {
     329                add_site_meta( self::$site_id, 'foo', 'bar' );
     330
     331                $actual = update_site_meta( self::$site_id, 'foo', 'baz' );
     332                $this->assertTrue( $actual );
     333
     334                $meta = get_site_meta( self::$site_id, 'foo', true );
     335                $this->assertSame( 'baz', $meta );
     336        }
     337
     338        public function test_delete_by_key() {
     339                add_site_meta( self::$site_id, 'unique_delete_by_key', 'value', true );
     340                add_site_meta( self::$site_id2, 'unique_delete_by_key', 'value', true );
     341
     342                $this->assertEquals( 'value', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     343                $this->assertEquals( 'value', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     344
     345                $this->assertTrue( delete_site_meta_by_key( 'unique_delete_by_key' ) );
     346
     347                $this->assertEquals( '', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     348                $this->assertEquals( '', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     349        }
     350
     351        public function test_site_meta_should_be_deleted_when_site_is_deleted() {
     352                $site_id = self::factory()->blog->create( array( 'domain' => 'foo.org', 'path' => '/' ) );
     353
     354                add_site_meta( $site_id, 'foo', 'bar' );
     355                add_site_meta( $site_id, 'foo1', 'bar' );
     356
     357                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo', true ) );
     358                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo1', true ) );
     359
     360                wpmu_delete_blog( $site_id, true );
     361
     362                $this->assertSame( '', get_site_meta( $site_id, 'foo', true ) );
     363                $this->assertSame( '', get_site_meta( $site_id, 'foo1', true ) );
     364        }
     365
     366        public function test_disabled_site_meta_by_filter(){
     367        $site_id = self::factory()->blog->create( array( 'domain' => 'foo.org', 'path' => '/' ) );
     368        add_filter( 'pre_site_option_site_meta_supported', '__return_null' );
     369
     370            $this->assertSame( null, get_site_option('site_meta_supported') );
     371            $this->assertSame( false, add_site_meta( $site_id, 'wibble', 'test1' ) );
     372            $this->assertSame( false, update_site_meta( $site_id, 'wibble', 'test2' ) );
     373        $this->assertSame( false, get_site_meta( $site_id, 'wibble' ) );
     374            $this->assertSame( false, delete_site_meta( $site_id, 'wibble' ) );
     375
     376        remove_filter( 'pre_site_option_site_meta_supported', '__return_null' );
     377    }
     378}
     379
     380endif;