WordPress.org

Make WordPress Core

Ticket #37923: 37923.diff

File 37923.diff, 35.1 KB (added by flixos90, 16 months ago)
  • src/wp-admin/includes/ms.php

     
    127127                        $wpdb->query( "DROP TABLE IF EXISTS `$table`" );
    128128                }
    129129
     130                $blog_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->blogmeta WHERE blog_id = %d ", $blog_id ) );
     131                foreach ( $blog_meta_ids as $mid ) {
     132                        delete_metadata_by_mid( 'blog', $mid );
     133                }
     134
    130135                $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
    131136
    132137                /**
  • 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-includes/class-wp-site-query.php

     
    4242        );
    4343
    4444        /**
     45         * Metadata query container.
     46         *
     47         * @since 4.8.0
     48         * @access public
     49         * @var object WP_Meta_Query
     50         */
     51        public $meta_query = false;
     52
     53        /**
     54         * Metadata query clauses.
     55         *
     56         * @since 4.8.0
     57         * @access protected
     58         * @var array
     59         */
     60        protected $meta_query_clauses = array();
     61
     62        /**
    4563         * Date query container.
    4664         *
    4765         * @since 4.6.0
     
    99117         * Sets up the site query, based on the query vars passed.
    100118         *
    101119         * @since 4.6.0
    102          * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
     120         * @since 4.8.0 Introduced the 'lang_id', 'lang__in', 'lang__not_in',
     121         *              `update_site_meta_cache`, `meta_query`, `meta_key`,
     122+        *              `meta_value`, `meta_type` and `meta_compare` parameters.
    103123         * @access public
    104124         *
    105125         * @param string|array $query {
    106126         *     Optional. Array or query string of site query parameters. Default empty.
    107127         *
    108          *     @type array        $site__in          Array of site IDs to include. Default empty.
    109          *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
    110          *     @type bool         $count             Whether to return a site count (true) or array of site objects.
    111          *                                           Default false.
    112          *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
    113          *                                           Default null.
    114          *     @type string       $fields            Site fields to return. Accepts 'ids' (returns an array of site IDs)
    115          *                                           or empty (returns an array of complete site objects). Default empty.
    116          *     @type int          $ID                A site ID to only return that site. Default empty.
    117          *     @type int          $number            Maximum number of sites to retrieve. Default 100.
    118          *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
    119          *                                           Default 0.
    120          *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
    121          *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
    122          *                                           'network_id', 'last_updated', 'registered', 'domain_length',
    123          *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
    124          *                                           an empty array, or 'none' to disable `ORDER BY` clause.
    125          *                                           Default 'id'.
    126          *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
    127          *     @type int          $network_id        Limit results to those affiliated with a given network ID. If 0,
    128          *                                           include all networks. Default 0.
    129          *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
    130          *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
    131          *     @type string       $domain            Limit results to those affiliated with a given domain. Default empty.
    132          *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
    133          *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
    134          *     @type string       $path              Limit results to those affiliated with a given path. Default empty.
    135          *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
    136          *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
    137          *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
    138          *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
    139          *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
    140          *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
    141          *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
    142          *     @type int          $lang_id           Limit results to a language ID. Default empty.
    143          *     @type array        $lang__in          Array of language IDs to include affiliated sites for. Default empty.
    144          *     @type array        $lang__not_in      Array of language IDs to exclude affiliated sites for. Default empty.
    145          *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
    146          *     @type array        $search_columns    Array of column names to be searched. Accepts 'domain' and 'path'.
    147          *                                           Default empty array.
    148          *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default false.
     128         *     @type array        $site__in               Array of site IDs to include. Default empty.
     129         *     @type array        $site__not_in           Array of site IDs to exclude. Default empty.
     130         *     @type bool         $count                  Whether to return a site count (true) or array of site objects.
     131         *                                                Default false.
     132         *     @type array        $date_query             Date query clauses to limit sites by. See WP_Date_Query.
     133         *                                                Default null.
     134         *     @type string       $fields                 Site fields to return. Accepts 'ids' (returns an array of site IDs)
     135         *                                                or empty (returns an array of complete site objects). Default empty.
     136         *     @type int          $ID                     A site ID to only return that site. Default empty.
     137         *     @type int          $number                 Maximum number of sites to retrieve. Default 100.
     138         *     @type int          $offset                 Number of sites to offset the query. Used to build LIMIT clause.
     139         *                                                Default 0.
     140         *     @type bool         $no_found_rows          Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
     141         *     @type string|array $orderby                Site status or array of statuses. Accepts 'id', 'domain', 'path',
     142         *                                                'network_id', 'last_updated', 'registered', 'domain_length',
     143         *                                                'path_length', 'site__in' and 'network__in'. Also accepts false,
     144         *                                                an empty array, or 'none' to disable `ORDER BY` clause.
     145         *                                                Default 'id'.
     146         *     @type string       $order                  How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
     147         *     @type int          $network_id             Limit results to those affiliated with a given network ID. If 0,
     148         *                                                include all networks. Default 0.
     149         *     @type array        $network__in            Array of network IDs to include affiliated sites for. Default empty.
     150         *     @type array        $network__not_in        Array of network IDs to exclude affiliated sites for. Default empty.
     151         *     @type string       $domain                 Limit results to those affiliated with a given domain. Default empty.
     152         *     @type array        $domain__in             Array of domains to include affiliated sites for. Default empty.
     153         *     @type array        $domain__not_in         Array of domains to exclude affiliated sites for. Default empty.
     154         *     @type string       $path                   Limit results to those affiliated with a given path. Default empty.
     155         *     @type array        $path__in               Array of paths to include affiliated sites for. Default empty.
     156         *     @type array        $path__not_in           Array of paths to exclude affiliated sites for. Default empty.
     157         *     @type int          $public                 Limit results to public sites. Accepts '1' or '0'. Default empty.
     158         *     @type int          $archived               Limit results to archived sites. Accepts '1' or '0'. Default empty.
     159         *     @type int          $mature                 Limit results to mature sites. Accepts '1' or '0'. Default empty.
     160         *     @type int          $spam                   Limit results to spam sites. Accepts '1' or '0'. Default empty.
     161         *     @type int          $deleted                Limit results to deleted sites. Accepts '1' or '0'. Default empty.
     162         *     @type int          $lang_id                Limit results to a language ID. Default empty.
     163         *     @type array        $lang__in               Array of language IDs to include affiliated sites for. Default empty.
     164         *     @type array        $lang__not_in           Array of language IDs to exclude affiliated sites for. Default empty.
     165         *     @type string       $search                 Search term(s) to retrieve matching sites for. Default empty.
     166         *     @type array        $search_columns         Array of column names to be searched. Accepts 'domain' and 'path'.
     167         *                                                Default empty array.
     168         *     @type bool         $update_site_cache      Whether to prime the cache for found sites. Default false.
     169         *     @type bool         $update_site_meta_cache Whether to prime meta caches for matched sites. Default true.
     170         *     @type array        $meta_query             Optional. Meta query clauses to limit retrieved sites by.
     171         *                                                See `WP_Meta_Query`. Default empty.
     172         *     @type string       $meta_key               Limit sites to those matching a specific metadata key.
     173         *                                                Can be used in conjunction with `$meta_value`. Default empty.
     174         *     @type string       $meta_value             Limit sites to those matching a specific metadata value.
     175         *                                                Usually used in conjunction with `$meta_key`. Default empty.
     176         *     @type string       $meta_type              Type of object metadata is for (e.g., comment, post, or user).
     177         *                                                Default empty.
     178         *     @type string       $meta_compare           Comparison operator to test the 'meta_value'. Default empty.
    149179         * }
    150180         */
    151181        public function __construct( $query = '' ) {
    152182                $this->query_var_defaults = array(
    153                         'fields'            => '',
    154                         'ID'                => '',
    155                         'site__in'          => '',
    156                         'site__not_in'      => '',
    157                         'number'            => 100,
    158                         'offset'            => '',
    159                         'no_found_rows'     => true,
    160                         'orderby'           => 'id',
    161                         'order'             => 'ASC',
    162                         'network_id'        => 0,
    163                         'network__in'       => '',
    164                         'network__not_in'   => '',
    165                         'domain'            => '',
    166                         'domain__in'        => '',
    167                         'domain__not_in'    => '',
    168                         'path'              => '',
    169                         'path__in'          => '',
    170                         'path__not_in'      => '',
    171                         'public'            => null,
    172                         'archived'          => null,
    173                         'mature'            => null,
    174                         'spam'              => null,
    175                         'deleted'           => null,
    176                         'lang_id'           => null,
    177                         'lang__in'          => '',
    178                         'lang__not_in'      => '',
    179                         'search'            => '',
    180                         'search_columns'    => array(),
    181                         'count'             => false,
    182                         'date_query'        => null, // See WP_Date_Query
    183                         'update_site_cache' => true,
     183                        'fields'                 => '',
     184                        'ID'                     => '',
     185                        'site__in'               => '',
     186                        'site__not_in'           => '',
     187                        'number'                 => 100,
     188                        'offset'                 => '',
     189                        'no_found_rows'          => true,
     190                        'orderby'                => 'id',
     191                        'order'                  => 'ASC',
     192                        'network_id'             => 0,
     193                        'network__in'            => '',
     194                        'network__not_in'        => '',
     195                        'domain'                 => '',
     196                        'domain__in'             => '',
     197                        'domain__not_in'         => '',
     198                        'path'                   => '',
     199                        'path__in'               => '',
     200                        'path__not_in'           => '',
     201                        'public'                 => null,
     202                        'archived'               => null,
     203                        'mature'                 => null,
     204                        'spam'                   => null,
     205                        'deleted'                => null,
     206                        'lang_id'                => null,
     207                        'lang__in'               => '',
     208                        'lang__not_in'           => '',
     209                        'search'                 => '',
     210                        'search_columns'         => array(),
     211                        'count'                  => false,
     212                        'date_query'             => null, // See WP_Date_Query
     213                        'update_site_cache'      => true,
     214                        'update_site_meta_cache' => true,
     215                        'meta_query'             => '',
     216                        'meta_key'               => '',
     217                        'meta_value'             => '',
     218                        'meta_type'              => '',
     219                        'meta_compare'           => '',
    184220                );
    185221
    186222                if ( ! empty( $query ) ) {
     
    236272         * @since 4.6.0
    237273         * @access public
    238274         *
     275         * @global wpdb $wpdb WordPress database abstraction object.
     276         *
    239277         * @return array|int List of sites, or number of sites when 'count' is passed as a query var.
    240278         */
    241279        public function get_sites() {
     280                global $wpdb;
     281
    242282                $this->parse_query();
    243283
     284                // Set up meta_query so it's available to 'pre_get_sites'.
     285                if ( class_exists( 'WP_Meta_Query' ) ) {
     286                        $this->meta_query = new WP_Meta_Query();
     287                        $this->meta_query->parse_query_vars( $this->query_vars );
     288                }
     289
    244290                /**
    245291                 * Fires before sites are retrieved.
    246292                 *
     
    250296                 */
    251297                do_action_ref_array( 'pre_get_sites', array( &$this ) );
    252298
     299                // Reparse query vars, in case they were modified in a 'pre_get_comments' callback.
     300                if ( $this->meta_query ) {
     301                        $this->meta_query->parse_query_vars( $this->query_vars );
     302                        if ( ! empty( $this->meta_query->queries ) ) {
     303                                $this->meta_query_clauses = $this->meta_query->get_sql( 'blog', $wpdb->blogs, 'blog_id', $this );
     304                        }
     305                }
     306
    253307                // $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
    254308                $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
    255309                $last_changed = wp_cache_get_last_changed( 'sites' );
     
    293347
    294348                // Prime site network caches.
    295349                if ( $this->query_vars['update_site_cache'] ) {
    296                         _prime_site_caches( $site_ids );
     350                        if ( $this->meta_query ) {
     351                                _prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] );
     352                        } else {
     353                                _prime_site_caches( $site_ids, false );
     354                        }
    297355                }
    298356
    299357                // Fetch full site objects from the primed cache.
     
    373431
    374432                        $orderby = implode( ', ', $orderby_array );
    375433                } else {
    376                         $orderby = "blog_id $order";
     434                        $orderby = "$wpdb->blogs.blog_id $order";
    377435                }
    378436
    379437                $number = absint( $this->query_vars['number'] );
     
    390448                if ( $this->query_vars['count'] ) {
    391449                        $fields = 'COUNT(*)';
    392450                } else {
    393                         $fields = 'blog_id';
     451                        $fields = "$wpdb->blogs.blog_id";
    394452                }
    395453
    396454                // Parse site IDs for an IN clause.
    397455                $site_id = absint( $this->query_vars['ID'] );
    398456                if ( ! empty( $site_id ) ) {
    399                         $this->sql_clauses['where']['ID'] = $wpdb->prepare( 'blog_id = %d', $site_id );
     457                        $this->sql_clauses['where']['ID'] = $wpdb->prepare( "$wpdb->blogs.blog_id = %d", $site_id );
    400458                }
    401459
    402460                // Parse site IDs for an IN clause.
    403461                if ( ! empty( $this->query_vars['site__in'] ) ) {
    404                         $this->sql_clauses['where']['site__in'] = "blog_id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__in'] ) ) . ' )';
     462                        $this->sql_clauses['where']['site__in'] = "$wpdb->blogs.blog_id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__in'] ) ) . ' )';
    405463                }
    406464
    407465                // Parse site IDs for a NOT IN clause.
    408466                if ( ! empty( $this->query_vars['site__not_in'] ) ) {
    409                         $this->sql_clauses['where']['site__not_in'] = "blog_id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__not_in'] ) ) . ' )';
     467                        $this->sql_clauses['where']['site__not_in'] = "$wpdb->blogs.blog_id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__not_in'] ) ) . ' )';
    410468                }
    411469
    412470                $network_id = absint( $this->query_vars['network_id'] );
     
    529587
    530588                $join = '';
    531589
     590                if ( ! empty( $this->meta_query_clauses ) ) {
     591                        $join .= $this->meta_query_clauses['join'];
     592
     593                        // Strip leading 'AND'.
     594                        $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] );
     595
     596                        if ( ! $this->query_vars['count'] ) {
     597                                $groupby = "{$wpdb->blogs}.blog_id";
     598                        }
     599                }
     600
    532601                $where = implode( ' AND ', $this->sql_clauses['where'] );
    533602
    534603                $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
     
    681750                                $parsed = 'CHAR_LENGTH(path)';
    682751                                break;
    683752                        case 'id':
    684                                 $parsed = 'blog_id';
     753                                $parsed = "$wpdb->blogs.blog_id";
    685754                                break;
    686755                }
    687756
     757                if ( ! $parsed && $this->meta_query ) {
     758                        switch ( $orderby ) {
     759                                case $this->query_vars['meta_key']:
     760                                case 'meta_value':
     761                                        $parsed = "$wpdb->blogmeta.meta_value";
     762                                        break;
     763                                case 'meta_value_num':
     764                                        $parsed = "$wpdb->blogmeta.meta_value+0";
     765                                        break;
     766                                default:
     767                                        $meta_query_clauses = $this->meta_query->get_clauses();
     768                                        if ( $meta_query_clauses && isset( $meta_query_clauses[ $orderby ] ) ) {
     769                                                $meta_clause = $meta_query_clauses[ $orderby ];
     770                                                $parsed = sprintf( "CAST(%s.meta_value AS %s)", esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) );
     771                                        }
     772                        }
     773                }
     774
    688775                return $parsed;
    689776        }
    690777
  • src/wp-includes/load.php

     
    515515        }
    516516
    517517        if ( function_exists( 'wp_cache_add_global_groups' ) ) {
    518                 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' ) );
     518                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' ) );
    519519                wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    520520        }
    521521}
  • 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.8.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' );
     
    556561                $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
    557562
    558563                update_site_cache( $fresh_sites );
     564
     565                if ( $update_meta_cache ) {
     566                        update_sitemeta_cache( $non_cached_ids );
     567                }
    559568        }
    560569}
    561570
     
    578587}
    579588
    580589/**
     590 * Updates metadata cache for list of site IDs.
     591 *
     592 * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache.
     593 * Subsequent calls to `get_site_meta()` will not need to query the database.
     594 *
     595 * @since 4.8.0
     596 *
     597 * @param array $site_ids List of site IDs.
     598 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
     599 */
     600function update_sitemeta_cache( $site_ids ) {
     601        return update_meta_cache( 'blog', $site_ids );
     602}
     603
     604/**
    581605 * Retrieves a list of sites matching requested arguments.
    582606 *
    583607 * @since 4.6.0
     
    639663}
    640664
    641665/**
     666 * Add meta data field to a site.
     667 *
     668 * Site meta data is called "Custom Fields" on the Administration Screen.
     669 *
     670 * @since 4.8.0
     671 *
     672 * @param int    $site_id    Site ID.
     673 * @param string $meta_key   Metadata name.
     674 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     675 * @param bool   $unique     Optional. Whether the same key should not be added.
     676 *                           Default false.
     677 * @return int|false Meta ID on success, false on failure.
     678 */
     679function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
     680        $added = add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique );
     681
     682        // Bust site query cache.
     683        if ( $added ) {
     684                wp_cache_set( 'last_changed', microtime(), 'sites' );
     685        }
     686
     687        return $added;
     688}
     689
     690/**
     691 * Remove metadata matching criteria from a site.
     692 *
     693 * You can match based on the key, or key and value. Removing based on key and
     694 * value, will keep from removing duplicate metadata with the same key. It also
     695 * allows removing all metadata matching key, if needed.
     696 *
     697 * @since 4.8.0
     698 *
     699 * @param int    $site_id    Site ID.
     700 * @param string $meta_key   Metadata name.
     701 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if
     702 *                           non-scalar. Default empty.
     703 * @return bool True on success, false on failure.
     704 */
     705function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
     706        $deleted = delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
     707
     708        // Bust site query cache.
     709        if ( $deleted ) {
     710                wp_cache_set( 'last_changed', microtime(), 'sites' );
     711        }
     712
     713        return $deleted;
     714}
     715
     716/**
     717 * Retrieve site meta field for a site.
     718 *
     719 * @since 4.8.0
     720 *
     721 * @param int    $site_id Site ID.
     722 * @param string $key     Optional. The meta key to retrieve. By default, returns
     723 *                        data for all keys. Default empty.
     724 * @param bool   $single  Optional. Whether to return a single value. Default false.
     725 * @return mixed Will be an array if $single is false. Will be value of meta data
     726 *               field if $single is true.
     727 */
     728function get_site_meta( $site_id, $key = '', $single = false ) {
     729        return get_metadata( 'blog', $site_id, $key, $single );
     730}
     731
     732/**
     733 * Update site meta field based on site ID.
     734 *
     735 * Use the $prev_value parameter to differentiate between meta fields with the
     736 * same key and site ID.
     737 *
     738 * If the meta field for the site does not exist, it will be added.
     739 *
     740 * @since 4.8.0
     741 *
     742 * @param int    $site_id    Site ID.
     743 * @param string $meta_key   Metadata key.
     744 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     745 * @param mixed  $prev_value Optional. Previous value to check before removing.
     746 *                           Default empty.
     747 * @return int|bool Meta ID if the key didn't exist, true on successful update,
     748 *                  false on failure.
     749 */
     750function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) {
     751        $updated = update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value );
     752
     753        // Bust site query cache.
     754        if ( $updated ) {
     755                wp_cache_set( 'last_changed', microtime(), 'sites' );
     756        }
     757
     758        return $updated;
     759}
     760
     761/**
     762 * Delete everything from site meta matching meta key.
     763 *
     764 * @since 4.8.0
     765 *
     766 * @param string $meta_key Metadata key to search for when deleting.
     767 * @return bool Whether the site meta key was deleted from the database.
     768 */
     769function delete_site_meta_by_key( $meta_key ) {
     770        return delete_metadata( 'blog', null, $meta_key, '', true );
     771}
     772
     773/**
    642774 * Retrieve option value for a given blog id based on name of option.
    643775 *
    644776 * If the option does not exist or does not have a value, then the return value
     
    842974                        if ( is_array( $global_groups ) ) {
    843975                                wp_cache_add_global_groups( $global_groups );
    844976                        } 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' ) );
     977                                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' ) );
    846978                        }
    847979                        wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    848980                }
     
    9161048                        if ( is_array( $global_groups ) ) {
    9171049                                wp_cache_add_global_groups( $global_groups );
    9181050                        } 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' ) );
     1051                                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' ) );
    9201052                        }
    9211053                        wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
    9221054                }
  • src/wp-includes/version.php

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

     
    298298         * @see wpdb::tables()
    299299         * @var array
    300300         */
    301         var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
     301        var $ms_global_tables = array( 'blogs', 'blogmeta', 'signups', 'site', 'sitemeta',
    302302                'sitecategories', 'registration_log', 'blog_versions' );
    303303
    304304        /**
     
    423423        public $blogs;
    424424
    425425        /**
     426         * Multisite Blog Metadata table
     427         *
     428         * @since 4.8.0
     429         * @access public
     430         * @var string
     431         */
     432        public $blogmeta;
     433
     434        /**
    426435         * Multisite Blog Versions table
    427436         *
    428437         * @since 3.0.0
  • tests/phpunit/tests/multisite/siteMeta.php

     
     1<?php
     2
     3if ( is_multisite() ) :
     4/**
     5 * @group ms-site
     6 * @group multisite
     7 * @group meta
     8 * @ticket 37923
     9 */
     10class Tests_Multisite_Site_Meta extends WP_UnitTestCase {
     11        protected static $site_id;
     12        protected static $site_id2;
     13
     14        public static function wpSetUpBeforeClass( $factory ) {
     15                self::$site_id = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/' ) );
     16                self::$site_id2 = $factory->blog->create( array( 'domain' => 'wordpress.org', 'path' => '/foo/' ) );
     17        }
     18
     19        public static function wpTearDownAfterClass() {
     20                wpmu_delete_blog( self::$site_id, true );
     21                wpmu_delete_blog( self::$site_id2, true );
     22
     23                wp_update_network_site_counts();
     24        }
     25
     26        public function test_add() {
     27                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     28        }
     29
     30        public function test_add_unique() {
     31                $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) );
     32                $this->assertFalse( add_site_meta( self::$site_id, 'foo', 'bar', true ) );
     33        }
     34
     35        public function test_delete() {
     36                add_site_meta( self::$site_id, 'foo', 'bar' );
     37
     38                $this->assertTrue( delete_site_meta( self::$site_id, 'foo' ) );
     39        }
     40
     41        public function test_delete_with_invalid_meta_key_should_return_false() {
     42                $this->assertFalse( delete_site_meta( self::$site_id, 'foo' ) );
     43        }
     44
     45        public function test_delete_should_respect_meta_value() {
     46                add_site_meta( self::$site_id, 'foo', 'bar' );
     47                add_site_meta( self::$site_id, 'foo', 'baz' );
     48
     49                $this->assertTrue( delete_site_meta( self::$site_id, 'foo', 'bar' ) );
     50
     51                $metas = get_site_meta( self::$site_id, 'foo', false );
     52                $this->assertSame( array( 'baz' ), $metas );
     53        }
     54
     55        public function test_get_with_no_key_should_fetch_all_keys() {
     56                add_site_meta( self::$site_id, 'foo', 'bar' );
     57                add_site_meta( self::$site_id, 'foo1', 'baz' );
     58
     59                $found = get_site_meta( self::$site_id );
     60                $expected = array(
     61                        'foo' => array( 'bar' ),
     62                        'foo1' => array( 'baz' ),
     63                );
     64
     65                $this->assertEqualSets( $expected, $found );
     66        }
     67
     68        public function test_get_with_key_should_fetch_all_for_key() {
     69                add_site_meta( self::$site_id, 'foo', 'bar' );
     70                add_site_meta( self::$site_id, 'foo', 'baz' );
     71                add_site_meta( self::$site_id, 'foo1', 'baz' );
     72
     73                $found = get_site_meta( self::$site_id, 'foo' );
     74                $expected = array( 'bar', 'baz' );
     75
     76                $this->assertEqualSets( $expected, $found );
     77        }
     78
     79        public function test_get_should_respect_single_true() {
     80                add_site_meta( self::$site_id, 'foo', 'bar' );
     81                add_site_meta( self::$site_id, 'foo', 'baz' );
     82
     83                $found = get_site_meta( self::$site_id, 'foo', true );
     84                $this->assertEquals( 'bar', $found );
     85        }
     86
     87        public function test_update_should_pass_to_add_when_no_value_exists_for_key() {
     88                $actual = update_site_meta( self::$site_id, 'foo', 'bar' );
     89                $this->assertInternalType( 'int', $actual );
     90                $this->assertNotEmpty( $actual );
     91
     92                $meta = get_site_meta( self::$site_id, 'foo', true );
     93                $this->assertSame( 'bar', $meta );
     94        }
     95
     96        public function test_update_should_return_true_when_updating_existing_value_for_key() {
     97                add_site_meta( self::$site_id, 'foo', 'bar' );
     98
     99                $actual = update_site_meta( self::$site_id, 'foo', 'baz' );
     100                $this->assertTrue( $actual );
     101
     102                $meta = get_site_meta( self::$site_id, 'foo', true );
     103                $this->assertSame( 'baz', $meta );
     104        }
     105
     106        public function test_delete_by_key() {
     107                add_site_meta( self::$site_id, 'unique_delete_by_key', 'value', true );
     108                add_site_meta( self::$site_id2, 'unique_delete_by_key', 'value', true );
     109
     110                $this->assertEquals( 'value', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     111                $this->assertEquals( 'value', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     112
     113                $this->assertTrue( delete_site_meta_by_key( 'unique_delete_by_key' ) );
     114
     115                $this->assertEquals( '', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) );
     116                $this->assertEquals( '', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) );
     117        }
     118
     119        public function test_adding_site_meta_should_bust_get_sites_cache() {
     120                add_site_meta( self::$site_id, 'foo', 'bar' );
     121
     122                // Prime cache.
     123                $found = get_sites( array(
     124                        'fields' => 'ids',
     125                        'meta_query' => array(
     126                                array(
     127                                        'key' => 'foo',
     128                                        'value' => 'bar',
     129                                ),
     130                        ),
     131                ) );
     132
     133                $this->assertEqualSets( array( self::$site_id ), $found );
     134
     135                add_site_meta( self::$site_id2, 'foo', 'bar' );
     136
     137                $found = get_sites( array(
     138                        'fields' => 'ids',
     139                        'meta_query' => array(
     140                                array(
     141                                        'key' => 'foo',
     142                                        'value' => 'bar',
     143                                ),
     144                        ),
     145                ) );
     146
     147                $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found );
     148        }
     149
     150        public function test_updating_site_meta_should_bust_get_sites_cache() {
     151                add_site_meta( self::$site_id, 'foo', 'bar' );
     152                add_site_meta( self::$site_id2, 'foo', 'baz' );
     153
     154                // Prime cache.
     155                $found = get_sites( array(
     156                        'fields' => 'ids',
     157                        'meta_query' => array(
     158                                array(
     159                                        'key' => 'foo',
     160                                        'value' => 'bar',
     161                                ),
     162                        ),
     163                ) );
     164
     165                $this->assertEqualSets( array( self::$site_id ), $found );
     166
     167                update_site_meta( self::$site_id2, 'foo', 'bar' );
     168
     169                $found = get_sites( array(
     170                        'fields' => 'ids',
     171                        'meta_query' => array(
     172                                array(
     173                                        'key' => 'foo',
     174                                        'value' => 'bar',
     175                                ),
     176                        ),
     177                ) );
     178
     179                $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found );
     180        }
     181
     182        public function test_deleting_site_meta_should_bust_get_sites_cache() {
     183                add_site_meta( self::$site_id, 'foo', 'bar' );
     184                add_site_meta( self::$site_id2, 'foo', 'bar' );
     185
     186                // Prime cache.
     187                $found = get_sites( array(
     188                        'fields' => 'ids',
     189                        'meta_query' => array(
     190                                array(
     191                                        'key' => 'foo',
     192                                        'value' => 'bar',
     193                                ),
     194                        ),
     195                ) );
     196
     197                $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found );
     198
     199                delete_site_meta( self::$site_id2, 'foo', 'bar' );
     200
     201                $found = get_sites( array(
     202                        'fields' => 'ids',
     203                        'meta_query' => array(
     204                                array(
     205                                        'key' => 'foo',
     206                                        'value' => 'bar',
     207                                ),
     208                        ),
     209                ) );
     210
     211                $this->assertEqualSets( array( self::$site_id ), $found );
     212        }
     213
     214        public function test_site_meta_should_be_deleted_when_site_is_deleted() {
     215                $site_id = self::factory()->blog->create( array( 'domain' => 'foo.org', 'path' => '/' ) );
     216
     217                add_site_meta( $site_id, 'foo', 'bar' );
     218                add_site_meta( $site_id, 'foo1', 'bar' );
     219
     220                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo', true ) );
     221                $this->assertSame( 'bar', get_site_meta( $site_id, 'foo1', true ) );
     222
     223                wpmu_delete_blog( $site_id, true );
     224
     225                $this->assertSame( '', get_site_meta( $site_id, 'foo', true ) );
     226                $this->assertSame( '', get_site_meta( $site_id, 'foo1', true ) );
     227        }
     228}
     229
     230endif;