wp/wp-includes/ms-blogs.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     3 /**
     3 /**
     4  * Site/blog functions that work with the blogs table and related data.
     4  * Site/blog functions that work with the blogs table and related data.
     5  *
     5  *
     6  * @package WordPress
     6  * @package WordPress
     7  * @subpackage Multisite
     7  * @subpackage Multisite
     8  * @since MU
     8  * @since MU (3.0.0)
     9  */
     9  */
    10 
    10 
    11 /**
    11 /**
    12  * Update the last_updated field for the current blog.
    12  * Update the last_updated field for the current site.
    13  *
    13  *
    14  * @since MU
    14  * @since MU (3.0.0)
    15  */
    15  */
    16 function wpmu_update_blogs_date() {
    16 function wpmu_update_blogs_date() {
    17 	global $wpdb;
    17 	$site_id = get_current_blog_id();
    18 
    18 
    19 	update_blog_details( $wpdb->blogid, array('last_updated' => current_time('mysql', true)) );
    19 	update_blog_details( $site_id, array( 'last_updated' => current_time( 'mysql', true ) ) );
    20 	/**
    20 	/**
    21 	 * Fires after the blog details are updated.
    21 	 * Fires after the blog details are updated.
    22 	 *
    22 	 *
    23 	 * @since MU
    23 	 * @since MU (3.0.0)
    24 	 *
    24 	 *
    25 	 * @param int $blog_id Blog ID.
    25 	 * @param int $blog_id Site ID.
    26 	 */
    26 	 */
    27 	do_action( 'wpmu_blog_updated', $wpdb->blogid );
    27 	do_action( 'wpmu_blog_updated', $site_id );
    28 }
    28 }
    29 
    29 
    30 /**
    30 /**
    31  * Get a full blog URL, given a blog id.
    31  * Get a full blog URL, given a blog id.
    32  *
    32  *
    33  * @since MU
    33  * @since MU (3.0.0)
    34  *
    34  *
    35  * @param int $blog_id Blog ID
    35  * @param int $blog_id Blog ID
    36  * @return string Full URL of the blog if found. Empty string if not.
    36  * @return string Full URL of the blog if found. Empty string if not.
    37  */
    37  */
    38 function get_blogaddress_by_id( $blog_id ) {
    38 function get_blogaddress_by_id( $blog_id ) {
    39 	$bloginfo = get_blog_details( (int) $blog_id, false ); // only get bare details!
    39 	$bloginfo = get_site( (int) $blog_id );
    40 	return ( $bloginfo ) ? esc_url( 'http://' . $bloginfo->domain . $bloginfo->path ) : '';
    40 
       
    41 	if ( empty( $bloginfo ) ) {
       
    42 		return '';
       
    43 	}
       
    44 
       
    45 	$scheme = parse_url( $bloginfo->home, PHP_URL_SCHEME );
       
    46 	$scheme = empty( $scheme ) ? 'http' : $scheme;
       
    47 
       
    48 	return esc_url( $scheme . '://' . $bloginfo->domain . $bloginfo->path );
    41 }
    49 }
    42 
    50 
    43 /**
    51 /**
    44  * Get a full blog URL, given a blog name.
    52  * Get a full blog URL, given a blog name.
    45  *
    53  *
    46  * @since MU
    54  * @since MU (3.0.0)
    47  *
    55  *
    48  * @param string $blogname The (subdomain or directory) name
    56  * @param string $blogname The (subdomain or directory) name
    49  * @return string
    57  * @return string
    50  */
    58  */
    51 function get_blogaddress_by_name( $blogname ) {
    59 function get_blogaddress_by_name( $blogname ) {
    60 	}
    68 	}
    61 	return esc_url( $url . '/' );
    69 	return esc_url( $url . '/' );
    62 }
    70 }
    63 
    71 
    64 /**
    72 /**
    65  * Given a blog's (subdomain or directory) slug, retrieve its id.
    73  * Retrieves a sites ID given its (subdomain or directory) slug.
    66  *
    74  *
    67  * @since MU
    75  * @since MU (3.0.0)
    68  *
    76  * @since 4.7.0 Converted to use get_sites().
    69  * @param string $slug
    77  *
    70  * @return int A blog id
    78  * @param string $slug A site's slug.
       
    79  * @return int|null The site ID, or null if no site is found for the given slug.
    71  */
    80  */
    72 function get_id_from_blogname( $slug ) {
    81 function get_id_from_blogname( $slug ) {
    73 	global $wpdb;
    82 	$current_network = get_network();
    74 
       
    75 	$current_site = get_current_site();
       
    76 	$slug = trim( $slug, '/' );
    83 	$slug = trim( $slug, '/' );
    77 
    84 
    78 	$blog_id = wp_cache_get( 'get_id_from_blogname_' . $slug, 'blog-details' );
       
    79 	if ( $blog_id )
       
    80 		return $blog_id;
       
    81 
       
    82 	if ( is_subdomain_install() ) {
    85 	if ( is_subdomain_install() ) {
    83 		$domain = $slug . '.' . $current_site->domain;
    86 		$domain = $slug . '.' . preg_replace( '|^www\.|', '', $current_network->domain );
    84 		$path = $current_site->path;
    87 		$path = $current_network->path;
    85 	} else {
    88 	} else {
    86 		$domain = $current_site->domain;
    89 		$domain = $current_network->domain;
    87 		$path = $current_site->path . $slug . '/';
    90 		$path = $current_network->path . $slug . '/';
    88 	}
    91 	}
    89 
    92 
    90 	$blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) );
    93 	$site_ids = get_sites( array(
    91 	wp_cache_set( 'get_id_from_blogname_' . $slug, $blog_id, 'blog-details' );
    94 		'number' => 1,
    92 	return $blog_id;
    95 		'fields' => 'ids',
       
    96 		'domain' => $domain,
       
    97 		'path' => $path,
       
    98 	) );
       
    99 
       
   100 	if ( empty( $site_ids ) ) {
       
   101 		return null;
       
   102 	}
       
   103 
       
   104 	return array_shift( $site_ids );
    93 }
   105 }
    94 
   106 
    95 /**
   107 /**
    96  * Retrieve the details for a blog from the blogs table and blog options.
   108  * Retrieve the details for a blog from the blogs table and blog options.
    97  *
   109  *
    98  * @since MU
   110  * @since MU (3.0.0)
    99  *
   111  *
   100  * @param int|string|array $fields A blog ID, a blog slug, or an array of fields to query against. Optional. If not specified the current blog ID is used.
   112  * @global wpdb $wpdb WordPress database abstraction object.
   101  * @param bool $get_all Whether to retrieve all details or only the details in the blogs table. Default is true.
   113  *
   102  * @return object|false Blog details on success. False on failure.
   114  * @param int|string|array $fields  Optional. A blog ID, a blog slug, or an array of fields to query against.
       
   115  *                                  If not specified the current blog ID is used.
       
   116  * @param bool             $get_all Whether to retrieve all details or only the details in the blogs table.
       
   117  *                                  Default is true.
       
   118  * @return WP_Site|false Blog details on success. False on failure.
   103  */
   119  */
   104 function get_blog_details( $fields = null, $get_all = true ) {
   120 function get_blog_details( $fields = null, $get_all = true ) {
   105 	global $wpdb;
   121 	global $wpdb;
   106 
   122 
   107 	if ( is_array($fields ) ) {
   123 	if ( is_array($fields ) ) {
   192 			}
   208 			}
   193 		}
   209 		}
   194 	}
   210 	}
   195 
   211 
   196 	if ( empty($details) ) {
   212 	if ( empty($details) ) {
   197 		$details = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE blog_id = %d /* get_blog_details */", $blog_id ) );
   213 		$details = WP_Site::get_instance( $blog_id );
   198 		if ( ! $details ) {
   214 		if ( ! $details ) {
   199 			// Set the full cache.
   215 			// Set the full cache.
   200 			wp_cache_set( $blog_id, -1, 'blog-details' );
   216 			wp_cache_set( $blog_id, -1, 'blog-details' );
   201 			return false;
   217 			return false;
   202 		}
   218 		}
   203 	}
   219 	}
   204 
   220 
       
   221 	if ( ! $details instanceof WP_Site ) {
       
   222 		$details = new WP_Site( $details );
       
   223 	}
       
   224 
   205 	if ( ! $get_all ) {
   225 	if ( ! $get_all ) {
   206 		wp_cache_set( $blog_id . $all, $details, 'blog-details' );
   226 		wp_cache_set( $blog_id . $all, $details, 'blog-details' );
   207 		return $details;
   227 		return $details;
   208 	}
   228 	}
   209 
   229 
   210 	switch_to_blog( $blog_id );
   230 	switch_to_blog( $blog_id );
   211 	$details->blogname		= get_option( 'blogname' );
   231 	$details->blogname   = get_option( 'blogname' );
   212 	$details->siteurl		= get_option( 'siteurl' );
   232 	$details->siteurl    = get_option( 'siteurl' );
   213 	$details->post_count	= get_option( 'post_count' );
   233 	$details->post_count = get_option( 'post_count' );
       
   234 	$details->home       = get_option( 'home' );
   214 	restore_current_blog();
   235 	restore_current_blog();
   215 
   236 
   216 	/**
   237 	/**
   217 	 * Filter a blog's details.
   238 	 * Filters a blog's details.
   218 	 *
   239 	 *
   219 	 * @since MU
   240 	 * @since MU (3.0.0)
       
   241 	 * @deprecated 4.7.0 Use site_details
   220 	 *
   242 	 *
   221 	 * @param object $details The blog details.
   243 	 * @param object $details The blog details.
   222 	 */
   244 	 */
   223 	$details = apply_filters( 'blog_details', $details );
   245 	$details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' );
   224 
   246 
   225 	wp_cache_set( $blog_id . $all, $details, 'blog-details' );
   247 	wp_cache_set( $blog_id . $all, $details, 'blog-details' );
   226 
   248 
   227 	$key = md5( $details->domain . $details->path );
   249 	$key = md5( $details->domain . $details->path );
   228 	wp_cache_set( $key, $details, 'blog-lookup' );
   250 	wp_cache_set( $key, $details, 'blog-lookup' );
   231 }
   253 }
   232 
   254 
   233 /**
   255 /**
   234  * Clear the blog details cache.
   256  * Clear the blog details cache.
   235  *
   257  *
   236  * @since MU
   258  * @since MU (3.0.0)
   237  *
   259  *
   238  * @param int $blog_id Optional. Blog ID. Defaults to current blog.
   260  * @param int $blog_id Optional. Blog ID. Defaults to current blog.
   239  */
   261  */
   240 function refresh_blog_details( $blog_id = 0 ) {
   262 function refresh_blog_details( $blog_id = 0 ) {
   241 	$blog_id = (int) $blog_id;
   263 	$blog_id = (int) $blog_id;
   242 	if ( ! $blog_id ) {
   264 	if ( ! $blog_id ) {
   243 		$blog_id = get_current_blog_id();
   265 		$blog_id = get_current_blog_id();
   244 	}
   266 	}
   245 
   267 
   246 	$details = get_blog_details( $blog_id, false );
   268 	clean_blog_cache( $blog_id );
   247 	if ( ! $details ) {
       
   248 		// Make sure clean_blog_cache() gets the blog ID
       
   249 		// when the blog has been previously cached as
       
   250 		// non-existent.
       
   251 		$details = (object) array(
       
   252 			'blog_id' => $blog_id,
       
   253 			'domain' => null,
       
   254 			'path' => null
       
   255 		);
       
   256 	}
       
   257 
       
   258 	clean_blog_cache( $details );
       
   259 
       
   260 	/**
       
   261 	 * Fires after the blog details cache is cleared.
       
   262 	 *
       
   263 	 * @since 3.4.0
       
   264 	 *
       
   265 	 * @param int $blog_id Blog ID.
       
   266 	 */
       
   267 	do_action( 'refresh_blog_details', $blog_id );
       
   268 }
   269 }
   269 
   270 
   270 /**
   271 /**
   271  * Update the details for a blog. Updates the blogs table for a given blog id.
   272  * Update the details for a blog. Updates the blogs table for a given blog id.
   272  *
   273  *
   273  * @since MU
   274  * @since MU (3.0.0)
   274  *
   275  *
   275  * @param int $blog_id Blog ID
   276  * @global wpdb $wpdb WordPress database abstraction object.
       
   277  *
       
   278  * @param int   $blog_id Blog ID
   276  * @param array $details Array of details keyed by blogs table field names.
   279  * @param array $details Array of details keyed by blogs table field names.
   277  * @return bool True if update succeeds, false otherwise.
   280  * @return bool True if update succeeds, false otherwise.
   278  */
   281  */
   279 function update_blog_details( $blog_id, $details = array() ) {
   282 function update_blog_details( $blog_id, $details = array() ) {
   280 	global $wpdb;
   283 	global $wpdb;
   283 		return false;
   286 		return false;
   284 
   287 
   285 	if ( is_object($details) )
   288 	if ( is_object($details) )
   286 		$details = get_object_vars($details);
   289 		$details = get_object_vars($details);
   287 
   290 
   288 	$current_details = get_blog_details($blog_id, false);
   291 	$current_details = get_site( $blog_id );
   289 	if ( empty($current_details) )
   292 	if ( empty($current_details) )
   290 		return false;
   293 		return false;
   291 
   294 
   292 	$current_details = get_object_vars($current_details);
   295 	$current_details = get_object_vars($current_details);
   293 
   296 
   311 
   314 
   312 	// If spam status changed, issue actions.
   315 	// If spam status changed, issue actions.
   313 	if ( $details['spam'] != $current_details['spam'] ) {
   316 	if ( $details['spam'] != $current_details['spam'] ) {
   314 		if ( $details['spam'] == 1 ) {
   317 		if ( $details['spam'] == 1 ) {
   315 			/**
   318 			/**
   316 			 * Fires when the blog status is changed to 'spam'.
   319 			 * Fires when the 'spam' status is added to a blog.
   317 			 *
   320 			 *
   318 			 * @since MU
   321 			 * @since MU (3.0.0)
   319 			 *
   322 			 *
   320 			 * @param int $blog_id Blog ID.
   323 			 * @param int $blog_id Blog ID.
   321 			 */
   324 			 */
   322 			do_action( 'make_spam_blog', $blog_id );
   325 			do_action( 'make_spam_blog', $blog_id );
   323 		} else {
   326 		} else {
   324 			/**
   327 			/**
   325 			 * Fires when the blog status is changed to 'ham'.
   328 			 * Fires when the 'spam' status is removed from a blog.
   326 			 *
   329 			 *
   327 			 * @since MU
   330 			 * @since MU (3.0.0)
   328 			 *
   331 			 *
   329 			 * @param int $blog_id Blog ID.
   332 			 * @param int $blog_id Blog ID.
   330 			 */
   333 			 */
   331 			do_action( 'make_ham_blog', $blog_id );
   334 			do_action( 'make_ham_blog', $blog_id );
   332 		}
   335 		}
   334 
   337 
   335 	// If mature status changed, issue actions.
   338 	// If mature status changed, issue actions.
   336 	if ( $details['mature'] != $current_details['mature'] ) {
   339 	if ( $details['mature'] != $current_details['mature'] ) {
   337 		if ( $details['mature'] == 1 ) {
   340 		if ( $details['mature'] == 1 ) {
   338 			/**
   341 			/**
   339 			 * Fires when the blog status is changed to 'mature'.
   342 			 * Fires when the 'mature' status is added to a blog.
   340 			 *
   343 			 *
   341 			 * @since 3.1.0
   344 			 * @since 3.1.0
   342 			 *
   345 			 *
   343 			 * @param int $blog_id Blog ID.
   346 			 * @param int $blog_id Blog ID.
   344 			 */
   347 			 */
   345 			do_action( 'mature_blog', $blog_id );
   348 			do_action( 'mature_blog', $blog_id );
   346 		} else {
   349 		} else {
   347 			/**
   350 			/**
   348 			 * Fires when the blog status is changed to 'unmature'.
   351 			 * Fires when the 'mature' status is removed from a blog.
   349 			 *
   352 			 *
   350 			 * @since 3.1.0
   353 			 * @since 3.1.0
   351 			 *
   354 			 *
   352 			 * @param int $blog_id Blog ID.
   355 			 * @param int $blog_id Blog ID.
   353 			 */
   356 			 */
   357 
   360 
   358 	// If archived status changed, issue actions.
   361 	// If archived status changed, issue actions.
   359 	if ( $details['archived'] != $current_details['archived'] ) {
   362 	if ( $details['archived'] != $current_details['archived'] ) {
   360 		if ( $details['archived'] == 1 ) {
   363 		if ( $details['archived'] == 1 ) {
   361 			/**
   364 			/**
   362 			 * Fires when the blog status is changed to 'archived'.
   365 			 * Fires when the 'archived' status is added to a blog.
   363 			 *
   366 			 *
   364 			 * @since MU
   367 			 * @since MU (3.0.0)
   365 			 *
   368 			 *
   366 			 * @param int $blog_id Blog ID.
   369 			 * @param int $blog_id Blog ID.
   367 			 */
   370 			 */
   368 			do_action( 'archive_blog', $blog_id );
   371 			do_action( 'archive_blog', $blog_id );
   369 		} else {
   372 		} else {
   370 			/**
   373 			/**
   371 			 * Fires when the blog status is changed to 'unarchived'.
   374 			 * Fires when the 'archived' status is removed from a blog.
   372 			 *
   375 			 *
   373 			 * @since MU
   376 			 * @since MU (3.0.0)
   374 			 *
   377 			 *
   375 			 * @param int $blog_id Blog ID.
   378 			 * @param int $blog_id Blog ID.
   376 			 */
   379 			 */
   377 			do_action( 'unarchive_blog', $blog_id );
   380 			do_action( 'unarchive_blog', $blog_id );
   378 		}
   381 		}
   380 
   383 
   381 	// If deleted status changed, issue actions.
   384 	// If deleted status changed, issue actions.
   382 	if ( $details['deleted'] != $current_details['deleted'] ) {
   385 	if ( $details['deleted'] != $current_details['deleted'] ) {
   383 		if ( $details['deleted'] == 1 ) {
   386 		if ( $details['deleted'] == 1 ) {
   384 			/**
   387 			/**
   385 			 * Fires when the blog status is changed to 'deleted'.
   388 			 * Fires when the 'deleted' status is added to a blog.
   386 			 *
   389 			 *
   387 			 * @since 3.5.0
   390 			 * @since 3.5.0
   388 			 *
   391 			 *
   389 			 * @param int $blog_id Blog ID.
   392 			 * @param int $blog_id Blog ID.
   390 			 */
   393 			 */
   391 			do_action( 'make_delete_blog', $blog_id );
   394 			do_action( 'make_delete_blog', $blog_id );
   392 		} else {
   395 		} else {
   393 			/**
   396 			/**
   394 			 * Fires when the blog status is changed to 'undeleted'.
   397 			 * Fires when the 'deleted' status is removed from a blog.
   395 			 *
   398 			 *
   396 			 * @since 3.5.0
   399 			 * @since 3.5.0
   397 			 *
   400 			 *
   398 			 * @param int $blog_id Blog ID.
   401 			 * @param int $blog_id Blog ID.
   399 			 */
   402 			 */
   405 		switch_to_blog( $blog_id );
   408 		switch_to_blog( $blog_id );
   406 		update_option( 'blog_public', $details['public'] );
   409 		update_option( 'blog_public', $details['public'] );
   407 		restore_current_blog();
   410 		restore_current_blog();
   408 	}
   411 	}
   409 
   412 
   410 	refresh_blog_details($blog_id);
   413 	clean_blog_cache( $blog_id );
   411 
   414 
   412 	return true;
   415 	return true;
   413 }
   416 }
   414 
   417 
   415 /**
   418 /**
   416  * Clean the blog cache
   419  * Clean the blog cache
   417  *
   420  *
   418  * @since 3.5.0
   421  * @since 3.5.0
   419  *
   422  *
   420  * @param stdClass $blog The blog details as returned from get_blog_details()
   423  * @global bool $_wp_suspend_cache_invalidation
       
   424  *
       
   425  * @param WP_Site|int $blog The site object or ID to be cleared from cache.
   421  */
   426  */
   422 function clean_blog_cache( $blog ) {
   427 function clean_blog_cache( $blog ) {
       
   428 	global $_wp_suspend_cache_invalidation;
       
   429 
       
   430 	if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
       
   431 		return;
       
   432 	}
       
   433 
       
   434 	if ( empty( $blog ) ) {
       
   435 		return;
       
   436 	}
       
   437 
       
   438 	$blog_id = $blog;
       
   439 	$blog = get_site( $blog_id );
       
   440 	if ( ! $blog ) {
       
   441 		if ( ! is_numeric( $blog_id ) ) {
       
   442 			return;
       
   443 		}
       
   444 
       
   445 		// Make sure a WP_Site object exists even when the site has been deleted.
       
   446 		$blog = new WP_Site( (object) array(
       
   447 			'blog_id' => $blog_id,
       
   448 			'domain'  => null,
       
   449 			'path'    => null,
       
   450 		) );
       
   451 	}
       
   452 
   423 	$blog_id = $blog->blog_id;
   453 	$blog_id = $blog->blog_id;
   424 	$domain_path_key = md5( $blog->domain . $blog->path );
   454 	$domain_path_key = md5( $blog->domain . $blog->path );
   425 
   455 
   426 	wp_cache_delete( $blog_id , 'blog-details' );
   456 	wp_cache_delete( $blog_id, 'sites' );
       
   457 	wp_cache_delete( $blog_id, 'site-details' );
       
   458 	wp_cache_delete( $blog_id, 'blog-details' );
   427 	wp_cache_delete( $blog_id . 'short' , 'blog-details' );
   459 	wp_cache_delete( $blog_id . 'short' , 'blog-details' );
   428 	wp_cache_delete(  $domain_path_key, 'blog-lookup' );
   460 	wp_cache_delete( $domain_path_key, 'blog-lookup' );
       
   461 	wp_cache_delete( $domain_path_key, 'blog-id-cache' );
   429 	wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
   462 	wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
   430 	wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
   463 	wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
   431 	wp_cache_delete( 'get_id_from_blogname_' . trim( $blog->path, '/' ), 'blog-details' );
   464 
   432 	wp_cache_delete( $domain_path_key, 'blog-id-cache' );
   465 	/**
       
   466 	 * Fires immediately after a site has been removed from the object cache.
       
   467 	 *
       
   468 	 * @since 4.6.0
       
   469 	 *
       
   470 	 * @param int     $id              Blog ID.
       
   471 	 * @param WP_Site $blog            Site object.
       
   472 	 * @param string  $domain_path_key md5 hash of domain and path.
       
   473 	 */
       
   474 	do_action( 'clean_site_cache', $blog_id, $blog, $domain_path_key );
       
   475 
       
   476 	wp_cache_set( 'last_changed', microtime(), 'sites' );
       
   477 
       
   478 	/**
       
   479 	 * Fires after the blog details cache is cleared.
       
   480 	 *
       
   481 	 * @since 3.4.0
       
   482 	 * @deprecated 4.9.0 Use clean_site_cache
       
   483 	 *
       
   484 	 * @param int $blog_id Blog ID.
       
   485 	 */
       
   486 	do_action_deprecated( 'refresh_blog_details', array( $blog_id ), '4.9.0', 'clean_site_cache' );
       
   487 }
       
   488 
       
   489 /**
       
   490  * Cleans the site details cache for a site.
       
   491  *
       
   492  * @since 4.7.4
       
   493  *
       
   494  * @param int $site_id Optional. Site ID. Default is the current site ID.
       
   495  */
       
   496 function clean_site_details_cache( $site_id = 0 ) {
       
   497 	$site_id = (int) $site_id;
       
   498 	if ( ! $site_id ) {
       
   499 		$site_id = get_current_blog_id();
       
   500 	}
       
   501 
       
   502 	wp_cache_delete( $site_id, 'site-details' );
       
   503 	wp_cache_delete( $site_id, 'blog-details' );
       
   504 }
       
   505 
       
   506 /**
       
   507  * Retrieves site data given a site ID or site object.
       
   508  *
       
   509  * Site data will be cached and returned after being passed through a filter.
       
   510  * If the provided site is empty, the current site global will be used.
       
   511  *
       
   512  * @since 4.6.0
       
   513  *
       
   514  * @param WP_Site|int|null $site Optional. Site to retrieve. Default is the current site.
       
   515  * @return WP_Site|null The site object or null if not found.
       
   516  */
       
   517 function get_site( $site = null ) {
       
   518 	if ( empty( $site ) ) {
       
   519 		$site = get_current_blog_id();
       
   520 	}
       
   521 
       
   522 	if ( $site instanceof WP_Site ) {
       
   523 		$_site = $site;
       
   524 	} elseif ( is_object( $site ) ) {
       
   525 		$_site = new WP_Site( $site );
       
   526 	} else {
       
   527 		$_site = WP_Site::get_instance( $site );
       
   528 	}
       
   529 
       
   530 	if ( ! $_site ) {
       
   531 		return null;
       
   532 	}
       
   533 
       
   534 	/**
       
   535 	 * Fires after a site is retrieved.
       
   536 	 *
       
   537 	 * @since 4.6.0
       
   538 	 *
       
   539 	 * @param WP_Site $_site Site data.
       
   540 	 */
       
   541 	$_site = apply_filters( 'get_site', $_site );
       
   542 
       
   543 	return $_site;
       
   544 }
       
   545 
       
   546 /**
       
   547  * Adds any sites from the given ids to the cache that do not already exist in cache.
       
   548  *
       
   549  * @since 4.6.0
       
   550  * @access private
       
   551  *
       
   552  * @see update_site_cache()
       
   553  * @global wpdb $wpdb WordPress database abstraction object.
       
   554  *
       
   555  * @param array $ids ID list.
       
   556  */
       
   557 function _prime_site_caches( $ids ) {
       
   558 	global $wpdb;
       
   559 
       
   560 	$non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
       
   561 	if ( ! empty( $non_cached_ids ) ) {
       
   562 		$fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
       
   563 
       
   564 		update_site_cache( $fresh_sites );
       
   565 	}
       
   566 }
       
   567 
       
   568 /**
       
   569  * Updates sites in cache.
       
   570  *
       
   571  * @since 4.6.0
       
   572  *
       
   573  * @param array $sites Array of site objects.
       
   574  */
       
   575 function update_site_cache( $sites ) {
       
   576 	if ( ! $sites ) {
       
   577 		return;
       
   578 	}
       
   579 
       
   580 	foreach ( $sites as $site ) {
       
   581 		wp_cache_add( $site->blog_id, $site, 'sites' );
       
   582 		wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
       
   583 	}
       
   584 }
       
   585 
       
   586 /**
       
   587  * Retrieves a list of sites matching requested arguments.
       
   588  *
       
   589  * @since 4.6.0
       
   590  * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
       
   591  *
       
   592  * @see WP_Site_Query::parse_query()
       
   593  *
       
   594  * @param string|array $args {
       
   595  *     Optional. Array or query string of site query parameters. Default empty.
       
   596  *
       
   597  *     @type array        $site__in          Array of site IDs to include. Default empty.
       
   598  *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
       
   599  *     @type bool         $count             Whether to return a site count (true) or array of site objects.
       
   600  *                                           Default false.
       
   601  *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
       
   602  *                                           Default null.
       
   603  *     @type string       $fields            Site fields to return. Accepts 'ids' (returns an array of site IDs)
       
   604  *                                           or empty (returns an array of complete site objects). Default empty.
       
   605  *     @type int          $ID                A site ID to only return that site. Default empty.
       
   606  *     @type int          $number            Maximum number of sites to retrieve. Default 100.
       
   607  *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
       
   608  *                                           Default 0.
       
   609  *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
       
   610  *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
       
   611  *                                           'network_id', 'last_updated', 'registered', 'domain_length',
       
   612  *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
       
   613  *                                           an empty array, or 'none' to disable `ORDER BY` clause.
       
   614  *                                           Default 'id'.
       
   615  *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
       
   616  *     @type int          $network_id        Limit results to those affiliated with a given network ID. If 0,
       
   617  *                                           include all networks. Default 0.
       
   618  *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
       
   619  *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
       
   620  *     @type string       $domain            Limit results to those affiliated with a given domain. Default empty.
       
   621  *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
       
   622  *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
       
   623  *     @type string       $path              Limit results to those affiliated with a given path. Default empty.
       
   624  *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
       
   625  *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
       
   626  *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
       
   627  *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
       
   628  *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
       
   629  *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
       
   630  *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
       
   631  *     @type int          $lang_id           Limit results to a language ID. Default empty.
       
   632  *     @type array        $lang__in          Array of language IDs to include affiliated sites for. Default empty.
       
   633  *     @type array        $lang__not_in      Array of language IDs to exclude affiliated sites for. Default empty.
       
   634  *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
       
   635  *     @type array        $search_columns    Array of column names to be searched. Accepts 'domain' and 'path'.
       
   636  *                                           Default empty array.
       
   637  *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default true.
       
   638  * }
       
   639  * @return array|int List of WP_Site objects, a list of site ids when 'fields' is set to 'ids',
       
   640  *                   or the number of sites when 'count' is passed as a query var.
       
   641  */
       
   642 function get_sites( $args = array() ) {
       
   643 	$query = new WP_Site_Query();
       
   644 
       
   645 	return $query->query( $args );
   433 }
   646 }
   434 
   647 
   435 /**
   648 /**
   436  * Retrieve option value for a given blog id based on name of option.
   649  * Retrieve option value for a given blog id based on name of option.
   437  *
   650  *
   440  * and is commonly used during installation of plugin options and to test
   653  * and is commonly used during installation of plugin options and to test
   441  * whether upgrading is required.
   654  * whether upgrading is required.
   442  *
   655  *
   443  * If the option was serialized then it will be unserialized when it is returned.
   656  * If the option was serialized then it will be unserialized when it is returned.
   444  *
   657  *
   445  * @since MU
   658  * @since MU (3.0.0)
   446  *
   659  *
   447  * @param int $id A blog ID. Can be null to refer to the current blog.
   660  * @param int    $id      A blog ID. Can be null to refer to the current blog.
   448  * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
   661  * @param string $option  Name of option to retrieve. Expected to not be SQL-escaped.
   449  * @param mixed $default Optional. Default value to return if the option does not exist.
   662  * @param mixed  $default Optional. Default value to return if the option does not exist.
   450  * @return mixed Value set for the option.
   663  * @return mixed Value set for the option.
   451  */
   664  */
   452 function get_blog_option( $id, $option, $default = false ) {
   665 function get_blog_option( $id, $option, $default = false ) {
   453 	$id = (int) $id;
   666 	$id = (int) $id;
   454 
   667 
   461 	switch_to_blog( $id );
   674 	switch_to_blog( $id );
   462 	$value = get_option( $option, $default );
   675 	$value = get_option( $option, $default );
   463 	restore_current_blog();
   676 	restore_current_blog();
   464 
   677 
   465 	/**
   678 	/**
   466 	 * Filter a blog option value.
   679 	 * Filters a blog option value.
   467 	 *
   680 	 *
   468 	 * The dynamic portion of the hook name, `$option`, refers to the blog option name.
   681 	 * The dynamic portion of the hook name, `$option`, refers to the blog option name.
   469 	 *
   682 	 *
   470 	 * @since 3.5.0
   683 	 * @since 3.5.0
   471 	 *
   684 	 *
   485  * You can create options without values and then update the values later.
   698  * You can create options without values and then update the values later.
   486  * Existing options will not be updated and checks are performed to ensure that you
   699  * Existing options will not be updated and checks are performed to ensure that you
   487  * aren't adding a protected WordPress option. Care should be taken to not name
   700  * aren't adding a protected WordPress option. Care should be taken to not name
   488  * options the same as the ones which are protected.
   701  * options the same as the ones which are protected.
   489  *
   702  *
   490  * @since MU
   703  * @since MU (3.0.0)
   491  *
   704  *
   492  * @param int $id A blog ID. Can be null to refer to the current blog.
   705  * @param int    $id     A blog ID. Can be null to refer to the current blog.
   493  * @param string $option Name of option to add. Expected to not be SQL-escaped.
   706  * @param string $option Name of option to add. Expected to not be SQL-escaped.
   494  * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped.
   707  * @param mixed  $value  Optional. Option value, can be anything. Expected to not be SQL-escaped.
   495  * @return bool False if option was not added and true if option was added.
   708  * @return bool False if option was not added and true if option was added.
   496  */
   709  */
   497 function add_blog_option( $id, $option, $value ) {
   710 function add_blog_option( $id, $option, $value ) {
   498 	$id = (int) $id;
   711 	$id = (int) $id;
   499 
   712 
   511 }
   724 }
   512 
   725 
   513 /**
   726 /**
   514  * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
   727  * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
   515  *
   728  *
   516  * @since MU
   729  * @since MU (3.0.0)
   517  *
   730  *
   518  * @param int $id A blog ID. Can be null to refer to the current blog.
   731  * @param int    $id     A blog ID. Can be null to refer to the current blog.
   519  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
   732  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
   520  * @return bool True, if option is successfully deleted. False on failure.
   733  * @return bool True, if option is successfully deleted. False on failure.
   521  */
   734  */
   522 function delete_blog_option( $id, $option ) {
   735 function delete_blog_option( $id, $option ) {
   523 	$id = (int) $id;
   736 	$id = (int) $id;
   536 }
   749 }
   537 
   750 
   538 /**
   751 /**
   539  * Update an option for a particular blog.
   752  * Update an option for a particular blog.
   540  *
   753  *
   541  * @since MU
   754  * @since MU (3.0.0)
   542  *
   755  *
   543  * @param int $id The blog id
   756  * @param int    $id         The blog id.
   544  * @param string $option The option key
   757  * @param string $option     The option key.
   545  * @param mixed $value The option value
   758  * @param mixed  $value      The option value.
       
   759  * @param mixed  $deprecated Not used.
   546  * @return bool True on success, false on failure.
   760  * @return bool True on success, false on failure.
   547  */
   761  */
   548 function update_blog_option( $id, $option, $value, $deprecated = null ) {
   762 function update_blog_option( $id, $option, $value, $deprecated = null ) {
   549 	$id = (int) $id;
   763 	$id = (int) $id;
   550 
   764 
   551 	if ( null !== $deprecated  )
   765 	if ( null !== $deprecated  )
   552 		_deprecated_argument( __FUNCTION__, '3.1' );
   766 		_deprecated_argument( __FUNCTION__, '3.1.0' );
   553 
   767 
   554 	if ( get_current_blog_id() == $id )
   768 	if ( get_current_blog_id() == $id )
   555 		return update_option( $option, $value );
   769 		return update_option( $option, $value );
   556 
   770 
   557 	switch_to_blog( $id );
   771 	switch_to_blog( $id );
   558 	$return = update_option( $option, $value );
   772 	$return = update_option( $option, $value );
   559 	restore_current_blog();
   773 	restore_current_blog();
   560 
   774 
   561 	refresh_blog_details( $id );
       
   562 
       
   563 	return $return;
   775 	return $return;
   564 }
   776 }
   565 
   777 
   566 /**
   778 /**
   567  * Switch the current blog.
   779  * Switch the current blog.
   568  *
   780  *
   569  * This function is useful if you need to pull posts, or other information,
   781  * This function is useful if you need to pull posts, or other information,
   570  * from other blogs. You can switch back afterwards using restore_current_blog().
   782  * from other blogs. You can switch back afterwards using restore_current_blog().
   571  *
   783  *
   572  * Things that aren't switched:
   784  * Things that aren't switched:
   573  *  - autoloaded options. See #14992
       
   574  *  - plugins. See #14941
   785  *  - plugins. See #14941
   575  *
   786  *
   576  * @see restore_current_blog()
   787  * @see restore_current_blog()
   577  * @since MU
   788  * @since MU (3.0.0)
   578  *
   789  *
   579  * @param int $new_blog The id of the blog you want to switch to. Default: current blog
   790  * @global wpdb            $wpdb
       
   791  * @global int             $blog_id
       
   792  * @global array           $_wp_switched_stack
       
   793  * @global bool            $switched
       
   794  * @global string          $table_prefix
       
   795  * @global WP_Object_Cache $wp_object_cache
       
   796  *
       
   797  * @param int  $new_blog   The id of the blog you want to switch to. Default: current blog
   580  * @param bool $deprecated Deprecated argument
   798  * @param bool $deprecated Deprecated argument
   581  * @return bool Always returns True.
   799  * @return true Always returns True.
   582  */
   800  */
   583 function switch_to_blog( $new_blog, $deprecated = null ) {
   801 function switch_to_blog( $new_blog, $deprecated = null ) {
   584 	global $wpdb, $wp_roles;
   802 	global $wpdb;
   585 
   803 
   586 	if ( empty( $new_blog ) )
   804 	$blog_id = get_current_blog_id();
   587 		$new_blog = $GLOBALS['blog_id'];
   805 	if ( empty( $new_blog ) ) {
   588 
   806 		$new_blog = $blog_id;
   589 	$GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id'];
   807 	}
       
   808 
       
   809 	$GLOBALS['_wp_switched_stack'][] = $blog_id;
   590 
   810 
   591 	/*
   811 	/*
   592 	 * If we're switching to the same blog id that we're on,
   812 	 * If we're switching to the same blog id that we're on,
   593 	 * set the right vars, do the associated actions, but skip
   813 	 * set the right vars, do the associated actions, but skip
   594 	 * the extra unnecessary work
   814 	 * the extra unnecessary work
   595 	 */
   815 	 */
   596 	if ( $new_blog == $GLOBALS['blog_id'] ) {
   816 	if ( $new_blog == $blog_id ) {
   597 		/**
   817 		/**
   598 		 * Fires when the blog is switched.
   818 		 * Fires when the blog is switched.
   599 		 *
   819 		 *
   600 		 * @since MU
   820 		 * @since MU (3.0.0)
   601 		 *
   821 		 *
   602 		 * @param int $new_blog New blog ID.
   822 		 * @param int $new_blog New blog ID.
   603 		 * @param int $new_blog Blog ID.
   823 		 * @param int $new_blog Blog ID.
   604 		 */
   824 		 */
   605 		do_action( 'switch_blog', $new_blog, $new_blog );
   825 		do_action( 'switch_blog', $new_blog, $new_blog );
   607 		return true;
   827 		return true;
   608 	}
   828 	}
   609 
   829 
   610 	$wpdb->set_blog_id( $new_blog );
   830 	$wpdb->set_blog_id( $new_blog );
   611 	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
   831 	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
   612 	$prev_blog_id = $GLOBALS['blog_id'];
   832 	$prev_blog_id = $blog_id;
   613 	$GLOBALS['blog_id'] = $new_blog;
   833 	$GLOBALS['blog_id'] = $new_blog;
   614 
   834 
   615 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
   835 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
   616 		wp_cache_switch_to_blog( $new_blog );
   836 		wp_cache_switch_to_blog( $new_blog );
   617 	} else {
   837 	} else {
   618 		global $wp_object_cache;
   838 		global $wp_object_cache;
   619 
   839 
   620 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
   840 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
   621 			$global_groups = $wp_object_cache->global_groups;
   841 			$global_groups = $wp_object_cache->global_groups;
   622 		else
   842 		} else {
   623 			$global_groups = false;
   843 			$global_groups = false;
   624 
   844 		}
   625 		wp_cache_init();
   845 		wp_cache_init();
   626 
   846 
   627 		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
   847 		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
   628 			if ( is_array( $global_groups ) ) {
   848 			if ( is_array( $global_groups ) ) {
   629 				wp_cache_add_global_groups( $global_groups );
   849 				wp_cache_add_global_groups( $global_groups );
   630 			} else {
   850 			} else {
   631 				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' ) );
   851 				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' ) );
   632 			}
   852 			}
   633 			wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
   853 			wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
   634 		}
   854 		}
   635 	}
       
   636 
       
   637 	if ( did_action( 'init' ) ) {
       
   638 		$wp_roles->reinit();
       
   639 		$current_user = wp_get_current_user();
       
   640 		$current_user->for_blog( $new_blog );
       
   641 	}
   855 	}
   642 
   856 
   643 	/** This filter is documented in wp-includes/ms-blogs.php */
   857 	/** This filter is documented in wp-includes/ms-blogs.php */
   644 	do_action( 'switch_blog', $new_blog, $prev_blog_id );
   858 	do_action( 'switch_blog', $new_blog, $prev_blog_id );
   645 	$GLOBALS['switched'] = true;
   859 	$GLOBALS['switched'] = true;
   649 
   863 
   650 /**
   864 /**
   651  * Restore the current blog, after calling switch_to_blog()
   865  * Restore the current blog, after calling switch_to_blog()
   652  *
   866  *
   653  * @see switch_to_blog()
   867  * @see switch_to_blog()
   654  * @since MU
   868  * @since MU (3.0.0)
       
   869  *
       
   870  * @global wpdb            $wpdb
       
   871  * @global array           $_wp_switched_stack
       
   872  * @global int             $blog_id
       
   873  * @global bool            $switched
       
   874  * @global string          $table_prefix
       
   875  * @global WP_Object_Cache $wp_object_cache
   655  *
   876  *
   656  * @return bool True on success, false if we're already on the current blog
   877  * @return bool True on success, false if we're already on the current blog
   657  */
   878  */
   658 function restore_current_blog() {
   879 function restore_current_blog() {
   659 	global $wpdb, $wp_roles;
   880 	global $wpdb;
   660 
   881 
   661 	if ( empty( $GLOBALS['_wp_switched_stack'] ) )
   882 	if ( empty( $GLOBALS['_wp_switched_stack'] ) ) {
   662 		return false;
   883 		return false;
       
   884 	}
   663 
   885 
   664 	$blog = array_pop( $GLOBALS['_wp_switched_stack'] );
   886 	$blog = array_pop( $GLOBALS['_wp_switched_stack'] );
   665 
   887 	$blog_id = get_current_blog_id();
   666 	if ( $GLOBALS['blog_id'] == $blog ) {
   888 
       
   889 	if ( $blog_id == $blog ) {
   667 		/** This filter is documented in wp-includes/ms-blogs.php */
   890 		/** This filter is documented in wp-includes/ms-blogs.php */
   668 		do_action( 'switch_blog', $blog, $blog );
   891 		do_action( 'switch_blog', $blog, $blog );
   669 		// If we still have items in the switched stack, consider ourselves still 'switched'
   892 		// If we still have items in the switched stack, consider ourselves still 'switched'
   670 		$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
   893 		$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
   671 		return true;
   894 		return true;
   672 	}
   895 	}
   673 
   896 
   674 	$wpdb->set_blog_id( $blog );
   897 	$wpdb->set_blog_id( $blog );
   675 	$prev_blog_id = $GLOBALS['blog_id'];
   898 	$prev_blog_id = $blog_id;
   676 	$GLOBALS['blog_id'] = $blog;
   899 	$GLOBALS['blog_id'] = $blog;
   677 	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
   900 	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
   678 
   901 
   679 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
   902 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
   680 		wp_cache_switch_to_blog( $blog );
   903 		wp_cache_switch_to_blog( $blog );
   681 	} else {
   904 	} else {
   682 		global $wp_object_cache;
   905 		global $wp_object_cache;
   683 
   906 
   684 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
   907 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
   685 			$global_groups = $wp_object_cache->global_groups;
   908 			$global_groups = $wp_object_cache->global_groups;
   686 		else
   909 		} else {
   687 			$global_groups = false;
   910 			$global_groups = false;
       
   911 		}
   688 
   912 
   689 		wp_cache_init();
   913 		wp_cache_init();
   690 
   914 
   691 		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
   915 		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
   692 			if ( is_array( $global_groups ) ) {
   916 			if ( is_array( $global_groups ) ) {
   693 				wp_cache_add_global_groups( $global_groups );
   917 				wp_cache_add_global_groups( $global_groups );
   694 			} else {
   918 			} else {
   695 				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' ) );
   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' ) );
   696 			}
   920 			}
   697 			wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
   921 			wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
   698 		}
   922 		}
   699 	}
       
   700 
       
   701 	if ( did_action( 'init' ) ) {
       
   702 		$wp_roles->reinit();
       
   703 		$current_user = wp_get_current_user();
       
   704 		$current_user->for_blog( $blog );
       
   705 	}
   923 	}
   706 
   924 
   707 	/** This filter is documented in wp-includes/ms-blogs.php */
   925 	/** This filter is documented in wp-includes/ms-blogs.php */
   708 	do_action( 'switch_blog', $blog, $prev_blog_id );
   926 	do_action( 'switch_blog', $blog, $prev_blog_id );
   709 
   927 
   712 
   930 
   713 	return true;
   931 	return true;
   714 }
   932 }
   715 
   933 
   716 /**
   934 /**
       
   935  * Switches the initialized roles and current user capabilities to another site.
       
   936  *
       
   937  * @since 4.9.0
       
   938  *
       
   939  * @param int $new_site_id New site ID.
       
   940  * @param int $old_site_id Old site ID.
       
   941  */
       
   942 function wp_switch_roles_and_user( $new_site_id, $old_site_id ) {
       
   943 	if ( $new_site_id == $old_site_id ) {
       
   944 		return;
       
   945 	}
       
   946 
       
   947 	if ( ! did_action( 'init' ) ) {
       
   948 		return;
       
   949 	}
       
   950 
       
   951 	wp_roles()->for_site( $new_site_id );
       
   952 	wp_get_current_user()->for_site( $new_site_id );
       
   953 }
       
   954 
       
   955 /**
   717  * Determines if switch_to_blog() is in effect
   956  * Determines if switch_to_blog() is in effect
   718  *
   957  *
   719  * @since 3.5.0
   958  * @since 3.5.0
       
   959  *
       
   960  * @global array $_wp_switched_stack
   720  *
   961  *
   721  * @return bool True if switched, false otherwise.
   962  * @return bool True if switched, false otherwise.
   722  */
   963  */
   723 function ms_is_switched() {
   964 function ms_is_switched() {
   724 	return ! empty( $GLOBALS['_wp_switched_stack'] );
   965 	return ! empty( $GLOBALS['_wp_switched_stack'] );
   725 }
   966 }
   726 
   967 
   727 /**
   968 /**
   728  * Check if a particular blog is archived.
   969  * Check if a particular blog is archived.
   729  *
   970  *
   730  * @since MU
   971  * @since MU (3.0.0)
   731  *
   972  *
   732  * @param int $id The blog id
   973  * @param int $id The blog id
   733  * @return string Whether the blog is archived or not
   974  * @return string Whether the blog is archived or not
   734  */
   975  */
   735 function is_archived( $id ) {
   976 function is_archived( $id ) {
   737 }
   978 }
   738 
   979 
   739 /**
   980 /**
   740  * Update the 'archived' status of a particular blog.
   981  * Update the 'archived' status of a particular blog.
   741  *
   982  *
   742  * @since MU
   983  * @since MU (3.0.0)
   743  *
   984  *
   744  * @param int $id The blog id
   985  * @param int    $id       The blog id
   745  * @param string $archived The new status
   986  * @param string $archived The new status
   746  * @return string $archived
   987  * @return string $archived
   747  */
   988  */
   748 function update_archived( $id, $archived ) {
   989 function update_archived( $id, $archived ) {
   749 	update_blog_status($id, 'archived', $archived);
   990 	update_blog_status($id, 'archived', $archived);
   751 }
   992 }
   752 
   993 
   753 /**
   994 /**
   754  * Update a blog details field.
   995  * Update a blog details field.
   755  *
   996  *
   756  * @since MU
   997  * @since MU (3.0.0)
   757  *
   998  *
   758  * @param int $blog_id BLog ID
   999  * @global wpdb $wpdb WordPress database abstraction object.
   759  * @param string $pref A field name
  1000  *
   760  * @param string $value Value for $pref
  1001  * @param int    $blog_id BLog ID
   761  * @return string $value
  1002  * @param string $pref    A field name
       
  1003  * @param string $value   Value for $pref
       
  1004  * @param null   $deprecated
       
  1005  * @return string|false $value
   762  */
  1006  */
   763 function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
  1007 function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
   764 	global $wpdb;
  1008 	global $wpdb;
   765 
  1009 
   766 	if ( null !== $deprecated  )
  1010 	if ( null !== $deprecated  )
   767 		_deprecated_argument( __FUNCTION__, '3.1' );
  1011 		_deprecated_argument( __FUNCTION__, '3.1.0' );
   768 
  1012 
   769 	if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
  1013 	if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
   770 		return $value;
  1014 		return $value;
   771 
  1015 
   772 	$result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
  1016 	$result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
   773 
  1017 
   774 	if ( false === $result )
  1018 	if ( false === $result )
   775 		return false;
  1019 		return false;
   776 
  1020 
   777 	refresh_blog_details( $blog_id );
  1021 	clean_blog_cache( $blog_id );
   778 
  1022 
   779 	if ( 'spam' == $pref ) {
  1023 	if ( 'spam' == $pref ) {
   780 		if ( $value == 1 ) {
  1024 		if ( $value == 1 ) {
   781 			/** This filter is documented in wp-includes/ms-blogs.php */
  1025 			/** This filter is documented in wp-includes/ms-blogs.php */
   782 			do_action( 'make_spam_blog', $blog_id );
  1026 			do_action( 'make_spam_blog', $blog_id );
   810 		}
  1054 		}
   811 	} elseif ( 'public' == $pref ) {
  1055 	} elseif ( 'public' == $pref ) {
   812 		/**
  1056 		/**
   813 		 * Fires after the current blog's 'public' setting is updated.
  1057 		 * Fires after the current blog's 'public' setting is updated.
   814 		 *
  1058 		 *
   815 		 * @since MU
  1059 		 * @since MU (3.0.0)
   816 		 *
  1060 		 *
   817 		 * @param int    $blog_id Blog ID.
  1061 		 * @param int    $blog_id Blog ID.
   818 		 * @param string $value   The value of blog status.
  1062 		 * @param string $value   The value of blog status.
   819  		 */
  1063  		 */
   820 		do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
  1064 		do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
   824 }
  1068 }
   825 
  1069 
   826 /**
  1070 /**
   827  * Get a blog details field.
  1071  * Get a blog details field.
   828  *
  1072  *
   829  * @since MU
  1073  * @since MU (3.0.0)
   830  *
  1074  *
   831  * @param int $id The blog id
  1075  * @global wpdb $wpdb WordPress database abstraction object.
       
  1076  *
       
  1077  * @param int    $id   The blog id
   832  * @param string $pref A field name
  1078  * @param string $pref A field name
   833  * @return bool $value
  1079  * @return bool|string|null $value
   834  */
  1080  */
   835 function get_blog_status( $id, $pref ) {
  1081 function get_blog_status( $id, $pref ) {
   836 	global $wpdb;
  1082 	global $wpdb;
   837 
  1083 
   838 	$details = get_blog_details( $id, false );
  1084 	$details = get_site( $id );
   839 	if ( $details )
  1085 	if ( $details )
   840 		return $details->$pref;
  1086 		return $details->$pref;
   841 
  1087 
   842 	return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
  1088 	return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
   843 }
  1089 }
   844 
  1090 
   845 /**
  1091 /**
   846  * Get a list of most recently updated blogs.
  1092  * Get a list of most recently updated blogs.
   847  *
  1093  *
   848  * @since MU
  1094  * @since MU (3.0.0)
       
  1095  *
       
  1096  * @global wpdb $wpdb WordPress database abstraction object.
   849  *
  1097  *
   850  * @param mixed $deprecated Not used
  1098  * @param mixed $deprecated Not used
   851  * @param int $start The offset
  1099  * @param int   $start      The offset
   852  * @param int $quantity The maximum number of blogs to retrieve. Default is 40.
  1100  * @param int   $quantity   The maximum number of blogs to retrieve. Default is 40.
   853  * @return array The list of blogs
  1101  * @return array The list of blogs
   854  */
  1102  */
   855 function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
  1103 function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
   856 	global $wpdb;
  1104 	global $wpdb;
   857 
  1105 
   858 	if ( ! empty( $deprecated ) )
  1106 	if ( ! empty( $deprecated ) )
   859 		_deprecated_argument( __FUNCTION__, 'MU' ); // never used
  1107 		_deprecated_argument( __FUNCTION__, 'MU' ); // never used
   860 
  1108 
   861 	return $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", $wpdb->siteid, $start, $quantity ) , ARRAY_A );
  1109 	return $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", get_current_network_id(), $start, $quantity ), ARRAY_A );
   862 }
  1110 }
   863 
  1111 
   864 /**
  1112 /**
   865  * Handler for updating the blog date when a post is published or an already published post is changed.
  1113  * Retrieves a list of networks.
       
  1114  *
       
  1115  * @since 4.6.0
       
  1116  *
       
  1117  * @param string|array $args Optional. Array or string of arguments. See WP_Network_Query::parse_query()
       
  1118  *                           for information on accepted arguments. Default empty array.
       
  1119  * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids',
       
  1120  *                   or the number of networks when 'count' is passed as a query var.
       
  1121  */
       
  1122 function get_networks( $args = array() ) {
       
  1123 	$query = new WP_Network_Query();
       
  1124 
       
  1125 	return $query->query( $args );
       
  1126 }
       
  1127 
       
  1128 /**
       
  1129  * Retrieves network data given a network ID or network object.
       
  1130  *
       
  1131  * Network data will be cached and returned after being passed through a filter.
       
  1132  * If the provided network is empty, the current network global will be used.
       
  1133  *
       
  1134  * @since 4.6.0
       
  1135  *
       
  1136  * @global WP_Network $current_site
       
  1137  *
       
  1138  * @param WP_Network|int|null $network Optional. Network to retrieve. Default is the current network.
       
  1139  * @return WP_Network|null The network object or null if not found.
       
  1140  */
       
  1141 function get_network( $network = null ) {
       
  1142 	global $current_site;
       
  1143 	if ( empty( $network ) && isset( $current_site ) ) {
       
  1144 		$network = $current_site;
       
  1145 	}
       
  1146 
       
  1147 	if ( $network instanceof WP_Network ) {
       
  1148 		$_network = $network;
       
  1149 	} elseif ( is_object( $network ) ) {
       
  1150 		$_network = new WP_Network( $network );
       
  1151 	} else {
       
  1152 		$_network = WP_Network::get_instance( $network );
       
  1153 	}
       
  1154 
       
  1155 	if ( ! $_network ) {
       
  1156 		return null;
       
  1157 	}
       
  1158 
       
  1159 	/**
       
  1160 	 * Fires after a network is retrieved.
       
  1161 	 *
       
  1162 	 * @since 4.6.0
       
  1163 	 *
       
  1164 	 * @param WP_Network $_network Network data.
       
  1165 	 */
       
  1166 	$_network = apply_filters( 'get_network', $_network );
       
  1167 
       
  1168 	return $_network;
       
  1169 }
       
  1170 
       
  1171 /**
       
  1172  * Removes a network from the object cache.
       
  1173  *
       
  1174  * @since 4.6.0
       
  1175  *
       
  1176  * @global bool $_wp_suspend_cache_invalidation
       
  1177  *
       
  1178  * @param int|array $ids Network ID or an array of network IDs to remove from cache.
       
  1179  */
       
  1180 function clean_network_cache( $ids ) {
       
  1181 	global $_wp_suspend_cache_invalidation;
       
  1182 
       
  1183 	if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
       
  1184 		return;
       
  1185 	}
       
  1186 
       
  1187 	foreach ( (array) $ids as $id ) {
       
  1188 		wp_cache_delete( $id, 'networks' );
       
  1189 
       
  1190 		/**
       
  1191 		 * Fires immediately after a network has been removed from the object cache.
       
  1192 		 *
       
  1193 		 * @since 4.6.0
       
  1194 		 *
       
  1195 		 * @param int $id Network ID.
       
  1196 		 */
       
  1197 		do_action( 'clean_network_cache', $id );
       
  1198 	}
       
  1199 
       
  1200 	wp_cache_set( 'last_changed', microtime(), 'networks' );
       
  1201 }
       
  1202 
       
  1203 /**
       
  1204  * Updates the network cache of given networks.
       
  1205  *
       
  1206  * Will add the networks in $networks to the cache. If network ID already exists
       
  1207  * in the network cache then it will not be updated. The network is added to the
       
  1208  * cache using the network group with the key using the ID of the networks.
       
  1209  *
       
  1210  * @since 4.6.0
       
  1211  *
       
  1212  * @param array $networks Array of network row objects.
       
  1213  */
       
  1214 function update_network_cache( $networks ) {
       
  1215 	foreach ( (array) $networks as $network ) {
       
  1216 		wp_cache_add( $network->id, $network, 'networks' );
       
  1217 	}
       
  1218 }
       
  1219 
       
  1220 /**
       
  1221  * Adds any networks from the given IDs to the cache that do not already exist in cache.
       
  1222  *
       
  1223  * @since 4.6.0
       
  1224  * @access private
       
  1225  *
       
  1226  * @see update_network_cache()
       
  1227  * @global wpdb $wpdb WordPress database abstraction object.
       
  1228  *
       
  1229  * @param array $network_ids Array of network IDs.
       
  1230  */
       
  1231 function _prime_network_caches( $network_ids ) {
       
  1232 	global $wpdb;
       
  1233 
       
  1234 	$non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' );
       
  1235 	if ( !empty( $non_cached_ids ) ) {
       
  1236 		$fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
       
  1237 
       
  1238 		update_network_cache( $fresh_networks );
       
  1239 	}
       
  1240 }
       
  1241 
       
  1242 /**
       
  1243  * Handler for updating the site's last updated date when a post is published or
       
  1244  * an already published post is changed.
   866  *
  1245  *
   867  * @since 3.3.0
  1246  * @since 3.3.0
   868  *
  1247  *
   869  * @param string $new_status The new post status
  1248  * @param string $new_status The new post status
   870  * @param string $old_status The old post status
  1249  * @param string $old_status The old post status
   871  * @param object $post Post object
  1250  * @param object $post       Post object
   872  */
  1251  */
   873 function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
  1252 function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
   874 	$post_type_obj = get_post_type_object( $post->post_type );
  1253 	$post_type_obj = get_post_type_object( $post->post_type );
   875 	if ( ! $post_type_obj || ! $post_type_obj->public ) {
  1254 	if ( ! $post_type_obj || ! $post_type_obj->public ) {
   876 		return;
  1255 		return;
   884 
  1263 
   885 	wpmu_update_blogs_date();
  1264 	wpmu_update_blogs_date();
   886 }
  1265 }
   887 
  1266 
   888 /**
  1267 /**
   889  * Handler for updating the blog date when a published post is deleted.
  1268  * Handler for updating the current site's last updated date when a published
       
  1269  * post is deleted.
   890  *
  1270  *
   891  * @since 3.4.0
  1271  * @since 3.4.0
   892  *
  1272  *
   893  * @param int $post_id Post ID
  1273  * @param int $post_id Post ID
   894  */
  1274  */
   906 
  1286 
   907 	wpmu_update_blogs_date();
  1287 	wpmu_update_blogs_date();
   908 }
  1288 }
   909 
  1289 
   910 /**
  1290 /**
   911  * Handler for updating the blog posts count date when a post is deleted.
  1291  * Handler for updating the current site's posts count when a post is deleted.
   912  *
  1292  *
   913  * @since 4.0.0
  1293  * @since 4.0.0
   914  *
  1294  *
   915  * @param int $post_id Post ID.
  1295  * @param int $post_id Post ID.
   916  */
  1296  */
   917 function _update_posts_count_on_delete( $post_id ) {
  1297 function _update_posts_count_on_delete( $post_id ) {
   918 	$post = get_post( $post_id );
  1298 	$post = get_post( $post_id );
   919 
  1299 
   920 	if ( ! $post || 'publish' !== $post->post_status ) {
  1300 	if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) {
   921 		return;
  1301 		return;
   922 	}
  1302 	}
   923 
  1303 
   924 	update_posts_count();
  1304 	update_posts_count();
   925 }
  1305 }
   926 
  1306 
   927 /**
  1307 /**
   928  * Handler for updating the blog posts count date when a post status changes.
  1308  * Handler for updating the current site's posts count when a post status changes.
   929  *
  1309  *
   930  * @since 4.0.0
  1310  * @since 4.0.0
   931  *
  1311  * @since 4.9.0 Added the `$post` parameter.
   932  * @param string $new_status The status the post is changing to.
  1312  *
   933  * @param string $old_status The status the post is changing from.
  1313  * @param string  $new_status The status the post is changing to.
   934  */
  1314  * @param string  $old_status The status the post is changing from.
   935 function _update_posts_count_on_transition_post_status( $new_status, $old_status ) {
  1315  * @param WP_Post $post       Post object
       
  1316  */
       
  1317 function _update_posts_count_on_transition_post_status( $new_status, $old_status, $post = null ) {
   936 	if ( $new_status === $old_status ) {
  1318 	if ( $new_status === $old_status ) {
   937 		return;
  1319 		return;
   938 	}
  1320 	}
   939 
  1321 
       
  1322 	if ( 'post' !== get_post_type( $post ) ) {
       
  1323 		return;
       
  1324 	}
       
  1325 
   940 	if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
  1326 	if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
   941 		return;
  1327 		return;
   942 	}
  1328 	}
   943 
  1329 
   944 	update_posts_count();
  1330 	update_posts_count();
   945 }
  1331 }
   946