Ticket #37923: 37923-phase1.diff
File 37923-phase1.diff, 39.9 KB (added by , 8 years ago) |
---|
-
src/wp-admin/includes/ms.php
127 127 $wpdb->query( "DROP TABLE IF EXISTS `$table`" ); 128 128 } 129 129 130 if ( is_site_meta_supported() ) { 131 $blog_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->blogmeta WHERE blog_id = %d ", $blog_id ) ); 132 foreach ( $blog_meta_ids as $mid ) { 133 delete_metadata_by_mid( 'blog', $mid ); 134 } 135 } 136 130 137 $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) ); 131 138 132 139 /** -
src/wp-admin/includes/schema.php
265 265 PRIMARY KEY (blog_id), 266 266 KEY db_version (db_version) 267 267 ) $charset_collate; 268 CREATE 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; 268 277 CREATE TABLE $wpdb->registration_log ( 269 278 ID bigint(20) NOT NULL auto_increment, 270 279 email varchar(255) NOT NULL default '', -
src/wp-includes/class-wp-site-query.php
42 42 ); 43 43 44 44 /** 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 /** 45 63 * Date query container. 46 64 * 47 65 * @since 4.6.0 … … 99 117 * Sets up the site query, based on the query vars passed. 100 118 * 101 119 * @since 4.6.0 120 * @since 4.8.0 Introduced the `update_site_meta_cache`, `meta_query`, `meta_key`, 121 * `meta_value`, `meta_type` and `meta_compare` parameters. 102 122 * @access public 103 123 * 104 124 * @param string|array $query { 105 125 * Optional. Array or query string of site query parameters. Default empty. 106 126 * 107 * @type array $site__in Array of site IDs to include. Default empty. 108 * @type array $site__not_in Array of site IDs to exclude. Default empty. 109 * @type bool $count Whether to return a site count (true) or array of site objects. 110 * Default false. 111 * @type array $date_query Date query clauses to limit sites by. See WP_Date_Query. 112 * Default null. 113 * @type string $fields Site fields to return. Accepts 'ids' (returns an array of site IDs) 114 * or empty (returns an array of complete site objects). Default empty. 115 * @type int $ID A site ID to only return that site. Default empty. 116 * @type int $number Maximum number of sites to retrieve. Default 100. 117 * @type int $offset Number of sites to offset the query. Used to build LIMIT clause. 118 * Default 0. 119 * @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true. 120 * @type string|array $orderby Site status or array of statuses. Accepts 'id', 'domain', 'path', 121 * 'network_id', 'last_updated', 'registered', 'domain_length', 122 * 'path_length', 'site__in' and 'network__in'. Also accepts false, 123 * an empty array, or 'none' to disable `ORDER BY` clause. 124 * Default 'id'. 125 * @type string $order How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'. 126 * @type int $network_id Limit results to those affiliated with a given network ID. If 0, 127 * include all networks. Default 0. 128 * @type array $network__in Array of network IDs to include affiliated sites for. Default empty. 129 * @type array $network__not_in Array of network IDs to exclude affiliated sites for. Default empty. 130 * @type string $domain Limit results to those affiliated with a given domain. Default empty. 131 * @type array $domain__in Array of domains to include affiliated sites for. Default empty. 132 * @type array $domain__not_in Array of domains to exclude affiliated sites for. Default empty. 133 * @type string $path Limit results to those affiliated with a given path. Default empty. 134 * @type array $path__in Array of paths to include affiliated sites for. Default empty. 135 * @type array $path__not_in Array of paths to exclude affiliated sites for. Default empty. 136 * @type int $public Limit results to public sites. Accepts '1' or '0'. Default empty. 137 * @type int $archived Limit results to archived sites. Accepts '1' or '0'. Default empty. 138 * @type int $mature Limit results to mature sites. Accepts '1' or '0'. Default empty. 139 * @type int $spam Limit results to spam sites. Accepts '1' or '0'. Default empty. 140 * @type int $deleted Limit results to deleted sites. Accepts '1' or '0'. Default empty. 141 * @type string $search Search term(s) to retrieve matching sites for. Default empty. 142 * @type array $search_columns Array of column names to be searched. Accepts 'domain' and 'path'. 143 * Default empty array. 144 * @type bool $update_site_cache Whether to prime the cache for found sites. Default false. 127 * @type array $site__in Array of site IDs to include. Default empty. 128 * @type array $site__not_in Array of site IDs to exclude. Default empty. 129 * @type bool $count Whether to return a site count (true) or array of site objects. 130 * Default false. 131 * @type array $date_query Date query clauses to limit sites by. See WP_Date_Query. 132 * Default null. 133 * @type string $fields Site fields to return. Accepts 'ids' (returns an array of site IDs) 134 * or empty (returns an array of complete site objects). Default empty. 135 * @type int $ID A site ID to only return that site. Default empty. 136 * @type int $number Maximum number of sites to retrieve. Default 100. 137 * @type int $offset Number of sites to offset the query. Used to build LIMIT clause. 138 * Default 0. 139 * @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true. 140 * @type string|array $orderby Site status or array of statuses. Accepts 'id', 'domain', 'path', 141 * 'network_id', 'last_updated', 'registered', 'domain_length', 142 * 'path_length', 'site__in' and 'network__in'. Also accepts false, 143 * an empty array, or 'none' to disable `ORDER BY` clause. 144 * Default 'id'. 145 * @type string $order How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'. 146 * @type int $network_id Limit results to those affiliated with a given network ID. If 0, 147 * include all networks. Default 0. 148 * @type array $network__in Array of network IDs to include affiliated sites for. Default empty. 149 * @type array $network__not_in Array of network IDs to exclude affiliated sites for. Default empty. 150 * @type string $domain Limit results to those affiliated with a given domain. Default empty. 151 * @type array $domain__in Array of domains to include affiliated sites for. Default empty. 152 * @type array $domain__not_in Array of domains to exclude affiliated sites for. Default empty. 153 * @type string $path Limit results to those affiliated with a given path. Default empty. 154 * @type array $path__in Array of paths to include affiliated sites for. Default empty. 155 * @type array $path__not_in Array of paths to exclude affiliated sites for. Default empty. 156 * @type int $public Limit results to public sites. Accepts '1' or '0'. Default empty. 157 * @type int $archived Limit results to archived sites. Accepts '1' or '0'. Default empty. 158 * @type int $mature Limit results to mature sites. Accepts '1' or '0'. Default empty. 159 * @type int $spam Limit results to spam sites. Accepts '1' or '0'. Default empty. 160 * @type int $deleted Limit results to deleted sites. Accepts '1' or '0'. Default empty. 161 * @type string $search Search term(s) to retrieve matching sites for. Default empty. 162 * @type array $search_columns Array of column names to be searched. Accepts 'domain' and 'path'. 163 * Default empty array. 164 * @type bool $update_site_cache Whether to prime the cache for found sites. Default false. 165 * @type bool $update_site_meta_cache Whether to prime meta caches for matched sites. Default true. 166 * @type array $meta_query Optional. Meta query clauses to limit retrieved sites by. 167 * See `WP_Meta_Query`. Default empty. 168 * @type string $meta_key Limit sites to those matching a specific metadata key. 169 * Can be used in conjunction with `$meta_value`. Default empty. 170 * @type string $meta_value Limit sites to those matching a specific metadata value. 171 * Usually used in conjunction with `$meta_key`. Default empty. 172 * @type string $meta_type Type of object metadata is for (e.g., comment, post, or user). 173 * Default empty. 174 * @type string $meta_compare Comparison operator to test the 'meta_value'. Default empty. 145 175 * } 146 176 */ 147 177 public function __construct( $query = '' ) { 148 178 $this->query_var_defaults = array( 149 'fields' => '', 150 'ID' => '', 151 'site__in' => '', 152 'site__not_in' => '', 153 'number' => 100, 154 'offset' => '', 155 'no_found_rows' => true, 156 'orderby' => 'id', 157 'order' => 'ASC', 158 'network_id' => 0, 159 'network__in' => '', 160 'network__not_in' => '', 161 'domain' => '', 162 'domain__in' => '', 163 'domain__not_in' => '', 164 'path' => '', 165 'path__in' => '', 166 'path__not_in' => '', 167 'public' => null, 168 'archived' => null, 169 'mature' => null, 170 'spam' => null, 171 'deleted' => null, 172 'search' => '', 173 'search_columns' => array(), 174 'count' => false, 175 'date_query' => null, // See WP_Date_Query 176 'update_site_cache' => true, 179 'fields' => '', 180 'ID' => '', 181 'site__in' => '', 182 'site__not_in' => '', 183 'number' => 100, 184 'offset' => '', 185 'no_found_rows' => true, 186 'orderby' => 'id', 187 'order' => 'ASC', 188 'network_id' => 0, 189 'network__in' => '', 190 'network__not_in' => '', 191 'domain' => '', 192 'domain__in' => '', 193 'domain__not_in' => '', 194 'path' => '', 195 'path__in' => '', 196 'path__not_in' => '', 197 'public' => null, 198 'archived' => null, 199 'mature' => null, 200 'spam' => null, 201 'deleted' => null, 202 'search' => '', 203 'search_columns' => array(), 204 'count' => false, 205 'date_query' => null, // See WP_Date_Query 206 'update_site_cache' => true, 207 'update_site_meta_cache' => true, 208 'meta_query' => '', 209 'meta_key' => '', 210 'meta_value' => '', 211 'meta_type' => '', 212 'meta_compare' => '', 177 213 ); 178 214 179 215 if ( ! empty( $query ) ) { … … 229 265 * @since 4.6.0 230 266 * @access public 231 267 * 268 * @global wpdb $wpdb WordPress database abstraction object. 269 * 232 270 * @return array|int List of sites, or number of sites when 'count' is passed as a query var. 233 271 */ 234 272 public function get_sites() { 273 global $wpdb; 274 235 275 $this->parse_query(); 236 276 277 // Set up meta_query so it's available to 'pre_get_sites'. 278 if ( class_exists( 'WP_Meta_Query' ) ) { 279 $this->meta_query = new WP_Meta_Query(); 280 $this->meta_query->parse_query_vars( $this->query_vars ); 281 } 282 237 283 /** 238 284 * Fires before sites are retrieved. 239 285 * … … 243 289 */ 244 290 do_action_ref_array( 'pre_get_sites', array( &$this ) ); 245 291 292 // Reparse query vars, in case they were modified in a 'pre_get_comments' callback. 293 if ( $this->meta_query ) { 294 $this->meta_query->parse_query_vars( $this->query_vars ); 295 if ( is_site_meta_supported() && ! empty( $this->meta_query->queries ) ) { 296 $this->meta_query_clauses = $this->meta_query->get_sql( 'blog', $wpdb->blogs, 'blog_id', $this ); 297 } 298 } 299 246 300 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 247 301 $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) ); 248 302 $last_changed = wp_cache_get_last_changed( 'sites' ); … … 286 340 287 341 // Prime site network caches. 288 342 if ( $this->query_vars['update_site_cache'] ) { 289 _prime_site_caches( $site_ids ); 343 if ( $this->meta_query ) { 344 _prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] ); 345 } else { 346 _prime_site_caches( $site_ids, false ); 347 } 290 348 } 291 349 292 350 // Fetch full site objects from the primed cache. … … 366 424 367 425 $orderby = implode( ', ', $orderby_array ); 368 426 } else { 369 $orderby = " blog_id $order";427 $orderby = "$wpdb->blogs.blog_id $order"; 370 428 } 371 429 372 430 $number = absint( $this->query_vars['number'] ); … … 383 441 if ( $this->query_vars['count'] ) { 384 442 $fields = 'COUNT(*)'; 385 443 } else { 386 $fields = 'blog_id';444 $fields = "$wpdb->blogs.blog_id"; 387 445 } 388 446 389 447 // Parse site IDs for an IN clause. 390 448 $site_id = absint( $this->query_vars['ID'] ); 391 449 if ( ! empty( $site_id ) ) { 392 $this->sql_clauses['where']['ID'] = $wpdb->prepare( 'blog_id = %d', $site_id );450 $this->sql_clauses['where']['ID'] = $wpdb->prepare( "$wpdb->blogs.blog_id = %d", $site_id ); 393 451 } 394 452 395 453 // Parse site IDs for an IN clause. 396 454 if ( ! empty( $this->query_vars['site__in'] ) ) { 397 $this->sql_clauses['where']['site__in'] = " blog_id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__in'] ) ) . ' )';455 $this->sql_clauses['where']['site__in'] = "$wpdb->blogs.blog_id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__in'] ) ) . ' )'; 398 456 } 399 457 400 458 // Parse site IDs for a NOT IN clause. 401 459 if ( ! empty( $this->query_vars['site__not_in'] ) ) { 402 $this->sql_clauses['where']['site__not_in'] = " blog_id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__not_in'] ) ) . ' )';460 $this->sql_clauses['where']['site__not_in'] = "$wpdb->blogs.blog_id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__not_in'] ) ) . ' )'; 403 461 } 404 462 405 463 $network_id = absint( $this->query_vars['network_id'] ); … … 507 565 508 566 $join = ''; 509 567 568 if ( ! empty( $this->meta_query_clauses ) ) { 569 $join .= $this->meta_query_clauses['join']; 570 571 // Strip leading 'AND'. 572 $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] ); 573 574 if ( ! $this->query_vars['count'] ) { 575 $groupby = "{$wpdb->blogs}.blog_id"; 576 } 577 } 578 510 579 $where = implode( ' AND ', $this->sql_clauses['where'] ); 511 580 512 581 $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); … … 659 728 $parsed = 'CHAR_LENGTH(path)'; 660 729 break; 661 730 case 'id': 662 $parsed = 'blog_id';731 $parsed = "$wpdb->blogs.blog_id"; 663 732 break; 664 733 } 665 734 735 if ( ! $parsed && is_site_meta_supported() && $this->meta_query ) { 736 switch ( $orderby ) { 737 case $this->query_vars['meta_key']: 738 case 'meta_value': 739 $parsed = "$wpdb->blogmeta.meta_value"; 740 break; 741 case 'meta_value_num': 742 $parsed = "$wpdb->blogmeta.meta_value+0"; 743 break; 744 default: 745 $meta_query_clauses = $this->meta_query->get_clauses(); 746 if ( $meta_query_clauses && isset( $meta_query_clauses[ $orderby ] ) ) { 747 $meta_clause = $meta_query_clauses[ $orderby ]; 748 $parsed = sprintf( "CAST(%s.meta_value AS %s)", esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) ); 749 } 750 } 751 } 752 666 753 return $parsed; 667 754 } 668 755 -
src/wp-includes/load.php
515 515 } 516 516 517 517 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', 'site-lookup', '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', 'site-lookup', 'blog-lookup', 'blog-details', 'site-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'blog_meta' ) ); 519 519 wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); 520 520 } 521 521 } -
src/wp-includes/ms-blogs.php
457 457 wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' ); 458 458 wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' ); 459 459 wp_cache_delete( $domain_path_key, 'blog-id-cache' ); 460 wp_cache_delete( $blog_id, 'blog_meta' ); 460 461 461 462 /** 462 463 * Fires immediately after a site has been removed from the object cache. … … 534 535 * Adds any sites from the given ids to the cache that do not already exist in cache. 535 536 * 536 537 * @since 4.6.0 538 * @since 4.8.0 The $update_meta_cache parameter was added. 537 539 * @access private 538 540 * 539 541 * @see update_site_cache() 542 * @see update_sitemeta_cache() 543 * 540 544 * @global wpdb $wpdb WordPress database abstraction object. 541 545 * 542 * @param array $ids ID list. 546 * @param array $ids ID list. 547 * @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true. 543 548 */ 544 function _prime_site_caches( $ids ) {549 function _prime_site_caches( $ids, $update_meta_cache = true ) { 545 550 global $wpdb; 546 551 547 552 $non_cached_ids = _get_non_cached_ids( $ids, 'sites' ); … … 549 554 $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) ); 550 555 551 556 update_site_cache( $fresh_sites ); 557 558 if ( $update_meta_cache ) { 559 update_sitemeta_cache( $non_cached_ids ); 560 } 552 561 } 553 562 } 554 563 … … 571 580 } 572 581 573 582 /** 583 * Updates metadata cache for list of site IDs. 584 * 585 * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache. 586 * Subsequent calls to `get_site_meta()` will not need to query the database. 587 * 588 * @since 4.8.0 589 * 590 * @param array $site_ids List of site IDs. 591 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success. 592 */ 593 function update_sitemeta_cache( $site_ids ) { 594 // Bail if site meta table is not installed. 595 if ( ! is_site_meta_supported() ) { 596 return; 597 } 598 599 return update_meta_cache( 'blog', $site_ids ); 600 } 601 602 /** 574 603 * Retrieves a list of sites matching requested arguments. 575 604 * 576 605 * @since 4.6.0 … … 628 657 } 629 658 630 659 /** 660 * Add meta data field to a site. 661 * 662 * Site meta data is called "Custom Fields" on the Administration Screen. 663 * 664 * @since 4.8.0 665 * 666 * @param int $site_id Site ID. 667 * @param string $meta_key Metadata name. 668 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. 669 * @param bool $unique Optional. Whether the same key should not be added. 670 * Default false. 671 * @return int|false Meta ID on success, false on failure. 672 */ 673 function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) { 674 if ( ! is_site_meta_supported() || is_core_site_meta_key( $meta_key ) ) { 675 return false; 676 } 677 678 $added = add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique ); 679 680 // Bust site query cache. 681 if ( $added ) { 682 wp_cache_set( 'last_changed', microtime(), 'sites' ); 683 } 684 685 return $added; 686 } 687 688 /** 689 * Remove metadata matching criteria from a site. 690 * 691 * You can match based on the key, or key and value. Removing based on key and 692 * value, will keep from removing duplicate metadata with the same key. It also 693 * allows removing all metadata matching key, if needed. 694 * 695 * @since 4.8.0 696 * 697 * @param int $site_id Site ID. 698 * @param string $meta_key Metadata name. 699 * @param mixed $meta_value Optional. Metadata value. Must be serializable if 700 * non-scalar. Default empty. 701 * @return bool True on success, false on failure. 702 */ 703 function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) { 704 if ( ! is_site_meta_supported() || is_core_site_meta_key( $meta_key ) ) { 705 return false; 706 } 707 708 $deleted = delete_metadata( 'blog', $site_id, $meta_key, $meta_value ); 709 710 // Bust site query cache. 711 if ( $deleted ) { 712 wp_cache_set( 'last_changed', microtime(), 'sites' ); 713 } 714 715 return $deleted; 716 } 717 718 /** 719 * Retrieve site meta field for a site. 720 * 721 * @since 4.8.0 722 * 723 * @param int $site_id Site ID. 724 * @param string $key Optional. The meta key to retrieve. By default, returns 725 * data for all keys. Default empty. 726 * @param bool $single Optional. Whether to return a single value. Default false. 727 * @return mixed Will be an array if $single is false. Will be value of meta data 728 * field if $single is true. 729 */ 730 function get_site_meta( $site_id, $key = '', $single = false ) { 731 if ( ! is_site_meta_supported() ) { 732 if ( ! empty( $key ) && $single ) { 733 return ''; 734 } 735 736 return array(); 737 } 738 739 return get_metadata( 'blog', $site_id, $key, $single ); 740 } 741 742 /** 743 * Update site meta field based on site ID. 744 * 745 * Use the $prev_value parameter to differentiate between meta fields with the 746 * same key and site ID. 747 * 748 * If the meta field for the site does not exist, it will be added. 749 * 750 * @since 4.8.0 751 * 752 * @param int $site_id Site ID. 753 * @param string $meta_key Metadata key. 754 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. 755 * @param mixed $prev_value Optional. Previous value to check before removing. 756 * Default empty. 757 * @return int|bool Meta ID if the key didn't exist, true on successful update, 758 * false on failure. 759 */ 760 function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) { 761 if ( ! is_site_meta_supported() || is_core_site_meta_key( $meta_key ) ) { 762 return false; 763 } 764 765 $updated = update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value ); 766 767 // Bust site query cache. 768 if ( $updated ) { 769 wp_cache_set( 'last_changed', microtime(), 'sites' ); 770 } 771 772 return $updated; 773 } 774 775 /** 776 * Delete everything from site meta matching meta key. 777 * 778 * @since 4.8.0 779 * 780 * @param string $meta_key Metadata key to search for when deleting. 781 * @return bool Whether the site meta key was deleted from the database. 782 */ 783 function delete_site_meta_by_key( $meta_key ) { 784 if ( ! is_site_meta_supported() || is_core_site_meta_key( $meta_key ) ) { 785 return false; 786 } 787 788 return delete_metadata( 'blog', null, $meta_key, '', true ); 789 } 790 791 /** 792 * Returns whether a given site meta key is one of the core site meta keys. 793 * 794 * @since 4.8.0 795 * 796 * @param string $meta_key Metadata key to check. 797 * @return bool True if the metadata key is one of the core site meta keys, 798 * otherwise false. 799 */ 800 function is_core_site_meta_key( $meta_key ) { 801 return in_array( $meta_key, get_core_site_meta_keys(), true ); 802 } 803 804 /** 805 * Returns the list of core site meta keys. 806 * 807 * @since 4.8.0 808 * 809 * @return array Core site meta keys. 810 */ 811 function get_core_site_meta_keys() { 812 return array( 813 'blogname', 814 'siteurl', 815 'post_count', 816 'home', 817 'blog_public', 818 'WPLANG', 819 'blogdescription', 820 'admin_email', 821 'db_version' 822 ); 823 } 824 825 /** 826 * Returns whether site meta is supported by this installation. 827 * 828 * By default this depends on the database version, however site meta can 829 * optionally be disabled completely using the {@see 'site_meta_supported'} 830 * filter. 831 * 832 * @since 4.8.0 833 * 834 * @return bool True if site meta is supported, otherwise false. 835 */ 836 function is_site_meta_supported() { 837 $supported = get_option( 'db_version' ) >= 40000; 838 839 /** 840 * Filters whether site meta is supported by this installation. 841 * 842 * @since 4.8.0 843 * 844 * @param bool $supported Whether site meta is supported. 845 */ 846 return apply_filters( 'site_meta_supported', $supported ); 847 } 848 849 /** 631 850 * Retrieve option value for a given blog id based on name of option. 632 851 * 633 852 * If the option does not exist or does not have a value, then the return value … … 831 1050 if ( is_array( $global_groups ) ) { 832 1051 wp_cache_add_global_groups( $global_groups ); 833 1052 } else { 834 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );1053 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details', 'blog_meta' ) ); 835 1054 } 836 1055 wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); 837 1056 } … … 905 1124 if ( is_array( $global_groups ) ) { 906 1125 wp_cache_add_global_groups( $global_groups ); 907 1126 } else { 908 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );1127 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details', 'blog_meta' ) ); 909 1128 } 910 1129 wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); 911 1130 } -
src/wp-includes/version.php
11 11 * 12 12 * @global int $wp_db_version 13 13 */ 14 $wp_db_version = 38590;14 $wp_db_version = 40000; 15 15 16 16 /** 17 17 * Holds the TinyMCE version -
src/wp-includes/wp-db.php
298 298 * @see wpdb::tables() 299 299 * @var array 300 300 */ 301 var $ms_global_tables = array( 'blogs', ' signups', 'site', 'sitemeta',301 var $ms_global_tables = array( 'blogs', 'blogmeta', 'signups', 'site', 'sitemeta', 302 302 'sitecategories', 'registration_log', 'blog_versions' ); 303 303 304 304 /** … … 423 423 public $blogs; 424 424 425 425 /** 426 * Multisite Blog Metadata table 427 * 428 * @since 4.8.0 429 * @access public 430 * @var string 431 */ 432 public $blogmeta; 433 434 /** 426 435 * Multisite Blog Versions table 427 436 * 428 437 * @since 3.0.0 -
tests/phpunit/tests/multisite/siteMeta.php
1 <?php 2 3 if ( is_multisite() ) : 4 /** 5 * @group ms-site 6 * @group multisite 7 * @group meta 8 * @ticket 37923 9 */ 10 class 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 if ( ! is_site_meta_supported() ) { 28 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 29 } 30 31 $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) ); 32 } 33 34 public function test_add_unique() { 35 if ( ! is_site_meta_supported() ) { 36 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 37 } 38 39 $this->assertNotEmpty( add_site_meta( self::$site_id, 'foo', 'bar' ) ); 40 $this->assertFalse( add_site_meta( self::$site_id, 'foo', 'bar', true ) ); 41 } 42 43 public function test_delete() { 44 if ( ! is_site_meta_supported() ) { 45 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 46 } 47 48 add_site_meta( self::$site_id, 'foo', 'bar' ); 49 50 $this->assertTrue( delete_site_meta( self::$site_id, 'foo' ) ); 51 } 52 53 public function test_delete_with_invalid_meta_key_should_return_false() { 54 if ( ! is_site_meta_supported() ) { 55 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 56 } 57 58 $this->assertFalse( delete_site_meta( self::$site_id, 'foo' ) ); 59 } 60 61 public function test_delete_should_respect_meta_value() { 62 if ( ! is_site_meta_supported() ) { 63 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 64 } 65 66 add_site_meta( self::$site_id, 'foo', 'bar' ); 67 add_site_meta( self::$site_id, 'foo', 'baz' ); 68 69 $this->assertTrue( delete_site_meta( self::$site_id, 'foo', 'bar' ) ); 70 71 $metas = get_site_meta( self::$site_id, 'foo', false ); 72 $this->assertSame( array( 'baz' ), $metas ); 73 } 74 75 public function test_get_with_no_key_should_fetch_all_keys() { 76 if ( ! is_site_meta_supported() ) { 77 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 78 } 79 80 add_site_meta( self::$site_id, 'foo', 'bar' ); 81 add_site_meta( self::$site_id, 'foo1', 'baz' ); 82 83 $found = get_site_meta( self::$site_id ); 84 $expected = array( 85 'foo' => array( 'bar' ), 86 'foo1' => array( 'baz' ), 87 ); 88 89 $this->assertEqualSets( $expected, $found ); 90 } 91 92 public function test_get_with_key_should_fetch_all_for_key() { 93 if ( ! is_site_meta_supported() ) { 94 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 95 } 96 97 add_site_meta( self::$site_id, 'foo', 'bar' ); 98 add_site_meta( self::$site_id, 'foo', 'baz' ); 99 add_site_meta( self::$site_id, 'foo1', 'baz' ); 100 101 $found = get_site_meta( self::$site_id, 'foo' ); 102 $expected = array( 'bar', 'baz' ); 103 104 $this->assertEqualSets( $expected, $found ); 105 } 106 107 public function test_get_should_respect_single_true() { 108 if ( ! is_site_meta_supported() ) { 109 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 110 } 111 112 add_site_meta( self::$site_id, 'foo', 'bar' ); 113 add_site_meta( self::$site_id, 'foo', 'baz' ); 114 115 $found = get_site_meta( self::$site_id, 'foo', true ); 116 $this->assertEquals( 'bar', $found ); 117 } 118 119 public function test_update_should_pass_to_add_when_no_value_exists_for_key() { 120 if ( ! is_site_meta_supported() ) { 121 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 122 } 123 124 $actual = update_site_meta( self::$site_id, 'foo', 'bar' ); 125 $this->assertInternalType( 'int', $actual ); 126 $this->assertNotEmpty( $actual ); 127 128 $meta = get_site_meta( self::$site_id, 'foo', true ); 129 $this->assertSame( 'bar', $meta ); 130 } 131 132 public function test_update_should_return_true_when_updating_existing_value_for_key() { 133 if ( ! is_site_meta_supported() ) { 134 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 135 } 136 137 add_site_meta( self::$site_id, 'foo', 'bar' ); 138 139 $actual = update_site_meta( self::$site_id, 'foo', 'baz' ); 140 $this->assertTrue( $actual ); 141 142 $meta = get_site_meta( self::$site_id, 'foo', true ); 143 $this->assertSame( 'baz', $meta ); 144 } 145 146 public function test_delete_by_key() { 147 if ( ! is_site_meta_supported() ) { 148 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 149 } 150 151 add_site_meta( self::$site_id, 'unique_delete_by_key', 'value', true ); 152 add_site_meta( self::$site_id2, 'unique_delete_by_key', 'value', true ); 153 154 $this->assertEquals( 'value', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) ); 155 $this->assertEquals( 'value', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) ); 156 157 $this->assertTrue( delete_site_meta_by_key( 'unique_delete_by_key' ) ); 158 159 $this->assertEquals( '', get_site_meta( self::$site_id, 'unique_delete_by_key', true ) ); 160 $this->assertEquals( '', get_site_meta( self::$site_id2, 'unique_delete_by_key', true ) ); 161 } 162 163 /** 164 * @dataProvider data_get_core_keys 165 */ 166 public function test_add_fails_for_core_key( $key ) { 167 if ( ! is_site_meta_supported() ) { 168 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 169 } 170 171 $this->assertFalse( add_site_meta( self::$site_id, $key, 'foo' ) ); 172 } 173 174 /** 175 * @dataProvider data_get_core_keys 176 */ 177 public function test_update_fails_for_core_key( $key ) { 178 if ( ! is_site_meta_supported() ) { 179 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 180 } 181 182 $this->assertFalse( update_site_meta( self::$site_id, $key, 'foo' ) ); 183 } 184 185 /** 186 * @dataProvider data_get_core_keys 187 */ 188 public function test_delete_fails_for_core_key( $key ) { 189 if ( ! is_site_meta_supported() ) { 190 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 191 } 192 193 $this->assertFalse( delete_site_meta( self::$site_id, $key ) ); 194 } 195 196 /** 197 * @dataProvider data_get_core_keys 198 */ 199 public function test_delete_by_key_fails_for_core_key( $key ) { 200 if ( ! is_site_meta_supported() ) { 201 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 202 } 203 204 $this->assertFalse( delete_site_meta_by_key( $key ) ); 205 } 206 207 public function data_get_core_keys() { 208 return array( 209 array( 'blogname' ), 210 array( 'siteurl' ), 211 array( 'post_count' ), 212 array( 'home' ), 213 array( 'blog_public' ), 214 array( 'WPLANG' ), 215 array( 'blogdescription' ), 216 array( 'admin_email' ), 217 array( 'db_version' ), 218 ); 219 } 220 221 public function test_adding_site_meta_should_bust_get_sites_cache() { 222 if ( ! is_site_meta_supported() ) { 223 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 224 } 225 226 add_site_meta( self::$site_id, 'foo', 'bar' ); 227 228 // Prime cache. 229 $found = get_sites( array( 230 'fields' => 'ids', 231 'meta_query' => array( 232 array( 233 'key' => 'foo', 234 'value' => 'bar', 235 ), 236 ), 237 ) ); 238 239 $this->assertEqualSets( array( self::$site_id ), $found ); 240 241 add_site_meta( self::$site_id2, 'foo', 'bar' ); 242 243 $found = get_sites( array( 244 'fields' => 'ids', 245 'meta_query' => array( 246 array( 247 'key' => 'foo', 248 'value' => 'bar', 249 ), 250 ), 251 ) ); 252 253 $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found ); 254 } 255 256 public function test_updating_site_meta_should_bust_get_sites_cache() { 257 if ( ! is_site_meta_supported() ) { 258 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 259 } 260 261 add_site_meta( self::$site_id, 'foo', 'bar' ); 262 add_site_meta( self::$site_id2, 'foo', 'baz' ); 263 264 // Prime cache. 265 $found = get_sites( array( 266 'fields' => 'ids', 267 'meta_query' => array( 268 array( 269 'key' => 'foo', 270 'value' => 'bar', 271 ), 272 ), 273 ) ); 274 275 $this->assertEqualSets( array( self::$site_id ), $found ); 276 277 update_site_meta( self::$site_id2, 'foo', 'bar' ); 278 279 $found = get_sites( array( 280 'fields' => 'ids', 281 'meta_query' => array( 282 array( 283 'key' => 'foo', 284 'value' => 'bar', 285 ), 286 ), 287 ) ); 288 289 $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found ); 290 } 291 292 public function test_deleting_site_meta_should_bust_get_sites_cache() { 293 if ( ! is_site_meta_supported() ) { 294 $this->markTestSkipped( 'Test only runs when site meta is supported' ); 295 } 296 297 add_site_meta( self::$site_id, 'foo', 'bar' ); 298 add_site_meta( self::$site_id2, 'foo', 'bar' ); 299 300 // Prime cache. 301 $found = get_sites( array( 302 'fields' => 'ids', 303 'meta_query' => array( 304 array( 305 'key' => 'foo', 306 'value' => 'bar', 307 ), 308 ), 309 ) ); 310 311 $this->assertEqualSets( array( self::$site_id, self::$site_id2 ), $found ); 312 313 delete_site_meta( self::$site_id2, 'foo', 'bar' ); 314 315 $found = get_sites( array( 316 'fields' => 'ids', 317 'meta_query' => array( 318 array( 319 'key' => 'foo', 320 'value' => 'bar', 321 ), 322 ), 323 ) ); 324 325 $this->assertEqualSets( array( self::$site_id ), $found ); 326 } 327 328 public function test_get_sites_bypass_meta_query_without_site_meta_support() { 329 add_filter( 'site_meta_supported', '__return_false' ); 330 331 $found = get_sites( array( 332 'fields' => 'ids', 333 'domain' => 'wordpress.org', 334 'path' => '/', 335 'meta_query' => array( 336 array( 337 'key' => 'foo', 338 'value' => 'baz', 339 ), 340 ), 341 ) ); 342 343 remove_filter( 'site_meta_supported', '__return_false' ); 344 345 $this->assertEqualSets( array( self::$site_id ), $found ); 346 } 347 348 public function test_site_meta_should_be_deleted_when_term_is_deleted() { 349 $site_id = self::factory()->blog->create( array( 'domain' => 'foo.org', 'path' => '/' ) ); 350 351 add_site_meta( $site_id, 'foo', 'bar' ); 352 add_site_meta( $site_id, 'foo1', 'bar' ); 353 354 $this->assertSame( 'bar', get_site_meta( $site_id, 'foo', true ) ); 355 $this->assertSame( 'bar', get_site_meta( $site_id, 'foo1', true ) ); 356 357 wpmu_delete_blog( $site_id, true ); 358 359 $this->assertSame( '', get_site_meta( $site_id, 'foo', true ) ); 360 $this->assertSame( '', get_site_meta( $site_id, 'foo1', true ) ); 361 } 362 363 public function test_site_meta_supported() { 364 add_filter( 'site_meta_supported', '__return_false' ); 365 366 $result = is_site_meta_supported(); 367 368 remove_filter( 'site_meta_supported', '__return_false' ); 369 370 $this->assertFalse( $result ); 371 } 372 } 373 374 endif;