WordPress.org

Make WordPress Core

Ticket #40647: 40647.2.diff

File 40647.2.diff, 50.0 KB (added by flixos90, 17 months ago)
  • src/wp-includes/ms-blogs.php

     
    88 * @since MU (3.0.0)
    99 */
    1010
     11require_once( ABSPATH . WPINC . '/ms-site.php' );
     12require_once( ABSPATH . WPINC . '/ms-network.php' );
     13
    1114/**
    1215 * Update the last_updated field for the current site.
    1316 *
     
    231234
    232235        if ( ! $get_all ) {
    233236                wp_cache_set( $blog_id . $all, $details, 'blog-details' );
    234                 return $details;
    235         }
    236 
    237         switch_to_blog( $blog_id );
    238         $details->blogname   = get_option( 'blogname' );
    239         $details->siteurl    = get_option( 'siteurl' );
    240         $details->post_count = get_option( 'post_count' );
    241         $details->home       = get_option( 'home' );
    242         restore_current_blog();
    243 
    244         /**
    245          * Filters a blog's details.
    246          *
    247          * @since MU (3.0.0)
    248          * @deprecated 4.7.0 Use site_details
    249          *
    250          * @param object $details The blog details.
    251          */
    252         $details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' );
    253 
    254         wp_cache_set( $blog_id . $all, $details, 'blog-details' );
    255 
    256         $key = md5( $details->domain . $details->path );
    257         wp_cache_set( $key, $details, 'blog-lookup' );
    258 
    259         return $details;
    260 }
    261 
    262 /**
    263  * Clear the blog details cache.
    264  *
    265  * @since MU (3.0.0)
    266  *
    267  * @param int $blog_id Optional. Blog ID. Defaults to current blog.
    268  */
    269 function refresh_blog_details( $blog_id = 0 ) {
    270         $blog_id = (int) $blog_id;
    271         if ( ! $blog_id ) {
    272                 $blog_id = get_current_blog_id();
    273         }
    274 
    275         clean_blog_cache( $blog_id );
    276 }
    277 
    278 /**
    279  * Update the details for a blog. Updates the blogs table for a given blog id.
    280  *
    281  * @since MU (3.0.0)
    282  *
    283  * @global wpdb $wpdb WordPress database abstraction object.
    284  *
    285  * @param int   $blog_id Blog ID
    286  * @param array $details Array of details keyed by blogs table field names.
    287  * @return bool True if update succeeds, false otherwise.
    288  */
    289 function update_blog_details( $blog_id, $details = array() ) {
    290         global $wpdb;
    291 
    292         if ( empty( $details ) ) {
    293                 return false;
    294         }
    295 
    296         if ( is_object( $details ) ) {
    297                 $details = get_object_vars( $details );
    298         }
    299 
    300         $site = wp_update_site( $blog_id, $details );
    301 
    302         if ( is_wp_error( $site ) ) {
    303                 return false;
    304         }
    305 
    306         return true;
    307 }
    308 
    309 /**
    310  * Clean the blog cache
    311  *
    312  * @since 3.5.0
    313  *
    314  * @global bool $_wp_suspend_cache_invalidation
    315  *
    316  * @param WP_Site|int $blog The site object or ID to be cleared from cache.
    317  */
    318 function clean_blog_cache( $blog ) {
    319         global $_wp_suspend_cache_invalidation;
    320 
    321         if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
    322                 return;
    323         }
    324 
    325         if ( empty( $blog ) ) {
    326                 return;
    327         }
    328 
    329         $blog_id = $blog;
    330         $blog    = get_site( $blog_id );
    331         if ( ! $blog ) {
    332                 if ( ! is_numeric( $blog_id ) ) {
    333                         return;
    334                 }
    335 
    336                 // Make sure a WP_Site object exists even when the site has been deleted.
    337                 $blog = new WP_Site(
    338                         (object) array(
    339                                 'blog_id' => $blog_id,
    340                                 'domain'  => null,
    341                                 'path'    => null,
    342                         )
    343                 );
    344         }
    345 
    346         $blog_id         = $blog->blog_id;
    347         $domain_path_key = md5( $blog->domain . $blog->path );
    348 
    349         wp_cache_delete( $blog_id, 'sites' );
    350         wp_cache_delete( $blog_id, 'site-details' );
    351         wp_cache_delete( $blog_id, 'blog-details' );
    352         wp_cache_delete( $blog_id . 'short', 'blog-details' );
    353         wp_cache_delete( $domain_path_key, 'blog-lookup' );
    354         wp_cache_delete( $domain_path_key, 'blog-id-cache' );
    355         wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
    356         wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
    357         wp_cache_delete( $blog_id, 'blog_meta' );
    358 
    359         /**
    360          * Fires immediately after a site has been removed from the object cache.
    361          *
    362          * @since 4.6.0
    363          *
    364          * @param int     $id              Blog ID.
    365          * @param WP_Site $blog            Site object.
    366          * @param string  $domain_path_key md5 hash of domain and path.
    367          */
    368         do_action( 'clean_site_cache', $blog_id, $blog, $domain_path_key );
    369 
    370         wp_cache_set( 'last_changed', microtime(), 'sites' );
    371 
    372         /**
    373          * Fires after the blog details cache is cleared.
    374          *
    375          * @since 3.4.0
    376          * @deprecated 4.9.0 Use clean_site_cache
    377          *
    378          * @param int $blog_id Blog ID.
    379          */
    380         do_action_deprecated( 'refresh_blog_details', array( $blog_id ), '4.9.0', 'clean_site_cache' );
    381 }
    382 
    383 /**
    384  * Cleans the site details cache for a site.
    385  *
    386  * @since 4.7.4
    387  *
    388  * @param int $site_id Optional. Site ID. Default is the current site ID.
    389  */
    390 function clean_site_details_cache( $site_id = 0 ) {
    391         $site_id = (int) $site_id;
    392         if ( ! $site_id ) {
    393                 $site_id = get_current_blog_id();
    394         }
    395 
    396         wp_cache_delete( $site_id, 'site-details' );
    397         wp_cache_delete( $site_id, 'blog-details' );
    398 }
    399 
    400 /**
    401  * Inserts a new site into the database.
    402  *
    403  * @since 5.1.0
    404  *
    405  * @global wpdb $wpdb WordPress database abstraction object.
    406  *
    407  * @param array $data {
    408  *     Data for the new site that should be inserted.
    409  *
    410  *     @type string $domain       Site domain. Default empty string.
    411  *     @type string $path         Site path. Default '/'.
    412  *     @type int    $network_id   The site's network ID. Default is the current network ID.
    413  *     @type string $registered   When the site was registered, in SQL datetime format. Default is
    414  *                                the current time.
    415  *     @type string $last_updated When the site was last updated, in SQL datetime format. Default is
    416  *                                the value of $registered.
    417  *     @type int    $public       Whether the site is public. Default 1.
    418  *     @type int    $archived     Whether the site is archived. Default 0.
    419  *     @type int    $mature       Whether the site is mature. Default 0.
    420  *     @type int    $spam         Whether the site is spam. Default 0.
    421  *     @type int    $deleted      Whether the site is deleted. Default 0.
    422  *     @type int    $lang_id      The site's language ID. Currently unused. Default 0.
    423  * }
    424  * @return int|WP_Error The new site's ID on success, or error object on failure.
    425  */
    426 function wp_insert_site( array $data ) {
    427         global $wpdb;
    428 
    429         $now = current_time( 'mysql', true );
    430 
    431         $defaults = array(
    432                 'domain'       => '',
    433                 'path'         => '/',
    434                 'network_id'   => get_current_network_id(),
    435                 'registered'   => $now,
    436                 'last_updated' => $now,
    437                 'public'       => 1,
    438                 'archived'     => 0,
    439                 'mature'       => 0,
    440                 'spam'         => 0,
    441                 'deleted'      => 0,
    442                 'lang_id'      => 0,
    443         );
    444 
    445         // Extract the passed arguments that may be relevant for site initialization.
    446         $args = array_diff_key( $data, $defaults );
    447         if ( isset( $args['site_id'] ) ) {
    448                 unset( $args['site_id'] );
    449         }
    450 
    451         $data = wp_prepare_site_data( $data, $defaults );
    452         if ( is_wp_error( $data ) ) {
    453                 return $data;
    454         }
    455 
    456         if ( false === $wpdb->insert( $wpdb->blogs, $data ) ) {
    457                 return new WP_Error( 'db_insert_error', __( 'Could not insert site into the database.' ), $wpdb->last_error );
    458         }
    459 
    460         $new_site = get_site( $wpdb->insert_id );
    461 
    462         clean_blog_cache( $new_site );
    463 
    464         /**
    465          * Fires once a site has been inserted into the database.
    466          *
    467          * @since 5.1.0
    468          *
    469          * @param WP_Site $new_site New site object.
    470          */
    471         do_action( 'wp_insert_site', $new_site );
    472 
    473         /**
    474          * Fires when a site's initialization routine should be executed.
    475          *
    476          * @since 5.1.0
    477          *
    478          * @param WP_Site $new_site New site object.
    479          * @param array   $args     Arguments for the initialization.
    480          */
    481         do_action( 'wp_initialize_site', $new_site, $args );
    482 
    483         // Only compute extra hook parameters if the deprecated hook is actually in use.
    484         if ( has_action( 'wpmu_new_blog' ) ) {
    485                 $user_id = ! empty( $args['user_id'] ) ? $args['user_id'] : 0;
    486                 $meta    = ! empty( $args['options'] ) ? $args['options'] : array();
    487 
    488                 /**
    489                  * Fires immediately after a new site is created.
    490                  *
    491                  * @since MU (3.0.0)
    492                  * @deprecated 5.1.0 Use wp_insert_site
    493                  *
    494                  * @param int    $site_id    Site ID.
    495                  * @param int    $user_id    User ID.
    496                  * @param string $domain     Site domain.
    497                  * @param string $path       Site path.
    498                  * @param int    $network_id Network ID. Only relevant on multi-network installations.
    499                  * @param array  $meta       Meta data. Used to set initial site options.
    500                  */
    501                 do_action_deprecated( 'wpmu_new_blog', array( $new_site->id, $user_id, $new_site->domain, $new_site->path, $new_site->network_id, $meta ), '5.1.0', 'wp_insert_site' );
    502         }
    503 
    504         return (int) $new_site->id;
    505 }
    506 
    507 /**
    508  * Updates a site in the database.
    509  *
    510  * @since 5.1.0
    511  *
    512  * @global wpdb $wpdb WordPress database abstraction object.
    513  *
    514  * @param int   $site_id ID of the site that should be updated.
    515  * @param array $data    Site data to update. See {@see wp_insert_site()} for the list of supported keys.
    516  * @return int|WP_Error The updated site's ID on success, or error object on failure.
    517  */
    518 function wp_update_site( $site_id, array $data ) {
    519         global $wpdb;
    520 
    521         if ( empty( $site_id ) ) {
    522                 return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
    523         }
    524 
    525         $old_site = get_site( $site_id );
    526         if ( ! $old_site ) {
    527                 return new WP_Error( 'site_not_exist', __( 'Site does not exist.' ) );
    528         }
    529 
    530         $defaults                 = $old_site->to_array();
    531         $defaults['network_id']   = (int) $defaults['site_id'];
    532         $defaults['last_updated'] = current_time( 'mysql', true );
    533         unset( $defaults['blog_id'], $defaults['site_id'] );
    534 
    535         $data = wp_prepare_site_data( $data, $defaults, $old_site );
    536         if ( is_wp_error( $data ) ) {
    537                 return $data;
    538         }
    539 
    540         if ( false === $wpdb->update( $wpdb->blogs, $data, array( 'blog_id' => $old_site->id ) ) ) {
    541                 return new WP_Error( 'db_update_error', __( 'Could not update site in the database.' ), $wpdb->last_error );
    542         }
    543 
    544         clean_blog_cache( $old_site );
    545 
    546         $new_site = get_site( $old_site->id );
    547 
    548         /**
    549          * Fires once a site has been updated in the database.
    550          *
    551          * @since 5.1.0
    552          *
    553          * @param WP_Site $new_site New site object.
    554          * @param WP_Site $old_site Old site object.
    555          */
    556         do_action( 'wp_update_site', $new_site, $old_site );
    557 
    558         return (int) $new_site->id;
    559 }
    560 
    561 /**
    562  * Deletes a site from the database.
    563  *
    564  * @since 5.1.0
    565  *
    566  * @global wpdb $wpdb WordPress database abstraction object.
    567  *
    568  * @param int $site_id ID of the site that should be deleted.
    569  * @return WP_Site|WP_Error The deleted site object on success, or error object on failure.
    570  */
    571 function wp_delete_site( $site_id ) {
    572         global $wpdb;
    573 
    574         if ( empty( $site_id ) ) {
    575                 return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
    576         }
    577 
    578         $old_site = get_site( $site_id );
    579         if ( ! $old_site ) {
    580                 return new WP_Error( 'site_not_exist', __( 'Site does not exist.' ) );
    581         }
    582 
    583         $errors = new WP_Error();
    584 
    585         /**
    586          * Fires before a site should be deleted from the database.
    587          *
    588          * Plugins should amend the `$errors` object via its `WP_Error::add()` method. If any errors
    589          * are present, the site will not be deleted.
    590          *
    591          * @since 5.1.0
    592          *
    593          * @param WP_Error $errors   Error object to add validation errors to.
    594          * @param WP_Site  $old_site The site object to be deleted.
    595          */
    596         do_action( 'wp_validate_site_deletion', $errors, $old_site );
    597 
    598         if ( ! empty( $errors->errors ) ) {
    599                 return $errors;
    600         }
    601 
    602         /**
    603          * Fires before a site is deleted.
    604          *
    605          * @since MU (3.0.0)
    606          * @deprecated 5.1.0
    607          *
    608          * @param int  $site_id The site ID.
    609          * @param bool $drop    True if site's table should be dropped. Default is false.
    610          */
    611         do_action_deprecated( 'delete_blog', array( $old_site->id, true ), '5.1.0' );
    612 
    613         /**
    614          * Fires when a site's uninitialization routine should be executed.
    615          *
    616          * @since 5.1.0
    617          *
    618          * @param WP_Site $old_site Deleted site object.
    619          */
    620         do_action( 'wp_uninitialize_site', $old_site );
    621 
    622         if ( is_site_meta_supported() ) {
    623                 $blog_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->blogmeta WHERE blog_id = %d ", $old_site->id ) );
    624                 foreach ( $blog_meta_ids as $mid ) {
    625                         delete_metadata_by_mid( 'blog', $mid );
    626                 }
    627         }
    628 
    629         if ( false === $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $old_site->id ) ) ) {
    630                 return new WP_Error( 'db_delete_error', __( 'Could not delete site from the database.' ), $wpdb->last_error );
    631         }
    632 
    633         clean_blog_cache( $old_site );
    634 
    635         /**
    636          * Fires once a site has been deleted from the database.
    637          *
    638          * @since 5.1.0
    639          *
    640          * @param WP_Site $old_site Deleted site object.
    641          */
    642         do_action( 'wp_delete_site', $old_site );
    643 
    644         /**
    645          * Fires after the site is deleted from the network.
    646          *
    647          * @since 4.8.0
    648          * @deprecated 5.1.0
    649          *
    650          * @param int  $site_id The site ID.
    651          * @param bool $drop    True if site's tables should be dropped. Default is false.
    652          */
    653         do_action_deprecated( 'deleted_blog', array( $old_site->id, true ), '5.1.0' );
    654 
    655         return $old_site;
    656 }
    657 
    658 /**
    659  * Retrieves site data given a site ID or site object.
    660  *
    661  * Site data will be cached and returned after being passed through a filter.
    662  * If the provided site is empty, the current site global will be used.
    663  *
    664  * @since 4.6.0
    665  *
    666  * @param WP_Site|int|null $site Optional. Site to retrieve. Default is the current site.
    667  * @return WP_Site|null The site object or null if not found.
    668  */
    669 function get_site( $site = null ) {
    670         if ( empty( $site ) ) {
    671                 $site = get_current_blog_id();
    672         }
    673 
    674         if ( $site instanceof WP_Site ) {
    675                 $_site = $site;
    676         } elseif ( is_object( $site ) ) {
    677                 $_site = new WP_Site( $site );
    678         } else {
    679                 $_site = WP_Site::get_instance( $site );
    680         }
    681 
    682         if ( ! $_site ) {
    683                 return null;
    684         }
    685 
    686         /**
    687          * Fires after a site is retrieved.
    688          *
    689          * @since 4.6.0
    690          *
    691          * @param WP_Site $_site Site data.
    692          */
    693         $_site = apply_filters( 'get_site', $_site );
    694 
    695         return $_site;
    696 }
    697 
    698 /**
    699  * Adds any sites from the given ids to the cache that do not already exist in cache.
    700  *
    701  * @since 4.6.0
    702  * @since 5.1.0 Introduced the `$update_meta_cache` parameter.
    703  * @access private
    704  *
    705  * @see update_site_cache()
    706  * @global wpdb $wpdb WordPress database abstraction object.
    707  *
    708  * @param array $ids               ID list.
    709  * @param bool  $update_meta_cache Optional. Whether to update the meta cache. Default true.
    710  */
    711 function _prime_site_caches( $ids, $update_meta_cache = true ) {
    712         global $wpdb;
    713 
    714         $non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
    715         if ( ! empty( $non_cached_ids ) ) {
    716                 $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    717 
    718                 update_site_cache( $fresh_sites, $update_meta_cache );
    719         }
    720 }
    721 
    722 /**
    723  * Updates sites in cache.
    724  *
    725  * @since 4.6.0
    726  * @since 5.1.0 Introduced the `$update_meta_cache` parameter.
    727  *
    728  * @param array $sites             Array of site objects.
    729  * @param bool  $update_meta_cache Whether to update site meta cache. Default true.
    730  */
    731 function update_site_cache( $sites, $update_meta_cache = true ) {
    732         if ( ! $sites ) {
    733                 return;
    734         }
    735         $site_ids = array();
    736         foreach ( $sites as $site ) {
    737                 $site_ids[] = $site->blog_id;
    738                 wp_cache_add( $site->blog_id, $site, 'sites' );
    739                 wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
    740         }
    741 
    742         if ( $update_meta_cache ) {
    743                 update_sitemeta_cache( $site_ids );
    744         }
    745 }
    746 
    747 /**
    748  * Updates metadata cache for list of site IDs.
    749  *
    750  * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache.
    751  * Subsequent calls to `get_site_meta()` will not need to query the database.
    752  *
    753  * @since 5.1.0
    754  *
    755  * @param array $site_ids List of site IDs.
    756  * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
    757  */
    758 function update_sitemeta_cache( $site_ids ) {
    759         return update_meta_cache( 'blog', $site_ids );
    760 }
    761 
    762 /**
    763  * Retrieves a list of sites matching requested arguments.
    764  *
    765  * @since 4.6.0
    766  * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
    767  *
    768  * @see WP_Site_Query::parse_query()
    769  *
    770  * @param string|array $args {
    771  *     Optional. Array or query string of site query parameters. Default empty.
    772  *
    773  *     @type array        $site__in          Array of site IDs to include. Default empty.
    774  *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
    775  *     @type bool         $count             Whether to return a site count (true) or array of site objects.
    776  *                                           Default false.
    777  *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
    778  *                                           Default null.
    779  *     @type string       $fields            Site fields to return. Accepts 'ids' (returns an array of site IDs)
    780  *                                           or empty (returns an array of complete site objects). Default empty.
    781  *     @type int          $ID                A site ID to only return that site. Default empty.
    782  *     @type int          $number            Maximum number of sites to retrieve. Default 100.
    783  *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
    784  *                                           Default 0.
    785  *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
    786  *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
    787  *                                           'network_id', 'last_updated', 'registered', 'domain_length',
    788  *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
    789  *                                           an empty array, or 'none' to disable `ORDER BY` clause.
    790  *                                           Default 'id'.
    791  *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
    792  *     @type int          $network_id        Limit results to those affiliated with a given network ID. If 0,
    793  *                                           include all networks. Default 0.
    794  *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
    795  *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
    796  *     @type string       $domain            Limit results to those affiliated with a given domain. Default empty.
    797  *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
    798  *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
    799  *     @type string       $path              Limit results to those affiliated with a given path. Default empty.
    800  *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
    801  *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
    802  *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
    803  *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
    804  *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
    805  *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
    806  *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
    807  *     @type int          $lang_id           Limit results to a language ID. Default empty.
    808  *     @type array        $lang__in          Array of language IDs to include affiliated sites for. Default empty.
    809  *     @type array        $lang__not_in      Array of language IDs to exclude affiliated sites for. Default empty.
    810  *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
    811  *     @type array        $search_columns    Array of column names to be searched. Accepts 'domain' and 'path'.
    812  *                                           Default empty array.
    813  *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default true.
    814  * }
    815  * @return array|int List of WP_Site objects, a list of site ids when 'fields' is set to 'ids',
    816  *                   or the number of sites when 'count' is passed as a query var.
    817  */
    818 function get_sites( $args = array() ) {
    819         $query = new WP_Site_Query();
    820 
    821         return $query->query( $args );
    822 }
    823 
    824 /**
    825  * Prepares site data for insertion or update in the database.
    826  *
    827  * @since 5.1.0
    828  *
    829  * @param array        $data     Associative array of site data passed to the respective function.
    830  *                               See {@see wp_insert_site()} for the possibly included data.
    831  * @param array        $defaults Site data defaults to parse $data against.
    832  * @param WP_Site|null $old_site Optional. Old site object if an update, or null if an insertion.
    833  *                               Default null.
    834  * @return array|WP_Error Site data ready for a database transaction, or WP_Error in case a validation
    835  *                        error occurred.
    836  */
    837 function wp_prepare_site_data( $data, $defaults, $old_site = null ) {
    838 
    839         // Maintain backward-compatibility with `$site_id` as network ID.
    840         if ( isset( $data['site_id'] ) ) {
    841                 if ( ! empty( $data['site_id'] ) && empty( $data['network_id'] ) ) {
    842                         $data['network_id'] = $data['site_id'];
    843                 }
    844                 unset( $data['site_id'] );
    845         }
    846 
    847         /**
    848          * Filters passed site data in order to normalize it.
    849          *
    850          * @since 5.1.0
    851          *
    852          * @param array $data Associative array of site data passed to the respective function.
    853          *                    See {@see wp_insert_site()} for the possibly included data.
    854          */
    855         $data = apply_filters( 'wp_normalize_site_data', $data );
    856 
    857         $whitelist = array( 'domain', 'path', 'network_id', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' );
    858         $data      = array_intersect_key( wp_parse_args( $data, $defaults ), array_flip( $whitelist ) );
    859 
    860         $errors = new WP_Error();
    861 
    862         /**
    863          * Fires when data should be validated for a site prior to inserting or updating in the database.
    864          *
    865          * Plugins should amend the `$errors` object via its `WP_Error::add()` method.
    866          *
    867          * @since 5.1.0
    868          *
    869          * @param WP_Error     $errors   Error object to add validation errors to.
    870          * @param array        $data     Associative array of complete site data. See {@see wp_insert_site()}
    871          *                               for the included data.
    872          * @param WP_Site|null $old_site The old site object if the data belongs to a site being updated,
    873          *                               or null if it is a new site being inserted.
    874          */
    875         do_action( 'wp_validate_site_data', $errors, $data, $old_site );
    876 
    877         if ( ! empty( $errors->errors ) ) {
    878                 return $errors;
    879         }
    880 
    881         // Prepare for database.
    882         $data['site_id'] = $data['network_id'];
    883         unset( $data['network_id'] );
    884 
    885         return $data;
    886 }
    887 
    888 /**
    889  * Normalizes data for a site prior to inserting or updating in the database.
    890  *
    891  * @since 5.1.0
    892  *
    893  * @param array $data Associative array of site data passed to the respective function.
    894  *                    See {@see wp_insert_site()} for the possibly included data.
    895  * @return array Normalized site data.
    896  */
    897 function wp_normalize_site_data( $data ) {
    898         // Sanitize domain if passed.
    899         if ( array_key_exists( 'domain', $data ) ) {
    900                 $data['domain'] = trim( $data['domain'] );
    901                 $data['domain'] = preg_replace( '/\s+/', '', sanitize_user( $data['domain'], true ) );
    902                 if ( is_subdomain_install() ) {
    903                         $data['domain'] = str_replace( '@', '', $data['domain'] );
    904                 }
    905         }
    906 
    907         // Sanitize path if passed.
    908         if ( array_key_exists( 'path', $data ) ) {
    909                 $data['path'] = trailingslashit( '/' . trim( $data['path'], '/' ) );
    910         }
    911 
    912         // Sanitize network ID if passed.
    913         if ( array_key_exists( 'network_id', $data ) ) {
    914                 $data['network_id'] = (int) $data['network_id'];
    915         }
    916 
    917         // Sanitize status fields if passed.
    918         $status_fields = array( 'public', 'archived', 'mature', 'spam', 'deleted' );
    919         foreach ( $status_fields as $status_field ) {
    920                 if ( array_key_exists( $status_field, $data ) ) {
    921                         $data[ $status_field ] = (int) $data[ $status_field ];
    922                 }
    923         }
    924 
    925         // Strip date fields if empty.
    926         $date_fields = array( 'registered', 'last_updated' );
    927         foreach ( $date_fields as $date_field ) {
    928                 if ( ! array_key_exists( $date_field, $data ) ) {
    929                         continue;
    930                 }
    931 
    932                 if ( empty( $data[ $date_field ] ) || '0000-00-00 00:00:00' === $data[ $date_field ] ) {
    933                         unset( $data[ $date_field ] );
    934                 }
    935         }
    936 
    937         return $data;
    938 }
    939 
    940 /**
    941  * Validates data for a site prior to inserting or updating in the database.
    942  *
    943  * @since 5.1.0
    944  *
    945  * @param WP_Error     $errors   Error object, passed by reference. Will contain validation errors if
    946  *                               any occurred.
    947  * @param array        $data     Associative array of complete site data. See {@see wp_insert_site()}
    948  *                               for the included data.
    949  * @param WP_Site|null $old_site The old site object if the data belongs to a site being updated,
    950  *                               or null if it is a new site being inserted.
    951  */
    952 function wp_validate_site_data( $errors, $data, $old_site = null ) {
    953         // A domain must always be present.
    954         if ( empty( $data['domain'] ) ) {
    955                 $errors->add( 'site_empty_domain', __( 'Site domain must not be empty.' ) );
    956         }
    957 
    958         // A path must always be present.
    959         if ( empty( $data['path'] ) ) {
    960                 $errors->add( 'site_empty_path', __( 'Site path must not be empty.' ) );
    961         }
    962 
    963         // A network ID must always be present.
    964         if ( empty( $data['network_id'] ) ) {
    965                 $errors->add( 'site_empty_network_id', __( 'Site network ID must be provided.' ) );
    966         }
    967 
    968         // Both registration and last updated dates must always be present and valid.
    969         $date_fields = array( 'registered', 'last_updated' );
    970         foreach ( $date_fields as $date_field ) {
    971                 if ( empty( $data[ $date_field ] ) ) {
    972                         $errors->add( 'site_empty_' . $date_field, __( 'Both registration and last updated dates must be provided.' ) );
    973                         break;
    974                 }
    975 
    976                 // Allow '0000-00-00 00:00:00', although it be stripped out at this point.
    977                 if ( '0000-00-00 00:00:00' !== $data[ $date_field ] ) {
    978                         $month      = substr( $data[ $date_field ], 5, 2 );
    979                         $day        = substr( $data[ $date_field ], 8, 2 );
    980                         $year       = substr( $data[ $date_field ], 0, 4 );
    981                         $valid_date = wp_checkdate( $month, $day, $year, $data[ $date_field ] );
    982                         if ( ! $valid_date ) {
    983                                 $errors->add( 'site_invalid_' . $date_field, __( 'Both registration and last updated dates must be valid dates.' ) );
    984                                 break;
    985                         }
    986                 }
    987         }
    988 
    989         if ( ! empty( $errors->errors ) ) {
    990                 return;
    991         }
    992 
    993         // If a new site, or domain/path/network ID have changed, ensure uniqueness.
    994         if ( ! $old_site
    995                 || $data['domain'] !== $old_site->domain
    996                 || $data['path'] !== $old_site->path
    997                 || $data['network_id'] !== $old_site->network_id
    998         ) {
    999                 if ( domain_exists( $data['domain'], $data['path'], $data['network_id'] ) ) {
    1000                         $errors->add( 'site_taken', __( 'Sorry, that site already exists!' ) );
    1001                 }
    1002         }
    1003 }
    1004 
    1005 /**
    1006  * Runs the initialization routine for a given site.
    1007  *
    1008  * This process includes creating the site's database tables and
    1009  * populating them with defaults.
    1010  *
    1011  * @since 5.1.0
    1012  *
    1013  * @global wpdb     $wpdb     WordPress database abstraction object.
    1014  * @global WP_Roles $wp_roles WordPress role management object.
    1015  *
    1016  * @param int|WP_Site $site_id Site ID or object.
    1017  * @param array       $args    {
    1018  *     Optional. Arguments to modify the initialization behavior.
    1019  *
    1020  *     @type int    $user_id Required. User ID for the site administrator.
    1021  *     @type string $title   Site title. Default is 'Site %d' where %d is the
    1022  *                           site ID.
    1023  *     @type array  $options Custom option $key => $value pairs to use. Default
    1024  *                           empty array.
    1025  *     @type array  $meta    Custom site metadata $key => $value pairs to use.
    1026  *                           Default empty array.
    1027  * }
    1028  * @return bool|WP_Error True on success, or error object on failure.
    1029  */
    1030 function wp_initialize_site( $site_id, array $args = array() ) {
    1031         global $wpdb, $wp_roles;
    1032 
    1033         if ( empty( $site_id ) ) {
    1034                 return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
    1035         }
    1036 
    1037         $site = get_site( $site_id );
    1038         if ( ! $site ) {
    1039                 return new WP_Error( 'site_invalid_id', __( 'Site with the ID does not exist.' ) );
    1040         }
    1041 
    1042         if ( wp_is_site_initialized( $site ) ) {
    1043                 return new WP_Error( 'site_already_initialized', __( 'The site appears to be already initialized.' ) );
    1044         }
    1045 
    1046         $network = get_network( $site->network_id );
    1047         if ( ! $network ) {
    1048                 $network = get_network();
    1049         }
    1050 
    1051         $args = wp_parse_args(
    1052                 $args,
    1053                 array(
    1054                         'user_id' => 0,
    1055                         /* translators: %d: site ID */
    1056                         'title'   => sprintf( __( 'Site %d' ), $site->id ),
    1057                         'options' => array(),
    1058                         'meta'    => array(),
    1059                 )
    1060         );
    1061 
    1062         /**
    1063          * Filters the arguments for initializing a site.
    1064          *
    1065          * @since 5.1.0
    1066          *
    1067          * @param array      $args    Arguments to modify the initialization behavior.
    1068          * @param WP_Site    $site    Site that is being initialized.
    1069          * @param WP_Network $network Network that the site belongs to.
    1070          */
    1071         $args = apply_filters( 'wp_initialize_site_args', $args, $site, $network );
    1072 
    1073         $orig_installing = wp_installing();
    1074         if ( ! $orig_installing ) {
    1075                 wp_installing( true );
    1076         }
    1077 
    1078         $switch = false;
    1079         if ( get_current_blog_id() !== $site->id ) {
    1080                 $switch = true;
    1081                 switch_to_blog( $site->id );
    1082         }
    1083 
    1084         require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    1085 
    1086         // Set up the database tables.
    1087         make_db_current_silent( 'blog' );
    1088 
    1089         $home_scheme    = 'http';
    1090         $siteurl_scheme = 'http';
    1091         if ( ! is_subdomain_install() ) {
    1092                 if ( 'https' === parse_url( get_home_url( $network->site_id ), PHP_URL_SCHEME ) ) {
    1093                         $home_scheme = 'https';
    1094                 }
    1095                 if ( 'https' === parse_url( get_network_option( $network->id, 'siteurl' ), PHP_URL_SCHEME ) ) {
    1096                         $siteurl_scheme = 'https';
    1097                 }
    1098         }
    1099 
    1100         // Populate the site's options.
    1101         populate_options(
    1102                 array_merge(
    1103                         array(
    1104                                 'home'        => untrailingslashit( $home_scheme . '://' . $site->domain . $site->path ),
    1105                                 'siteurl'     => untrailingslashit( $siteurl_scheme . '://' . $site->domain . $site->path ),
    1106                                 'blogname'    => wp_unslash( $args['title'] ),
    1107                                 'admin_email' => '',
    1108                                 'upload_path' => get_network_option( $network->id, 'ms_files_rewriting' ) ? UPLOADBLOGSDIR . "/{$site->id}/files" : get_blog_option( $network->site_id, 'upload_path' ),
    1109                                 'blog_public' => (int) $site->public,
    1110                                 'WPLANG'      => get_network_option( $network->id, 'WPLANG' ),
    1111                         ),
    1112                         $args['options']
    1113                 )
    1114         );
    1115 
    1116         // Populate the site's roles.
    1117         populate_roles();
    1118         $wp_roles = new WP_Roles();
    1119 
    1120         // Populate metadata for the site.
    1121         populate_site_meta( $site->id, $args['meta'] );
    1122 
    1123         // Remove all permissions that may exist for the site.
    1124         $table_prefix = $wpdb->get_blog_prefix();
    1125         delete_metadata( 'user', 0, $table_prefix . 'user_level', null, true ); // delete all
    1126         delete_metadata( 'user', 0, $table_prefix . 'capabilities', null, true ); // delete all
    1127 
    1128         // Install default site content.
    1129         wp_install_defaults( $args['user_id'] );
    1130 
    1131         // Set the site administrator.
    1132         add_user_to_blog( $site->id, $args['user_id'], 'administrator' );
    1133         if ( ! user_can( $args['user_id'], 'manage_network' ) && ! get_user_meta( $args['user_id'], 'primary_blog', true ) ) {
    1134                 update_user_meta( $args['user_id'], 'primary_blog', $site->id );
    1135         }
    1136 
    1137         if ( $switch ) {
    1138                 restore_current_blog();
    1139         }
    1140 
    1141         wp_installing( $orig_installing );
    1142 
    1143         return true;
    1144 }
    1145 
    1146 /**
    1147  * Runs the uninitialization routine for a given site.
    1148  *
    1149  * This process includes dropping the site's database tables and deleting its uploads directory.
    1150  *
    1151  * @since 5.1.0
    1152  *
    1153  * @global wpdb $wpdb WordPress database abstraction object.
    1154  *
    1155  * @param int|WP_Site $site_id Site ID or object.
    1156  * @return bool|WP_Error True on success, or error object on failure.
    1157  */
    1158 function wp_uninitialize_site( $site_id ) {
    1159         global $wpdb;
    1160 
    1161         if ( empty( $site_id ) ) {
    1162                 return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
    1163         }
    1164 
    1165         $site = get_site( $site_id );
    1166         if ( ! $site ) {
    1167                 return new WP_Error( 'site_invalid_id', __( 'Site with the ID does not exist.' ) );
    1168         }
    1169 
    1170         if ( ! wp_is_site_initialized( $site ) ) {
    1171                 return new WP_Error( 'site_already_uninitialized', __( 'The site appears to be already uninitialized.' ) );
    1172         }
    1173 
    1174         $users = get_users(
    1175                 array(
    1176                         'blog_id' => $site->id,
    1177                         'fields'  => 'ids',
    1178                 )
    1179         );
    1180 
    1181         // Remove users from the site.
    1182         if ( ! empty( $users ) ) {
    1183                 foreach ( $users as $user_id ) {
    1184                         remove_user_from_blog( $user_id, $site->id );
    1185                 }
    1186         }
    1187 
    1188         $switch = false;
    1189         if ( get_current_blog_id() !== $site->id ) {
    1190                 $switch = true;
    1191                 switch_to_blog( $site->id );
    1192         }
    1193 
    1194         $uploads = wp_get_upload_dir();
    1195 
    1196         $tables = $wpdb->tables( 'blog' );
    1197 
    1198         /**
    1199          * Filters the tables to drop when the site is deleted.
    1200          *
    1201          * @since MU (3.0.0)
    1202          *
    1203          * @param string[] $tables  Array of names of the site tables to be dropped.
    1204          * @param int      $site_id The ID of the site to drop tables for.
    1205          */
    1206         $drop_tables = apply_filters( 'wpmu_drop_tables', $tables, $site->id );
    1207 
    1208         foreach ( (array) $drop_tables as $table ) {
    1209                 $wpdb->query( "DROP TABLE IF EXISTS `$table`" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
     237                return $details;
    1210238        }
    1211239
     240        switch_to_blog( $blog_id );
     241        $details->blogname   = get_option( 'blogname' );
     242        $details->siteurl    = get_option( 'siteurl' );
     243        $details->post_count = get_option( 'post_count' );
     244        $details->home       = get_option( 'home' );
     245        restore_current_blog();
     246
    1212247        /**
    1213          * Filters the upload base directory to delete when the site is deleted.
     248         * Filters a blog's details.
    1214249         *
    1215250         * @since MU (3.0.0)
     251         * @deprecated 4.7.0 Use site_details
    1216252         *
    1217          * @param string $uploads['basedir'] Uploads path without subdirectory. @see wp_upload_dir()
    1218          * @param int    $site_id            The site ID.
     253         * @param object $details The blog details.
    1219254         */
    1220         $dir     = apply_filters( 'wpmu_delete_blog_upload_dir', $uploads['basedir'], $site->id );
    1221         $dir     = rtrim( $dir, DIRECTORY_SEPARATOR );
    1222         $top_dir = $dir;
    1223         $stack   = array( $dir );
    1224         $index   = 0;
    1225 
    1226         while ( $index < count( $stack ) ) {
    1227                 // Get indexed directory from stack
    1228                 $dir = $stack[ $index ];
    1229 
    1230                 // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
    1231                 $dh = @opendir( $dir );
    1232                 if ( $dh ) {
    1233                         $file = @readdir( $dh );
    1234                         while ( false !== $file ) {
    1235                                 if ( '.' === $file || '..' === $file ) {
    1236                                         $file = @readdir( $dh );
    1237                                         continue;
    1238                                 }
     255        $details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' );
    1239256
    1240                                 if ( @is_dir( $dir . DIRECTORY_SEPARATOR . $file ) ) {
    1241                                         $stack[] = $dir . DIRECTORY_SEPARATOR . $file;
    1242                                 } elseif ( @is_file( $dir . DIRECTORY_SEPARATOR . $file ) ) {
    1243                                         @unlink( $dir . DIRECTORY_SEPARATOR . $file );
    1244                                 }
     257        wp_cache_set( $blog_id . $all, $details, 'blog-details' );
    1245258
    1246                                 $file = @readdir( $dh );
    1247                         }
    1248                         @closedir( $dh );
    1249                 }
    1250                 $index++;
    1251         }
     259        $key = md5( $details->domain . $details->path );
     260        wp_cache_set( $key, $details, 'blog-lookup' );
    1252261
    1253         $stack = array_reverse( $stack ); // Last added dirs are deepest
    1254         foreach ( (array) $stack as $dir ) {
    1255                 if ( $dir != $top_dir ) {
    1256                         @rmdir( $dir );
    1257                 }
    1258         }
     262        return $details;
     263}
    1259264
    1260         // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged
    1261         if ( $switch ) {
    1262                 restore_current_blog();
     265/**
     266 * Clear the blog details cache.
     267 *
     268 * @since MU (3.0.0)
     269 *
     270 * @param int $blog_id Optional. Blog ID. Defaults to current blog.
     271 */
     272function refresh_blog_details( $blog_id = 0 ) {
     273        $blog_id = (int) $blog_id;
     274        if ( ! $blog_id ) {
     275                $blog_id = get_current_blog_id();
    1263276        }
    1264277
    1265         return true;
     278        clean_blog_cache( $blog_id );
    1266279}
    1267280
    1268281/**
    1269  * Checks whether a site is initialized.
    1270  *
    1271  * A site is considered initialized when its database tables are present.
     282 * Update the details for a blog. Updates the blogs table for a given blog id.
    1272283 *
    1273  * @since 5.1.0
     284 * @since MU (3.0.0)
    1274285 *
    1275286 * @global wpdb $wpdb WordPress database abstraction object.
    1276287 *
    1277  * @param int|WP_Site $site_id Site ID or object.
    1278  * @return bool True if the site is initialized, false otherwise.
     288 * @param int   $blog_id Blog ID
     289 * @param array $details Array of details keyed by blogs table field names.
     290 * @return bool True if update succeeds, false otherwise.
    1279291 */
    1280 function wp_is_site_initialized( $site_id ) {
     292function update_blog_details( $blog_id, $details = array() ) {
    1281293        global $wpdb;
    1282294
    1283         if ( is_object( $site_id ) ) {
    1284                 $site_id = $site_id->blog_id;
     295        if ( empty( $details ) ) {
     296                return false;
    1285297        }
    1286         $site_id = (int) $site_id;
    1287298
    1288         /**
    1289          * Filters the check for whether a site is initialized before the database is accessed.
    1290          *
    1291          * Returning a non-null value will effectively short-circuit the function, returning
    1292          * that value instead.
    1293          *
    1294          * @since 5.1.0
    1295          *
    1296          * @param bool|null $pre     The value to return, if not null.
    1297          * @param int       $site_id The site ID that is being checked.
    1298          */
    1299         $pre = apply_filters( 'pre_wp_is_site_initialized', null, $site_id );
    1300         if ( null !== $pre ) {
    1301                 return (bool) $pre;
     299        if ( is_object( $details ) ) {
     300                $details = get_object_vars( $details );
    1302301        }
    1303302
    1304         $switch = false;
    1305         if ( get_current_blog_id() !== $site_id ) {
    1306                 $switch = true;
    1307                 remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 );
    1308                 switch_to_blog( $site_id );
     303        $site = wp_update_site( $blog_id, $details );
     304
     305        if ( is_wp_error( $site ) ) {
     306                return false;
    1309307        }
    1310308
    1311         $suppress = $wpdb->suppress_errors();
    1312         $result   = (bool) $wpdb->get_results( "DESCRIBE {$wpdb->posts}" );
    1313         $wpdb->suppress_errors( $suppress );
     309        return true;
     310}
    1314311
    1315         if ( $switch ) {
    1316                 restore_current_blog();
    1317                 add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 );
     312/**
     313 * Cleans the site details cache for a site.
     314 *
     315 * @since 4.7.4
     316 *
     317 * @param int $site_id Optional. Site ID. Default is the current site ID.
     318 */
     319function clean_site_details_cache( $site_id = 0 ) {
     320        $site_id = (int) $site_id;
     321        if ( ! $site_id ) {
     322                $site_id = get_current_blog_id();
    1318323        }
    1319324
    1320         return $result;
     325        wp_cache_delete( $site_id, 'site-details' );
     326        wp_cache_delete( $site_id, 'blog-details' );
    1321327}
    1322328
    1323329/**
     
    1459465}
    1460466
    1461467/**
    1462  * Adds metadata to a site.
    1463  *
    1464  * @since 5.1.0
    1465  *
    1466  * @param int    $site_id    Site ID.
    1467  * @param string $meta_key   Metadata name.
    1468  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
    1469  * @param bool   $unique     Optional. Whether the same key should not be added.
    1470  *                           Default false.
    1471  * @return int|false Meta ID on success, false on failure.
    1472  */
    1473 function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
    1474         return add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique );
    1475 }
    1476 
    1477 /**
    1478  * Removes metadata matching criteria from a site.
    1479  *
    1480  * You can match based on the key, or key and value. Removing based on key and
    1481  * value, will keep from removing duplicate metadata with the same key. It also
    1482  * allows removing all metadata matching key, if needed.
    1483  *
    1484  * @since 5.1.0
    1485  *
    1486  * @param int    $site_id    Site ID.
    1487  * @param string $meta_key   Metadata name.
    1488  * @param mixed  $meta_value Optional. Metadata value. Must be serializable if
    1489  *                           non-scalar. Default empty.
    1490  * @return bool True on success, false on failure.
    1491  */
    1492 function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
    1493         return delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
    1494 }
    1495 
    1496 /**
    1497  * Retrieves metadata for a site.
    1498  *
    1499  * @since 5.1.0
    1500  *
    1501  * @param int    $site_id Site ID.
    1502  * @param string $key     Optional. The meta key to retrieve. By default, returns
    1503  *                        data for all keys. Default empty.
    1504  * @param bool   $single  Optional. Whether to return a single value. Default false.
    1505  * @return mixed Will be an array if $single is false. Will be value of meta data
    1506  *               field if $single is true.
    1507  */
    1508 function get_site_meta( $site_id, $key = '', $single = false ) {
    1509         return get_metadata( 'blog', $site_id, $key, $single );
    1510 }
    1511 
    1512 /**
    1513  * Updates metadata for a site.
    1514  *
    1515  * Use the $prev_value parameter to differentiate between meta fields with the
    1516  * same key and site ID.
    1517  *
    1518  * If the meta field for the site does not exist, it will be added.
    1519  *
    1520  * @since 5.1.0
    1521  *
    1522  * @param int    $site_id    Site ID.
    1523  * @param string $meta_key   Metadata key.
    1524  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
    1525  * @param mixed  $prev_value Optional. Previous value to check before removing.
    1526  *                           Default empty.
    1527  * @return int|bool Meta ID if the key didn't exist, true on successful update,
    1528  *                  false on failure.
    1529  */
    1530 function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) {
    1531         return update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value );
    1532 }
    1533 
    1534 /**
    1535  * Deletes everything from site meta matching meta key.
    1536  *
    1537  * @since 5.1.0
    1538  *
    1539  * @param string $meta_key Metadata key to search for when deleting.
    1540  * @return bool Whether the site meta key was deleted from the database.
    1541  */
    1542 function delete_site_meta_by_key( $meta_key ) {
    1543         return delete_metadata( 'blog', null, $meta_key, '', true );
    1544 }
    1545 
    1546 /**
    1547468 * Switch the current blog.
    1548469 *
    1549470 * This function is useful if you need to pull posts, or other information,
     
    1843764}
    1844765
    1845766/**
    1846  * Retrieves a list of networks.
    1847  *
    1848  * @since 4.6.0
    1849  *
    1850  * @param string|array $args Optional. Array or string of arguments. See WP_Network_Query::parse_query()
    1851  *                           for information on accepted arguments. Default empty array.
    1852  * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids',
    1853  *                   or the number of networks when 'count' is passed as a query var.
    1854  */
    1855 function get_networks( $args = array() ) {
    1856         $query = new WP_Network_Query();
    1857 
    1858         return $query->query( $args );
    1859 }
    1860 
    1861 /**
    1862  * Retrieves network data given a network ID or network object.
    1863  *
    1864  * Network data will be cached and returned after being passed through a filter.
    1865  * If the provided network is empty, the current network global will be used.
    1866  *
    1867  * @since 4.6.0
    1868  *
    1869  * @global WP_Network $current_site
    1870  *
    1871  * @param WP_Network|int|null $network Optional. Network to retrieve. Default is the current network.
    1872  * @return WP_Network|null The network object or null if not found.
    1873  */
    1874 function get_network( $network = null ) {
    1875         global $current_site;
    1876         if ( empty( $network ) && isset( $current_site ) ) {
    1877                 $network = $current_site;
    1878         }
    1879 
    1880         if ( $network instanceof WP_Network ) {
    1881                 $_network = $network;
    1882         } elseif ( is_object( $network ) ) {
    1883                 $_network = new WP_Network( $network );
    1884         } else {
    1885                 $_network = WP_Network::get_instance( $network );
    1886         }
    1887 
    1888         if ( ! $_network ) {
    1889                 return null;
    1890         }
    1891 
    1892         /**
    1893          * Fires after a network is retrieved.
    1894          *
    1895          * @since 4.6.0
    1896          *
    1897          * @param WP_Network $_network Network data.
    1898          */
    1899         $_network = apply_filters( 'get_network', $_network );
    1900 
    1901         return $_network;
    1902 }
    1903 
    1904 /**
    1905  * Removes a network from the object cache.
    1906  *
    1907  * @since 4.6.0
    1908  *
    1909  * @global bool $_wp_suspend_cache_invalidation
    1910  *
    1911  * @param int|array $ids Network ID or an array of network IDs to remove from cache.
    1912  */
    1913 function clean_network_cache( $ids ) {
    1914         global $_wp_suspend_cache_invalidation;
    1915 
    1916         if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
    1917                 return;
    1918         }
    1919 
    1920         foreach ( (array) $ids as $id ) {
    1921                 wp_cache_delete( $id, 'networks' );
    1922 
    1923                 /**
    1924                  * Fires immediately after a network has been removed from the object cache.
    1925                  *
    1926                  * @since 4.6.0
    1927                  *
    1928                  * @param int $id Network ID.
    1929                  */
    1930                 do_action( 'clean_network_cache', $id );
    1931         }
    1932 
    1933         wp_cache_set( 'last_changed', microtime(), 'networks' );
    1934 }
    1935 
    1936 /**
    1937  * Updates the network cache of given networks.
    1938  *
    1939  * Will add the networks in $networks to the cache. If network ID already exists
    1940  * in the network cache then it will not be updated. The network is added to the
    1941  * cache using the network group with the key using the ID of the networks.
    1942  *
    1943  * @since 4.6.0
    1944  *
    1945  * @param array $networks Array of network row objects.
    1946  */
    1947 function update_network_cache( $networks ) {
    1948         foreach ( (array) $networks as $network ) {
    1949                 wp_cache_add( $network->id, $network, 'networks' );
    1950         }
    1951 }
    1952 
    1953 /**
    1954  * Adds any networks from the given IDs to the cache that do not already exist in cache.
    1955  *
    1956  * @since 4.6.0
    1957  * @access private
    1958  *
    1959  * @see update_network_cache()
    1960  * @global wpdb $wpdb WordPress database abstraction object.
    1961  *
    1962  * @param array $network_ids Array of network IDs.
    1963  */
    1964 function _prime_network_caches( $network_ids ) {
    1965         global $wpdb;
    1966 
    1967         $non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' );
    1968         if ( ! empty( $non_cached_ids ) ) {
    1969                 $fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    1970 
    1971                 update_network_cache( $fresh_networks );
    1972         }
    1973 }
    1974 
    1975 /**
    1976767 * Handler for updating the site's last updated date when a post is published or
    1977768 * an already published post is changed.
    1978769 *
     
    2062853
    2063854        update_posts_count();
    2064855}
    2065 
    2066 /**
    2067  * Updates the count of sites for a network based on a changed site.
    2068  *
    2069  * @since 5.1.0
    2070  *
    2071  * @param WP_Site      $new_site The site object that has been inserted, updated or deleted.
    2072  * @param WP_Site|null $old_site Optional. If $new_site has been updated, this must be the previous
    2073  *                               state of that site. Default null.
    2074  */
    2075 function wp_maybe_update_network_site_counts_on_update( $new_site, $old_site = null ) {
    2076         if ( null === $old_site ) {
    2077                 wp_maybe_update_network_site_counts( $new_site->network_id );
    2078                 return;
    2079         }
    2080 
    2081         if ( $new_site->network_id != $old_site->network_id ) {
    2082                 wp_maybe_update_network_site_counts( $new_site->network_id );
    2083                 wp_maybe_update_network_site_counts( $old_site->network_id );
    2084         }
    2085 }
    2086 
    2087 /**
    2088  * Triggers actions on site status updates.
    2089  *
    2090  * @since 5.1.0
    2091  *
    2092  * @param WP_Site      $new_site The site object after the update.
    2093  * @param WP_Site|null $old_site Optional. If $new_site has been updated, this must be the previous
    2094  *                               state of that site. Default null.
    2095  */
    2096 function wp_maybe_transition_site_statuses_on_update( $new_site, $old_site = null ) {
    2097         $site_id = $new_site->id;
    2098 
    2099         // Use the default values for a site if no previous state is given.
    2100         if ( ! $old_site ) {
    2101                 $old_site = new WP_Site( new stdClass() );
    2102         }
    2103 
    2104         if ( $new_site->spam != $old_site->spam ) {
    2105                 if ( 1 == $new_site->spam ) {
    2106 
    2107                         /**
    2108                          * Fires when the 'spam' status is added to a site.
    2109                          *
    2110                          * @since MU (3.0.0)
    2111                          *
    2112                          * @param int $site_id Site ID.
    2113                          */
    2114                         do_action( 'make_spam_blog', $site_id );
    2115                 } else {
    2116 
    2117                         /**
    2118                          * Fires when the 'spam' status is removed from a site.
    2119                          *
    2120                          * @since MU (3.0.0)
    2121                          *
    2122                          * @param int $site_id Site ID.
    2123                          */
    2124                         do_action( 'make_ham_blog', $site_id );
    2125                 }
    2126         }
    2127 
    2128         if ( $new_site->mature != $old_site->mature ) {
    2129                 if ( 1 == $new_site->mature ) {
    2130 
    2131                         /**
    2132                          * Fires when the 'mature' status is added to a site.
    2133                          *
    2134                          * @since 3.1.0
    2135                          *
    2136                          * @param int $site_id Site ID.
    2137                          */
    2138                         do_action( 'mature_blog', $site_id );
    2139                 } else {
    2140 
    2141                         /**
    2142                          * Fires when the 'mature' status is removed from a site.
    2143                          *
    2144                          * @since 3.1.0
    2145                          *
    2146                          * @param int $site_id Site ID.
    2147                          */
    2148                         do_action( 'unmature_blog', $site_id );
    2149                 }
    2150         }
    2151 
    2152         if ( $new_site->archived != $old_site->archived ) {
    2153                 if ( 1 == $new_site->archived ) {
    2154 
    2155                         /**
    2156                          * Fires when the 'archived' status is added to a site.
    2157                          *
    2158                          * @since MU (3.0.0)
    2159                          *
    2160                          * @param int $site_id Site ID.
    2161                          */
    2162                         do_action( 'archive_blog', $site_id );
    2163                 } else {
    2164 
    2165                         /**
    2166                          * Fires when the 'archived' status is removed from a site.
    2167                          *
    2168                          * @since MU (3.0.0)
    2169                          *
    2170                          * @param int $site_id Site ID.
    2171                          */
    2172                         do_action( 'unarchive_blog', $site_id );
    2173                 }
    2174         }
    2175 
    2176         if ( $new_site->deleted != $old_site->deleted ) {
    2177                 if ( 1 == $new_site->deleted ) {
    2178 
    2179                         /**
    2180                          * Fires when the 'deleted' status is added to a site.
    2181                          *
    2182                          * @since 3.5.0
    2183                          *
    2184                          * @param int $site_id Site ID.
    2185                          */
    2186                         do_action( 'make_delete_blog', $site_id );
    2187                 } else {
    2188 
    2189                         /**
    2190                          * Fires when the 'deleted' status is removed from a site.
    2191                          *
    2192                          * @since 3.5.0
    2193                          *
    2194                          * @param int $site_id Site ID.
    2195                          */
    2196                         do_action( 'make_undelete_blog', $site_id );
    2197                 }
    2198         }
    2199 
    2200         if ( $new_site->public != $old_site->public ) {
    2201 
    2202                 /**
    2203                  * Fires after the current blog's 'public' setting is updated.
    2204                  *
    2205                  * @since MU (3.0.0)
    2206                  *
    2207                  * @param int    $site_id Site ID.
    2208                  * @param string $value   The value of the site status.
    2209                  */
    2210                 do_action( 'update_blog_public', $site_id, $new_site->public );
    2211         }
    2212 }
    2213 
    2214 /**
    2215  * Cleans the necessary caches after specific site data has been updated.
    2216  *
    2217  * @since 5.1.0
    2218  *
    2219  * @param WP_Site $new_site The site object after the update.
    2220  * @param WP_Site $old_site The site obejct prior to the update.
    2221  */
    2222 function wp_maybe_clean_new_site_cache_on_update( $new_site, $old_site ) {
    2223         if ( $old_site->domain !== $new_site->domain || $old_site->path !== $new_site->path ) {
    2224                 clean_blog_cache( $new_site );
    2225         }
    2226 }
    2227 
    2228 /**
    2229  * Updates the `blog_public` option for a given site ID.
    2230  *
    2231  * @since 5.1.0
    2232  *
    2233  * @param int    $site_id Site ID.
    2234  * @param string $public  The value of the site status.
    2235  */
    2236 function wp_update_blog_public_option_on_site_update( $site_id, $public ) {
    2237 
    2238         // Bail if the site's database tables do not exist (yet).
    2239         if ( ! wp_is_site_initialized( $site_id ) ) {
    2240                 return;
    2241         }
    2242 
    2243         update_blog_option( $site_id, 'blog_public', $public );
    2244 }
    2245 
    2246 /**
    2247  * Sets the last changed time for the 'sites' cache group.
    2248  *
    2249  * @since 5.1.0
    2250  */
    2251 function wp_cache_set_sites_last_changed() {
    2252         wp_cache_set( 'last_changed', microtime(), 'sites' );
    2253 }
    2254 
    2255 /**
    2256  * Aborts calls to site meta if it is not supported.
    2257  *
    2258  * @since 5.1.0
    2259  *
    2260  * @global wpdb $wpdb WordPress database abstraction object.
    2261  *
    2262  * @param mixed $check Skip-value for whether to proceed site meta function execution.
    2263  * @return mixed Original value of $check, or false if site meta is not supported.
    2264  */
    2265 function wp_check_site_meta_support_prefilter( $check ) {
    2266         if ( ! is_site_meta_supported() ) {
    2267                 /* translators: %s: database table name */
    2268                 _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.1.0' );
    2269                 return false;
    2270         }
    2271 
    2272         return $check;
    2273 }