: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$GLOBALS['_wp_switched_stack'][] = $prev_blog_id;
* If we're switching to the same blog id that we're on,
* set the right vars, do the associated actions, but skip
* the extra unnecessary work
if ( $new_blog_id === $prev_blog_id ) {
* Fires when the blog is switched.
* @since 5.4.0 The `$context` parameter was added.
* @param int $new_blog_id New blog ID.
* @param int $prev_blog_id Previous blog ID.
* @param string $context Additional context. Accepts 'switch' when called from switch_to_blog()
* or 'restore' when called from restore_current_blog().
do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' );
$GLOBALS['switched'] = true;
$wpdb->set_blog_id( $new_blog_id );
$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
$GLOBALS['blog_id'] = $new_blog_id;
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
wp_cache_switch_to_blog( $new_blog_id );
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
$global_groups = $wp_object_cache->global_groups;
if ( function_exists( 'wp_cache_add_global_groups' ) ) {
if ( is_array( $global_groups ) ) {
wp_cache_add_global_groups( $global_groups );
wp_cache_add_global_groups(
wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) );
/** This filter is documented in wp-includes/ms-blogs.php */
do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' );
$GLOBALS['switched'] = true;
* Restores the current blog, after calling switch_to_blog().
* @global wpdb $wpdb WordPress database abstraction object.
* @global array $_wp_switched_stack
* @global string $table_prefix The database table prefix.
* @global WP_Object_Cache $wp_object_cache
* @return bool True on success, false if we're already on the current blog.
function restore_current_blog() {
if ( empty( $GLOBALS['_wp_switched_stack'] ) ) {
$new_blog_id = array_pop( $GLOBALS['_wp_switched_stack'] );
$prev_blog_id = get_current_blog_id();
if ( $new_blog_id === $prev_blog_id ) {
/** This filter is documented in wp-includes/ms-blogs.php */
do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'restore' );
// If we still have items in the switched stack, consider ourselves still 'switched'.
$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
$wpdb->set_blog_id( $new_blog_id );
$GLOBALS['blog_id'] = $new_blog_id;
$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
wp_cache_switch_to_blog( $new_blog_id );
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
$global_groups = $wp_object_cache->global_groups;
if ( function_exists( 'wp_cache_add_global_groups' ) ) {
if ( is_array( $global_groups ) ) {
wp_cache_add_global_groups( $global_groups );
wp_cache_add_global_groups(
wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) );
/** This filter is documented in wp-includes/ms-blogs.php */
do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'restore' );
// If we still have items in the switched stack, consider ourselves still 'switched'.
$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
* Switches the initialized roles and current user capabilities to another site.
* @param int $new_site_id New site ID.
* @param int $old_site_id Old site ID.
function wp_switch_roles_and_user( $new_site_id, $old_site_id ) {
if ( $new_site_id === $old_site_id ) {
if ( ! did_action( 'init' ) ) {
wp_roles()->for_site( $new_site_id );
wp_get_current_user()->for_site( $new_site_id );
* Determines if switch_to_blog() is in effect.
* @global array $_wp_switched_stack
* @return bool True if switched, false otherwise.
function ms_is_switched() {
return ! empty( $GLOBALS['_wp_switched_stack'] );
* Checks if a particular blog is archived.
* @param int $id Blog ID.
* @return string Whether the blog is archived or not.
function is_archived( $id ) {
return get_blog_status( $id, 'archived' );
* Updates the 'archived' status of a particular blog.
* @param int $id Blog ID.
* @param string $archived The new status.
* @return string $archived
function update_archived( $id, $archived ) {
update_blog_status( $id, 'archived', $archived );
* Updates a blog details field.
* @since 5.1.0 Use wp_update_site() internally.
* @global wpdb $wpdb WordPress database abstraction object.
* @param int $blog_id Blog ID.
* @param string $pref Field name.
* @param string $value Field value.
* @param null $deprecated Not used.
* @return string|false $value
function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
if ( null !== $deprecated ) {
_deprecated_argument( __FUNCTION__, '3.1.0' );
$allowed_field_names = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' );
if ( ! in_array( $pref, $allowed_field_names, true ) ) {
$result = wp_update_site(
if ( is_wp_error( $result ) ) {
* Gets a blog details field.
* @global wpdb $wpdb WordPress database abstraction object.
* @param int $id Blog ID.
* @param string $pref Field name.
* @return bool|string|null $value
function get_blog_status( $id, $pref ) {
$details = get_site( $id );
return $wpdb->get_var( $wpdb->prepare( "SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id ) );
* Gets a list of most recently updated blogs.
* @global wpdb $wpdb WordPress database abstraction object.
* @param mixed $deprecated Not used.
* @param int $start Optional. Number of blogs to offset the query. Used to build LIMIT clause.
* Can be used for pagination. Default 0.
* @param int $quantity Optional. The maximum number of blogs to retrieve. Default 40.
* @return array The list of blogs.
function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, 'MU' ); // Never used.
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 );
* Handler for updating the site's last updated date when a post is published or
* an already published post is changed.
* @param string $new_status The new post status.
* @param string $old_status The old post status.
* @param WP_Post $post Post object.
function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
$post_type_obj = get_post_type_object( $post->post_type );
if ( ! $post_type_obj || ! $post_type_obj->public ) {
if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
// Post was freshly published, published post was saved, or published post was unpublished.
wpmu_update_blogs_date();
* Handler for updating the current site's last updated date when a published
* @param int $post_id Post ID
function _update_blog_date_on_post_delete( $post_id ) {
$post = get_post( $post_id );
$post_type_obj = get_post_type_object( $post->post_type );
if ( ! $post_type_obj || ! $post_type_obj->public ) {
if ( 'publish' !== $post->post_status ) {
wpmu_update_blogs_date();
* Handler for updating the current site's posts count when a post is deleted.
* @since 6.2.0 Added the `$post` parameter.
* @param int $post_id Post ID.
* @param WP_Post $post Post object.
function _update_posts_count_on_delete( $post_id, $post ) {
if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) {
* Handler for updating the current site's posts count when a post status changes.
* @since 4.9.0 Added the `$post` parameter.
* @param string $new_status The status the post is changing to.
* @param string $old_status The status the post is changing from.
* @param WP_Post $post Post object
function _update_posts_count_on_transition_post_status( $new_status, $old_status, $post = null ) {
if ( $new_status === $old_status ) {
if ( 'post' !== get_post_type( $post ) ) {
if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
* Counts number of sites grouped by site status.
* @param int $network_id Optional. The network to get counts for. Default is the current network ID.
* Numbers of sites grouped by site status.
* @type int $all The total number of sites.
* @type int $public The number of public sites.
* @type int $archived The number of archived sites.
* @type int $mature The number of mature sites.
* @type int $spam The number of spam sites.
* @type int $deleted The number of deleted sites.
function wp_count_sites( $network_id = null ) {
if ( empty( $network_id ) ) {
$network_id = get_current_network_id();
'network_id' => $network_id,
'no_found_rows' => false,
$q = new WP_Site_Query( $args );
$counts['all'] = $q->found_sites;
$statuses = array( 'public', 'archived', 'mature', 'spam', 'deleted' );
foreach ( $statuses as $status ) {
$q = new WP_Site_Query( $_args );
$counts[ $status ] = $q->found_sites;