WordPress.org

Make WordPress Core

Ticket #37923: 37923.diff

File 37923.diff, 35.1 KB (added by flixos90, 8 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;