[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> ms-site.php (source)

   1  <?php
   2  /**
   3   * Site API
   4   *
   5   * @package WordPress
   6   * @subpackage Multisite
   7   * @since 5.1.0
   8   */
   9  
  10  /**
  11   * Inserts a new site into the database.
  12   *
  13   * @since 5.1.0
  14   *
  15   * @global wpdb $wpdb WordPress database abstraction object.
  16   *
  17   * @param array $data {
  18   *     Data for the new site that should be inserted.
  19   *
  20   *     @type string $domain       Site domain. Default empty string.
  21   *     @type string $path         Site path. Default '/'.
  22   *     @type int    $network_id   The site's network ID. Default is the current network ID.
  23   *     @type string $registered   When the site was registered, in SQL datetime format. Default is
  24   *                                the current time.
  25   *     @type string $last_updated When the site was last updated, in SQL datetime format. Default is
  26   *                                the value of $registered.
  27   *     @type int    $public       Whether the site is public. Default 1.
  28   *     @type int    $archived     Whether the site is archived. Default 0.
  29   *     @type int    $mature       Whether the site is mature. Default 0.
  30   *     @type int    $spam         Whether the site is spam. Default 0.
  31   *     @type int    $deleted      Whether the site is deleted. Default 0.
  32   *     @type int    $lang_id      The site's language ID. Currently unused. Default 0.
  33   *     @type int    $user_id      User ID for the site administrator. Passed to the
  34   *                                `wp_initialize_site` hook.
  35   *     @type string $title        Site title. Default is 'Site %d' where %d is the site ID. Passed
  36   *                                to the `wp_initialize_site` hook.
  37   *     @type array  $options      Custom option $key => $value pairs to use. Default empty array. Passed
  38   *                                to the `wp_initialize_site` hook.
  39   *     @type array  $meta         Custom site metadata $key => $value pairs to use. Default empty array.
  40   *                                Passed to the `wp_initialize_site` hook.
  41   * }
  42   * @return int|WP_Error The new site's ID on success, or error object on failure.
  43   */
  44  function wp_insert_site( array $data ) {
  45      global $wpdb;
  46  
  47      $now = current_time( 'mysql', true );
  48  
  49      $defaults = array(
  50          'domain'       => '',
  51          'path'         => '/',
  52          'network_id'   => get_current_network_id(),
  53          'registered'   => $now,
  54          'last_updated' => $now,
  55          'public'       => 1,
  56          'archived'     => 0,
  57          'mature'       => 0,
  58          'spam'         => 0,
  59          'deleted'      => 0,
  60          'lang_id'      => 0,
  61      );
  62  
  63      $prepared_data = wp_prepare_site_data( $data, $defaults );
  64      if ( is_wp_error( $prepared_data ) ) {
  65          return $prepared_data;
  66      }
  67  
  68      if ( false === $wpdb->insert( $wpdb->blogs, $prepared_data ) ) {
  69          return new WP_Error( 'db_insert_error', __( 'Could not insert site into the database.' ), $wpdb->last_error );
  70      }
  71  
  72      $site_id = (int) $wpdb->insert_id;
  73  
  74      clean_blog_cache( $site_id );
  75  
  76      $new_site = get_site( $site_id );
  77  
  78      if ( ! $new_site ) {
  79          return new WP_Error( 'get_site_error', __( 'Could not retrieve site data.' ) );
  80      }
  81  
  82      /**
  83       * Fires once a site has been inserted into the database.
  84       *
  85       * @since 5.1.0
  86       *
  87       * @param WP_Site $new_site New site object.
  88       */
  89      do_action( 'wp_insert_site', $new_site );
  90  
  91      // Extract the passed arguments that may be relevant for site initialization.
  92      $args = array_diff_key( $data, $defaults );
  93      if ( isset( $args['site_id'] ) ) {
  94          unset( $args['site_id'] );
  95      }
  96  
  97      /**
  98       * Fires when a site's initialization routine should be executed.
  99       *
 100       * @since 5.1.0
 101       *
 102       * @param WP_Site $new_site New site object.
 103       * @param array   $args     Arguments for the initialization.
 104       */
 105      do_action( 'wp_initialize_site', $new_site, $args );
 106  
 107      // Only compute extra hook parameters if the deprecated hook is actually in use.
 108      if ( has_action( 'wpmu_new_blog' ) ) {
 109          $user_id = ! empty( $args['user_id'] ) ? $args['user_id'] : 0;
 110          $meta    = ! empty( $args['options'] ) ? $args['options'] : array();
 111  
 112          // WPLANG was passed with `$meta` to the `wpmu_new_blog` hook prior to 5.1.0.
 113          if ( ! array_key_exists( 'WPLANG', $meta ) ) {
 114              $meta['WPLANG'] = get_network_option( $new_site->network_id, 'WPLANG' );
 115          }
 116  
 117          /*
 118           * Rebuild the data expected by the `wpmu_new_blog` hook prior to 5.1.0 using allowed keys.
 119           * The `$allowed_data_fields` matches the one used in `wpmu_create_blog()`.
 120           */
 121          $allowed_data_fields = array( 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' );
 122          $meta                = array_merge( array_intersect_key( $data, array_flip( $allowed_data_fields ) ), $meta );
 123  
 124          /**
 125           * Fires immediately after a new site is created.
 126           *
 127           * @since MU (3.0.0)
 128           * @deprecated 5.1.0 Use {@see 'wp_initialize_site'} instead.
 129           *
 130           * @param int    $site_id    Site ID.
 131           * @param int    $user_id    User ID.
 132           * @param string $domain     Site domain.
 133           * @param string $path       Site path.
 134           * @param int    $network_id Network ID. Only relevant on multi-network installations.
 135           * @param array  $meta       Meta data. Used to set initial site options.
 136           */
 137          do_action_deprecated(
 138              'wpmu_new_blog',
 139              array( $new_site->id, $user_id, $new_site->domain, $new_site->path, $new_site->network_id, $meta ),
 140              '5.1.0',
 141              'wp_initialize_site'
 142          );
 143      }
 144  
 145      return (int) $new_site->id;
 146  }
 147  
 148  /**
 149   * Updates a site in the database.
 150   *
 151   * @since 5.1.0
 152   *
 153   * @global wpdb $wpdb WordPress database abstraction object.
 154   *
 155   * @param int   $site_id ID of the site that should be updated.
 156   * @param array $data    Site data to update. See {@see wp_insert_site()} for the list of supported keys.
 157   * @return int|WP_Error The updated site's ID on success, or error object on failure.
 158   */
 159  function wp_update_site( $site_id, array $data ) {
 160      global $wpdb;
 161  
 162      if ( empty( $site_id ) ) {
 163          return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
 164      }
 165  
 166      $old_site = get_site( $site_id );
 167      if ( ! $old_site ) {
 168          return new WP_Error( 'site_not_exist', __( 'Site does not exist.' ) );
 169      }
 170  
 171      $defaults                 = $old_site->to_array();
 172      $defaults['network_id']   = (int) $defaults['site_id'];
 173      $defaults['last_updated'] = current_time( 'mysql', true );
 174      unset( $defaults['blog_id'], $defaults['site_id'] );
 175  
 176      $data = wp_prepare_site_data( $data, $defaults, $old_site );
 177      if ( is_wp_error( $data ) ) {
 178          return $data;
 179      }
 180  
 181      if ( false === $wpdb->update( $wpdb->blogs, $data, array( 'blog_id' => $old_site->id ) ) ) {
 182          return new WP_Error( 'db_update_error', __( 'Could not update site in the database.' ), $wpdb->last_error );
 183      }
 184  
 185      clean_blog_cache( $old_site );
 186  
 187      $new_site = get_site( $old_site->id );
 188  
 189      /**
 190       * Fires once a site has been updated in the database.
 191       *
 192       * @since 5.1.0
 193       *
 194       * @param WP_Site $new_site New site object.
 195       * @param WP_Site $old_site Old site object.
 196       */
 197      do_action( 'wp_update_site', $new_site, $old_site );
 198  
 199      return (int) $new_site->id;
 200  }
 201  
 202  /**
 203   * Deletes a site from the database.
 204   *
 205   * @since 5.1.0
 206   *
 207   * @global wpdb $wpdb WordPress database abstraction object.
 208   *
 209   * @param int $site_id ID of the site that should be deleted.
 210   * @return WP_Site|WP_Error The deleted site object on success, or error object on failure.
 211   */
 212  function wp_delete_site( $site_id ) {
 213      global $wpdb;
 214  
 215      if ( empty( $site_id ) ) {
 216          return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
 217      }
 218  
 219      $old_site = get_site( $site_id );
 220      if ( ! $old_site ) {
 221          return new WP_Error( 'site_not_exist', __( 'Site does not exist.' ) );
 222      }
 223  
 224      $errors = new WP_Error();
 225  
 226      /**
 227       * Fires before a site should be deleted from the database.
 228       *
 229       * Plugins should amend the `$errors` object via its `WP_Error::add()` method. If any errors
 230       * are present, the site will not be deleted.
 231       *
 232       * @since 5.1.0
 233       *
 234       * @param WP_Error $errors   Error object to add validation errors to.
 235       * @param WP_Site  $old_site The site object to be deleted.
 236       */
 237      do_action( 'wp_validate_site_deletion', $errors, $old_site );
 238  
 239      if ( ! empty( $errors->errors ) ) {
 240          return $errors;
 241      }
 242  
 243      /**
 244       * Fires before a site is deleted.
 245       *
 246       * @since MU (3.0.0)
 247       * @deprecated 5.1.0
 248       *
 249       * @param int  $site_id The site ID.
 250       * @param bool $drop    True if site's table should be dropped. Default false.
 251       */
 252      do_action_deprecated( 'delete_blog', array( $old_site->id, true ), '5.1.0' );
 253  
 254      /**
 255       * Fires when a site's uninitialization routine should be executed.
 256       *
 257       * @since 5.1.0
 258       *
 259       * @param WP_Site $old_site Deleted site object.
 260       */
 261      do_action( 'wp_uninitialize_site', $old_site );
 262  
 263      if ( is_site_meta_supported() ) {
 264          $blog_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->blogmeta WHERE blog_id = %d ", $old_site->id ) );
 265          foreach ( $blog_meta_ids as $mid ) {
 266              delete_metadata_by_mid( 'blog', $mid );
 267          }
 268      }
 269  
 270      if ( false === $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $old_site->id ) ) ) {
 271          return new WP_Error( 'db_delete_error', __( 'Could not delete site from the database.' ), $wpdb->last_error );
 272      }
 273  
 274      clean_blog_cache( $old_site );
 275  
 276      /**
 277       * Fires once a site has been deleted from the database.
 278       *
 279       * @since 5.1.0
 280       *
 281       * @param WP_Site $old_site Deleted site object.
 282       */
 283      do_action( 'wp_delete_site', $old_site );
 284  
 285      /**
 286       * Fires after the site is deleted from the network.
 287       *
 288       * @since 4.8.0
 289       * @deprecated 5.1.0
 290       *
 291       * @param int  $site_id The site ID.
 292       * @param bool $drop    True if site's tables should be dropped. Default false.
 293       */
 294      do_action_deprecated( 'deleted_blog', array( $old_site->id, true ), '5.1.0' );
 295  
 296      return $old_site;
 297  }
 298  
 299  /**
 300   * Retrieves site data given a site ID or site object.
 301   *
 302   * Site data will be cached and returned after being passed through a filter.
 303   * If the provided site is empty, the current site global will be used.
 304   *
 305   * @since 4.6.0
 306   *
 307   * @param WP_Site|int|null $site Optional. Site to retrieve. Default is the current site.
 308   * @return WP_Site|null The site object or null if not found.
 309   */
 310  function get_site( $site = null ) {
 311      if ( empty( $site ) ) {
 312          $site = get_current_blog_id();
 313      }
 314  
 315      if ( $site instanceof WP_Site ) {
 316          $_site = $site;
 317      } elseif ( is_object( $site ) ) {
 318          $_site = new WP_Site( $site );
 319      } else {
 320          $_site = WP_Site::get_instance( $site );
 321      }
 322  
 323      if ( ! $_site ) {
 324          return null;
 325      }
 326  
 327      /**
 328       * Fires after a site is retrieved.
 329       *
 330       * @since 4.6.0
 331       *
 332       * @param WP_Site $_site Site data.
 333       */
 334      $_site = apply_filters( 'get_site', $_site );
 335  
 336      return $_site;
 337  }
 338  
 339  /**
 340   * Adds any sites from the given IDs to the cache that do not already exist in cache.
 341   *
 342   * @since 4.6.0
 343   * @since 5.1.0 Introduced the `$update_meta_cache` parameter.
 344   * @since 6.1.0 This function is no longer marked as "private".
 345   * @since 6.3.0 Use wp_lazyload_site_meta() for lazy-loading of site meta.
 346   *
 347   * @see update_site_cache()
 348   * @global wpdb $wpdb WordPress database abstraction object.
 349   *
 350   * @param array $ids               ID list.
 351   * @param bool  $update_meta_cache Optional. Whether to update the meta cache. Default true.
 352   */
 353  function _prime_site_caches( $ids, $update_meta_cache = true ) {
 354      global $wpdb;
 355  
 356      $non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
 357      if ( ! empty( $non_cached_ids ) ) {
 358          $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
 359  
 360          update_site_cache( $fresh_sites, false );
 361      }
 362  
 363      if ( $update_meta_cache ) {
 364          wp_lazyload_site_meta( $ids );
 365      }
 366  }
 367  
 368  /**
 369   * Queue site meta for lazy-loading.
 370   *
 371   * @since 6.3.0
 372   *
 373   * @param array $site_ids List of site IDs.
 374   */
 375  function wp_lazyload_site_meta( array $site_ids ) {
 376      if ( empty( $site_ids ) ) {
 377          return;
 378      }
 379      $lazyloader = wp_metadata_lazyloader();
 380      $lazyloader->queue_objects( 'blog', $site_ids );
 381  }
 382  
 383  /**
 384   * Updates sites in cache.
 385   *
 386   * @since 4.6.0
 387   * @since 5.1.0 Introduced the `$update_meta_cache` parameter.
 388   *
 389   * @param array $sites             Array of site objects.
 390   * @param bool  $update_meta_cache Whether to update site meta cache. Default true.
 391   */
 392  function update_site_cache( $sites, $update_meta_cache = true ) {
 393      if ( ! $sites ) {
 394          return;
 395      }
 396      $site_ids          = array();
 397      $site_data         = array();
 398      $blog_details_data = array();
 399      foreach ( $sites as $site ) {
 400          $site_ids[]                                    = $site->blog_id;
 401          $site_data[ $site->blog_id ]                   = $site;
 402          $blog_details_data[ $site->blog_id . 'short' ] = $site;
 403  
 404      }
 405      wp_cache_add_multiple( $site_data, 'sites' );
 406      wp_cache_add_multiple( $blog_details_data, 'blog-details' );
 407  
 408      if ( $update_meta_cache ) {
 409          update_sitemeta_cache( $site_ids );
 410      }
 411  }
 412  
 413  /**
 414   * Updates metadata cache for list of site IDs.
 415   *
 416   * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache.
 417   * Subsequent calls to `get_site_meta()` will not need to query the database.
 418   *
 419   * @since 5.1.0
 420   *
 421   * @param array $site_ids List of site IDs.
 422   * @return array|false An array of metadata on success, false if there is nothing to update.
 423   */
 424  function update_sitemeta_cache( $site_ids ) {
 425      // Ensure this filter is hooked in even if the function is called early.
 426      if ( ! has_filter( 'update_blog_metadata_cache', 'wp_check_site_meta_support_prefilter' ) ) {
 427          add_filter( 'update_blog_metadata_cache', 'wp_check_site_meta_support_prefilter' );
 428      }
 429      return update_meta_cache( 'blog', $site_ids );
 430  }
 431  
 432  /**
 433   * Retrieves a list of sites matching requested arguments.
 434   *
 435   * @since 4.6.0
 436   * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
 437   *
 438   * @see WP_Site_Query::parse_query()
 439   *
 440   * @param string|array $args Optional. Array or string of arguments. See WP_Site_Query::__construct()
 441   *                           for information on accepted arguments. Default empty array.
 442   * @return WP_Site[]|int[]|int List of WP_Site objects, a list of site IDs when 'fields' is set to 'ids',
 443   *                             or the number of sites when 'count' is passed as a query var.
 444   *
 445   * @phpstan-return (
 446   *     $args is array{ count: true, ... } ? int : (
 447   *         $args is array{ fields: 'ids', ... } ? int[] : array<int, WP_Site>
 448   *     )
 449   * )
 450   */
 451  function get_sites( $args = array() ) {
 452      $query = new WP_Site_Query();
 453  
 454      return $query->query( $args );
 455  }
 456  
 457  /**
 458   * Prepares site data for insertion or update in the database.
 459   *
 460   * @since 5.1.0
 461   *
 462   * @param array        $data     Associative array of site data passed to the respective function.
 463   *                               See {@see wp_insert_site()} for the possibly included data.
 464   * @param array        $defaults Site data defaults to parse $data against.
 465   * @param WP_Site|null $old_site Optional. Old site object if an update, or null if an insertion.
 466   *                               Default null.
 467   * @return array|WP_Error Site data ready for a database transaction, or WP_Error in case a validation
 468   *                        error occurred.
 469   */
 470  function wp_prepare_site_data( $data, $defaults, $old_site = null ) {
 471  
 472      // Maintain backward-compatibility with `$site_id` as network ID.
 473      if ( isset( $data['site_id'] ) ) {
 474          if ( ! empty( $data['site_id'] ) && empty( $data['network_id'] ) ) {
 475              $data['network_id'] = $data['site_id'];
 476          }
 477          unset( $data['site_id'] );
 478      }
 479  
 480      /**
 481       * Filters passed site data in order to normalize it.
 482       *
 483       * @since 5.1.0
 484       *
 485       * @param array $data Associative array of site data passed to the respective function.
 486       *                    See {@see wp_insert_site()} for the possibly included data.
 487       */
 488      $data = apply_filters( 'wp_normalize_site_data', $data );
 489  
 490      $allowed_data_fields = array( 'domain', 'path', 'network_id', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' );
 491      $data                = array_intersect_key( wp_parse_args( $data, $defaults ), array_flip( $allowed_data_fields ) );
 492  
 493      $errors = new WP_Error();
 494  
 495      /**
 496       * Fires when data should be validated for a site prior to inserting or updating in the database.
 497       *
 498       * Plugins should amend the `$errors` object via its `WP_Error::add()` method.
 499       *
 500       * @since 5.1.0
 501       *
 502       * @param WP_Error     $errors   Error object to add validation errors to.
 503       * @param array        $data     Associative array of complete site data. See {@see wp_insert_site()}
 504       *                               for the included data.
 505       * @param WP_Site|null $old_site The old site object if the data belongs to a site being updated,
 506       *                               or null if it is a new site being inserted.
 507       */
 508      do_action( 'wp_validate_site_data', $errors, $data, $old_site );
 509  
 510      if ( ! empty( $errors->errors ) ) {
 511          return $errors;
 512      }
 513  
 514      // Prepare for database.
 515      $data['site_id'] = $data['network_id'];
 516      unset( $data['network_id'] );
 517  
 518      return $data;
 519  }
 520  
 521  /**
 522   * Normalizes data for a site prior to inserting or updating in the database.
 523   *
 524   * @since 5.1.0
 525   *
 526   * @param array $data Associative array of site data passed to the respective function.
 527   *                    See {@see wp_insert_site()} for the possibly included data.
 528   * @return array Normalized site data.
 529   */
 530  function wp_normalize_site_data( $data ) {
 531      // Sanitize domain if passed.
 532      if ( array_key_exists( 'domain', $data ) ) {
 533          $data['domain'] = preg_replace( '/[^a-z0-9\-.:]+/i', '', $data['domain'] );
 534      }
 535  
 536      // Sanitize path if passed.
 537      if ( array_key_exists( 'path', $data ) ) {
 538          $data['path'] = trailingslashit( '/' . trim( $data['path'], '/' ) );
 539      }
 540  
 541      // Sanitize network ID if passed.
 542      if ( array_key_exists( 'network_id', $data ) ) {
 543          $data['network_id'] = (int) $data['network_id'];
 544      }
 545  
 546      // Sanitize status fields if passed.
 547      $status_fields = array( 'public', 'archived', 'mature', 'spam', 'deleted' );
 548      foreach ( $status_fields as $status_field ) {
 549          if ( array_key_exists( $status_field, $data ) ) {
 550              $data[ $status_field ] = (int) $data[ $status_field ];
 551          }
 552      }
 553  
 554      // Strip date fields if empty.
 555      $date_fields = array( 'registered', 'last_updated' );
 556      foreach ( $date_fields as $date_field ) {
 557          if ( ! array_key_exists( $date_field, $data ) ) {
 558              continue;
 559          }
 560  
 561          if ( empty( $data[ $date_field ] ) || '0000-00-00 00:00:00' === $data[ $date_field ] ) {
 562              unset( $data[ $date_field ] );
 563          }
 564      }
 565  
 566      return $data;
 567  }
 568  
 569  /**
 570   * Validates data for a site prior to inserting or updating in the database.
 571   *
 572   * @since 5.1.0
 573   *
 574   * @param WP_Error     $errors   Error object, passed by reference. Will contain validation errors if
 575   *                               any occurred.
 576   * @param array        $data     Associative array of complete site data. See {@see wp_insert_site()}
 577   *                               for the included data.
 578   * @param WP_Site|null $old_site The old site object if the data belongs to a site being updated,
 579   *                               or null if it is a new site being inserted.
 580   */
 581  function wp_validate_site_data( $errors, $data, $old_site = null ) {
 582      // A domain must always be present.
 583      if ( empty( $data['domain'] ) ) {
 584          $errors->add( 'site_empty_domain', __( 'Site domain must not be empty.' ) );
 585      }
 586  
 587      // A path must always be present.
 588      if ( empty( $data['path'] ) ) {
 589          $errors->add( 'site_empty_path', __( 'Site path must not be empty.' ) );
 590      }
 591  
 592      // A network ID must always be present.
 593      if ( empty( $data['network_id'] ) ) {
 594          $errors->add( 'site_empty_network_id', __( 'Site network ID must be provided.' ) );
 595      }
 596  
 597      // Both registration and last updated dates must always be present and valid.
 598      $date_fields = array( 'registered', 'last_updated' );
 599      foreach ( $date_fields as $date_field ) {
 600          if ( empty( $data[ $date_field ] ) ) {
 601              $errors->add( 'site_empty_' . $date_field, __( 'Both registration and last updated dates must be provided.' ) );
 602              break;
 603          }
 604  
 605          // Allow '0000-00-00 00:00:00', although it be stripped out at this point.
 606          if ( '0000-00-00 00:00:00' !== $data[ $date_field ] ) {
 607              $month      = substr( $data[ $date_field ], 5, 2 );
 608              $day        = substr( $data[ $date_field ], 8, 2 );
 609              $year       = substr( $data[ $date_field ], 0, 4 );
 610              $valid_date = wp_checkdate( $month, $day, $year, $data[ $date_field ] );
 611              if ( ! $valid_date ) {
 612                  $errors->add( 'site_invalid_' . $date_field, __( 'Both registration and last updated dates must be valid dates.' ) );
 613                  break;
 614              }
 615          }
 616      }
 617  
 618      if ( ! empty( $errors->errors ) ) {
 619          return;
 620      }
 621  
 622      // If a new site, or domain/path/network ID have changed, ensure uniqueness.
 623      if ( ! $old_site
 624          || $data['domain'] !== $old_site->domain
 625          || $data['path'] !== $old_site->path
 626          || $data['network_id'] !== $old_site->network_id
 627      ) {
 628          if ( domain_exists( $data['domain'], $data['path'], $data['network_id'] ) ) {
 629              $errors->add( 'site_taken', __( 'Sorry, that site already exists!' ) );
 630          }
 631      }
 632  }
 633  
 634  /**
 635   * Runs the initialization routine for a given site.
 636   *
 637   * This process includes creating the site's database tables and
 638   * populating them with defaults.
 639   *
 640   * @since 5.1.0
 641   *
 642   * @global wpdb     $wpdb     WordPress database abstraction object.
 643   * @global WP_Roles $wp_roles WordPress role management object.
 644   *
 645   * @param int|WP_Site $site_id Site ID or object.
 646   * @param array       $args    {
 647   *     Optional. Arguments to modify the initialization behavior.
 648   *
 649   *     @type int    $user_id Required. User ID for the site administrator.
 650   *     @type string $title   Site title. Default is 'Site %d' where %d is the
 651   *                           site ID.
 652   *     @type array  $options Custom option $key => $value pairs to use. Default
 653   *                           empty array.
 654   *     @type array  $meta    Custom site metadata $key => $value pairs to use.
 655   *                           Default empty array.
 656   * }
 657   * @return true|WP_Error True on success, or error object on failure.
 658   */
 659  function wp_initialize_site( $site_id, array $args = array() ) {
 660      global $wpdb, $wp_roles;
 661  
 662      if ( empty( $site_id ) ) {
 663          return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
 664      }
 665  
 666      $site = get_site( $site_id );
 667      if ( ! $site ) {
 668          return new WP_Error( 'site_invalid_id', __( 'Site with the ID does not exist.' ) );
 669      }
 670  
 671      if ( wp_is_site_initialized( $site ) ) {
 672          return new WP_Error( 'site_already_initialized', __( 'The site appears to be already initialized.' ) );
 673      }
 674  
 675      $network = get_network( $site->network_id );
 676      if ( ! $network ) {
 677          $network = get_network();
 678      }
 679  
 680      $args = wp_parse_args(
 681          $args,
 682          array(
 683              'user_id' => 0,
 684              /* translators: %d: Site ID. */
 685              'title'   => sprintf( __( 'Site %d' ), $site->id ),
 686              'options' => array(),
 687              'meta'    => array(),
 688          )
 689      );
 690  
 691      /**
 692       * Filters the arguments for initializing a site.
 693       *
 694       * @since 5.1.0
 695       *
 696       * @param array      $args    Arguments to modify the initialization behavior.
 697       * @param WP_Site    $site    Site that is being initialized.
 698       * @param WP_Network $network Network that the site belongs to.
 699       */
 700      $args = apply_filters( 'wp_initialize_site_args', $args, $site, $network );
 701  
 702      $orig_installing = wp_installing();
 703      if ( ! $orig_installing ) {
 704          wp_installing( true );
 705      }
 706  
 707      $switch = false;
 708      if ( get_current_blog_id() !== $site->id ) {
 709          $switch = true;
 710          switch_to_blog( $site->id );
 711      }
 712  
 713      require_once  ABSPATH . 'wp-admin/includes/upgrade.php';
 714  
 715      // Set up the database tables.
 716      make_db_current_silent( 'blog' );
 717  
 718      $home_scheme    = 'http';
 719      $siteurl_scheme = 'http';
 720      if ( ! is_subdomain_install() ) {
 721          if ( 'https' === parse_url( get_home_url( $network->site_id ), PHP_URL_SCHEME ) ) {
 722              $home_scheme = 'https';
 723          }
 724          if ( 'https' === parse_url( get_network_option( $network->id, 'siteurl' ), PHP_URL_SCHEME ) ) {
 725              $siteurl_scheme = 'https';
 726          }
 727      }
 728  
 729      // Populate the site's options.
 730      populate_options(
 731          array_merge(
 732              array(
 733                  'home'        => untrailingslashit( $home_scheme . '://' . $site->domain . $site->path ),
 734                  'siteurl'     => untrailingslashit( $siteurl_scheme . '://' . $site->domain . $site->path ),
 735                  'blogname'    => wp_unslash( $args['title'] ),
 736                  'admin_email' => '',
 737                  'upload_path' => get_network_option( $network->id, 'ms_files_rewriting' ) ? UPLOADBLOGSDIR . "/{$site->id}/files" : get_blog_option( $network->site_id, 'upload_path' ),
 738                  'blog_public' => (int) $site->public,
 739                  'WPLANG'      => get_network_option( $network->id, 'WPLANG' ),
 740              ),
 741              $args['options']
 742          )
 743      );
 744  
 745      // Clean blog cache after populating options.
 746      clean_blog_cache( $site );
 747  
 748      // Populate the site's roles.
 749      populate_roles();
 750      $wp_roles = new WP_Roles();
 751  
 752      // Populate metadata for the site.
 753      populate_site_meta( $site->id, $args['meta'] );
 754  
 755      // Remove all permissions that may exist for the site.
 756      $table_prefix = $wpdb->get_blog_prefix();
 757      delete_metadata( 'user', 0, $table_prefix . 'user_level', null, true );   // Delete all.
 758      delete_metadata( 'user', 0, $table_prefix . 'capabilities', null, true ); // Delete all.
 759  
 760      // Install default site content.
 761      wp_install_defaults( $args['user_id'] );
 762  
 763      // Set the site administrator.
 764      add_user_to_blog( $site->id, $args['user_id'], 'administrator' );
 765      if ( ! user_can( $args['user_id'], 'manage_network' ) && ! get_user_meta( $args['user_id'], 'primary_blog', true ) ) {
 766          update_user_meta( $args['user_id'], 'primary_blog', $site->id );
 767      }
 768  
 769      if ( $switch ) {
 770          restore_current_blog();
 771      }
 772  
 773      wp_installing( $orig_installing );
 774  
 775      return true;
 776  }
 777  
 778  /**
 779   * Runs the uninitialization routine for a given site.
 780   *
 781   * This process includes dropping the site's database tables and deleting its uploads directory.
 782   *
 783   * @since 5.1.0
 784   *
 785   * @global wpdb $wpdb WordPress database abstraction object.
 786   *
 787   * @param int|WP_Site $site_id Site ID or object.
 788   * @return true|WP_Error True on success, or error object on failure.
 789   */
 790  function wp_uninitialize_site( $site_id ) {
 791      global $wpdb;
 792  
 793      if ( empty( $site_id ) ) {
 794          return new WP_Error( 'site_empty_id', __( 'Site ID must not be empty.' ) );
 795      }
 796  
 797      $site = get_site( $site_id );
 798      if ( ! $site ) {
 799          return new WP_Error( 'site_invalid_id', __( 'Site with the ID does not exist.' ) );
 800      }
 801  
 802      if ( ! wp_is_site_initialized( $site ) ) {
 803          return new WP_Error( 'site_already_uninitialized', __( 'The site appears to be already uninitialized.' ) );
 804      }
 805  
 806      $users = get_users(
 807          array(
 808              'blog_id' => $site->id,
 809              'fields'  => 'ids',
 810          )
 811      );
 812  
 813      // Remove users from the site.
 814      if ( ! empty( $users ) ) {
 815          foreach ( $users as $user_id ) {
 816              remove_user_from_blog( $user_id, $site->id );
 817          }
 818      }
 819  
 820      $switch = false;
 821      if ( get_current_blog_id() !== $site->id ) {
 822          $switch = true;
 823          switch_to_blog( $site->id );
 824      }
 825  
 826      $uploads = wp_get_upload_dir();
 827  
 828      $tables = $wpdb->tables( 'blog' );
 829  
 830      /**
 831       * Filters the tables to drop when the site is deleted.
 832       *
 833       * @since MU (3.0.0)
 834       *
 835       * @param string[] $tables  Array of names of the site tables to be dropped.
 836       * @param int      $site_id The ID of the site to drop tables for.
 837       */
 838      $drop_tables = apply_filters( 'wpmu_drop_tables', $tables, $site->id );
 839  
 840      foreach ( (array) $drop_tables as $table ) {
 841          $wpdb->query( "DROP TABLE IF EXISTS `$table`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
 842      }
 843  
 844      /**
 845       * Filters the upload base directory to delete when the site is deleted.
 846       *
 847       * @since MU (3.0.0)
 848       *
 849       * @param string $basedir Uploads path without subdirectory. See {@see wp_upload_dir()}.
 850       * @param int    $site_id The site ID.
 851       */
 852      $dir     = apply_filters( 'wpmu_delete_blog_upload_dir', $uploads['basedir'], $site->id );
 853      $dir     = rtrim( $dir, DIRECTORY_SEPARATOR );
 854      $top_dir = $dir;
 855      $stack   = array( $dir );
 856      $index   = 0;
 857  
 858      while ( $index < count( $stack ) ) {
 859          // Get indexed directory from stack.
 860          $dir = $stack[ $index ];
 861  
 862          // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
 863          $dh = @opendir( $dir );
 864          if ( $dh ) {
 865              $file = @readdir( $dh );
 866              while ( false !== $file ) {
 867                  if ( '.' === $file || '..' === $file ) {
 868                      $file = @readdir( $dh );
 869                      continue;
 870                  }
 871  
 872                  if ( @is_dir( $dir . DIRECTORY_SEPARATOR . $file ) ) {
 873                      $stack[] = $dir . DIRECTORY_SEPARATOR . $file;
 874                  } elseif ( @is_file( $dir . DIRECTORY_SEPARATOR . $file ) ) {
 875                      @unlink( $dir . DIRECTORY_SEPARATOR . $file );
 876                  }
 877  
 878                  $file = @readdir( $dh );
 879              }
 880              @closedir( $dh );
 881          }
 882          ++$index;
 883      }
 884  
 885      $stack = array_reverse( $stack ); // Last added directories are deepest.
 886      foreach ( (array) $stack as $dir ) {
 887          if ( $dir !== $top_dir ) {
 888              @rmdir( $dir );
 889          }
 890      }
 891  
 892      // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged
 893      if ( $switch ) {
 894          restore_current_blog();
 895      }
 896  
 897      return true;
 898  }
 899  
 900  /**
 901   * Checks whether a site is initialized.
 902   *
 903   * A site is considered initialized when its database tables are present.
 904   *
 905   * @since 5.1.0
 906   *
 907   * @global wpdb $wpdb WordPress database abstraction object.
 908   *
 909   * @param int|WP_Site $site_id Site ID or object.
 910   * @return bool True if the site is initialized, false otherwise.
 911   */
 912  function wp_is_site_initialized( $site_id ) {
 913      global $wpdb;
 914  
 915      if ( is_object( $site_id ) ) {
 916          $site_id = $site_id->blog_id;
 917      }
 918      $site_id = (int) $site_id;
 919  
 920      /**
 921       * Filters the check for whether a site is initialized before the database is accessed.
 922       *
 923       * Returning a non-null value will effectively short-circuit the function, returning
 924       * that value instead.
 925       *
 926       * @since 5.1.0
 927       *
 928       * @param bool|null $pre     The value to return instead. Default null
 929       *                           to continue with the check.
 930       * @param int       $site_id The site ID that is being checked.
 931       */
 932      $pre = apply_filters( 'pre_wp_is_site_initialized', null, $site_id );
 933      if ( null !== $pre ) {
 934          return (bool) $pre;
 935      }
 936  
 937      $switch = false;
 938      if ( get_current_blog_id() !== $site_id ) {
 939          $switch = true;
 940          remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 );
 941          switch_to_blog( $site_id );
 942      }
 943  
 944      $suppress = $wpdb->suppress_errors();
 945      $result   = (bool) $wpdb->get_results( "DESCRIBE {$wpdb->posts}" );
 946      $wpdb->suppress_errors( $suppress );
 947  
 948      if ( $switch ) {
 949          restore_current_blog();
 950          add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 );
 951      }
 952  
 953      return $result;
 954  }
 955  
 956  /**
 957   * Clean the blog cache
 958   *
 959   * @since 3.5.0
 960   *
 961   * @global bool $_wp_suspend_cache_invalidation
 962   *
 963   * @param WP_Site|int $blog The site object or ID to be cleared from cache.
 964   */
 965  function clean_blog_cache( $blog ) {
 966      global $_wp_suspend_cache_invalidation;
 967  
 968      if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
 969          return;
 970      }
 971  
 972      if ( empty( $blog ) ) {
 973          return;
 974      }
 975  
 976      $blog_id = $blog;
 977      $blog    = get_site( $blog_id );
 978      if ( ! $blog ) {
 979          if ( ! is_numeric( $blog_id ) ) {
 980              return;
 981          }
 982  
 983          // Make sure a WP_Site object exists even when the site has been deleted.
 984          $blog = new WP_Site(
 985              (object) array(
 986                  'blog_id' => $blog_id,
 987                  'domain'  => null,
 988                  'path'    => null,
 989              )
 990          );
 991      }
 992  
 993      $blog_id         = $blog->blog_id;
 994      $domain_path_key = md5( $blog->domain . $blog->path );
 995  
 996      wp_cache_delete( $blog_id, 'sites' );
 997      wp_cache_delete( $blog_id, 'site-details' );
 998      wp_cache_delete( $blog_id, 'blog-details' );
 999      wp_cache_delete( $blog_id . 'short', 'blog-details' );
1000      wp_cache_delete( $domain_path_key, 'blog-lookup' );
1001      wp_cache_delete( $domain_path_key, 'blog-id-cache' );
1002      wp_cache_delete( $blog_id, 'blog_meta' );
1003  
1004      /**
1005       * Fires immediately after a site has been removed from the object cache.
1006       *
1007       * @since 4.6.0
1008       *
1009       * @param string  $id              Site ID as a numeric string.
1010       * @param WP_Site $blog            Site object.
1011       * @param string  $domain_path_key md5 hash of domain and path.
1012       */
1013      do_action( 'clean_site_cache', $blog_id, $blog, $domain_path_key );
1014  
1015      wp_cache_set_sites_last_changed();
1016  
1017      /**
1018       * Fires after the blog details cache is cleared.
1019       *
1020       * @since 3.4.0
1021       * @deprecated 4.9.0 Use {@see 'clean_site_cache'} instead.
1022       *
1023       * @param int $blog_id Blog ID.
1024       */
1025      do_action_deprecated( 'refresh_blog_details', array( $blog_id ), '4.9.0', 'clean_site_cache' );
1026  }
1027  
1028  /**
1029   * Adds metadata to a site.
1030   *
1031   * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
1032   *
1033   * @since 5.1.0
1034   *
1035   * @param int    $site_id    Site ID.
1036   * @param string $meta_key   Metadata name.
1037   * @param mixed  $meta_value Metadata value. Arrays and objects are stored as serialized data and
1038   *                           will be returned as the same type when retrieved. Other data types will
1039   *                           be stored as strings in the database:
1040   *                           - false is stored and retrieved as an empty string ('')
1041   *                           - true is stored and retrieved as '1'
1042   *                           - numbers (both integer and float) are stored and retrieved as strings
1043   *                           Must be serializable if non-scalar.
1044   * @param bool   $unique     Optional. Whether the same key should not be added.
1045   *                           Default false.
1046   * @return int|false Meta ID on success, false on failure.
1047   */
1048  function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
1049      return add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique );
1050  }
1051  
1052  /**
1053   * Removes metadata matching criteria from a site.
1054   *
1055   * You can match based on the key, or key and value. Removing based on key and
1056   * value, will keep from removing duplicate metadata with the same key. It also
1057   * allows removing all metadata matching key, if needed.
1058   *
1059   * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
1060   *
1061   * @since 5.1.0
1062   *
1063   * @param int    $site_id    Site ID.
1064   * @param string $meta_key   Metadata name.
1065   * @param mixed  $meta_value Optional. Metadata value. If provided,
1066   *                           rows will only be removed that match the value.
1067   *                           Must be serializable if non-scalar. Default empty.
1068   * @return bool True on success, false on failure.
1069   *
1070   * @phpstan-param positive-int $site_id
1071   */
1072  function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
1073      return delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
1074  }
1075  
1076  /**
1077   * Retrieves metadata for a site.
1078   *
1079   * @since 5.1.0
1080   *
1081   * @param int    $site_id Site ID.
1082   * @param string $key     Optional. The meta key to retrieve. By default,
1083   *                        returns data for all keys. Default empty.
1084   * @param bool   $single  Optional. Whether to return a single value.
1085   *                        This parameter has no effect if `$key` is not specified.
1086   *                        Default false.
1087   * @return mixed An array of values if `$single` is false.
1088   *               The value of meta data field if `$single` is true.
1089   *               False for an invalid `$site_id` (non-numeric, zero, or negative value).
1090   *               An empty array if a valid but non-existing site ID is passed and `$single` is false.
1091   *               An empty string if a valid but non-existing site ID is passed and `$single` is true.
1092   *               Note: Non-serialized values are returned as strings:
1093   *               - false values are returned as empty strings ('')
1094   *               - true values are returned as '1'
1095   *               - numbers (both integer and float) are returned as strings
1096   *               Arrays and objects retain their original type.
1097   *               These conversions apply to stored values. A default value registered
1098   *               with {@see register_meta()} is never stored, so it is returned with
1099   *               the type it was registered with, which may be an integer, float, or
1100   *               boolean.
1101   *
1102   * @phpstan-return (
1103   *     $key is ''|'0'
1104   *         ? array<array-key, list<string>>|false
1105   *         : ( $single is true
1106   *             ? mixed
1107   *             : list<mixed>|false )
1108   * )
1109   */
1110  function get_site_meta( $site_id, $key = '', $single = false ) {
1111      return get_metadata( 'blog', $site_id, $key, $single );
1112  }
1113  
1114  /**
1115   * Updates metadata for a site.
1116   *
1117   * Use the `$prev_value` parameter to differentiate between meta fields with the
1118   * same key and site ID.
1119   *
1120   * If the meta field for the site does not exist, it will be added.
1121   *
1122   * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
1123   *
1124   * @since 5.1.0
1125   *
1126   * @param int    $site_id    Site ID.
1127   * @param string $meta_key   Metadata key.
1128   * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
1129   * @param mixed  $prev_value Optional. Previous value to check before updating.
1130   *                           If specified, only update existing metadata entries with
1131   *                           this value. Otherwise, update all entries. Default empty.
1132   * @return int|bool Meta ID if the key didn't exist, true on successful update,
1133   *                  false on failure or if the value passed to the function
1134   *                  is the same as the one that is already in the database.
1135   */
1136  function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) {
1137      return update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value );
1138  }
1139  
1140  /**
1141   * Deletes everything from site meta matching meta key.
1142   *
1143   * @since 5.1.0
1144   *
1145   * @param string $meta_key Metadata key to search for when deleting.
1146   * @return bool Whether the site meta key was deleted from the database.
1147   */
1148  function delete_site_meta_by_key( $meta_key ) {
1149      return delete_metadata( 'blog', 0, $meta_key, '', true );
1150  }
1151  
1152  /**
1153   * Registers a meta key for sites.
1154   *
1155   * @since 7.2.0
1156   *
1157   * @param string $meta_key The meta key to register.
1158   * @param array  $args     Data used to describe the meta key when registered. See
1159   *                         {@see register_meta()} for a list of supported arguments.
1160   * @return bool True if the meta key was successfully registered, false if not.
1161   */
1162  function register_site_meta( $meta_key, array $args ) {
1163      return register_meta( 'blog', $meta_key, $args );
1164  }
1165  
1166  /**
1167   * Unregisters a meta key for sites.
1168   *
1169   * @since 7.2.0
1170   *
1171   * @param string $meta_key The meta key to unregister.
1172   * @return bool True on success, false if the meta key was not previously registered.
1173   */
1174  function unregister_site_meta( $meta_key ) {
1175      return unregister_meta_key( 'blog', $meta_key );
1176  }
1177  
1178  /**
1179   * Updates the count of sites for a network based on a changed site.
1180   *
1181   * @since 5.1.0
1182   *
1183   * @param WP_Site      $new_site The site object that has been inserted, updated or deleted.
1184   * @param WP_Site|null $old_site Optional. If $new_site has been updated, this must be the previous
1185   *                               state of that site. Default null.
1186   */
1187  function wp_maybe_update_network_site_counts_on_update( $new_site, $old_site = null ) {
1188      if ( null === $old_site ) {
1189          wp_maybe_update_network_site_counts( $new_site->network_id );
1190          return;
1191      }
1192  
1193      if ( $new_site->network_id !== $old_site->network_id ) {
1194          wp_maybe_update_network_site_counts( $new_site->network_id );
1195          wp_maybe_update_network_site_counts( $old_site->network_id );
1196      }
1197  }
1198  
1199  /**
1200   * Triggers actions on site status updates.
1201   *
1202   * @since 5.1.0
1203   *
1204   * @param WP_Site      $new_site The site object after the update.
1205   * @param WP_Site|null $old_site Optional. If $new_site has been updated, this must be the previous
1206   *                               state of that site. Default null.
1207   */
1208  function wp_maybe_transition_site_statuses_on_update( $new_site, $old_site = null ) {
1209      $site_id = $new_site->id;
1210  
1211      // Use the default values for a site if no previous state is given.
1212      if ( ! $old_site ) {
1213          $old_site = new WP_Site( new stdClass() );
1214      }
1215  
1216      if ( $new_site->spam !== $old_site->spam ) {
1217          if ( '1' === $new_site->spam ) {
1218  
1219              /**
1220               * Fires when the 'spam' status is added to a site.
1221               *
1222               * @since MU (3.0.0)
1223               *
1224               * @param int $site_id Site ID.
1225               */
1226              do_action( 'make_spam_blog', $site_id );
1227          } else {
1228  
1229              /**
1230               * Fires when the 'spam' status is removed from a site.
1231               *
1232               * @since MU (3.0.0)
1233               *
1234               * @param int $site_id Site ID.
1235               */
1236              do_action( 'make_ham_blog', $site_id );
1237          }
1238      }
1239  
1240      if ( $new_site->mature !== $old_site->mature ) {
1241          if ( '1' === $new_site->mature ) {
1242  
1243              /**
1244               * Fires when the 'mature' status is added to a site.
1245               *
1246               * @since 3.1.0
1247               *
1248               * @param int $site_id Site ID.
1249               */
1250              do_action( 'mature_blog', $site_id );
1251          } else {
1252  
1253              /**
1254               * Fires when the 'mature' status is removed from a site.
1255               *
1256               * @since 3.1.0
1257               *
1258               * @param int $site_id Site ID.
1259               */
1260              do_action( 'unmature_blog', $site_id );
1261          }
1262      }
1263  
1264      if ( $new_site->archived !== $old_site->archived ) {
1265          if ( '1' === $new_site->archived ) {
1266  
1267              /**
1268               * Fires when the 'archived' status is added to a site.
1269               *
1270               * @since MU (3.0.0)
1271               *
1272               * @param int $site_id Site ID.
1273               */
1274              do_action( 'archive_blog', $site_id );
1275          } else {
1276  
1277              /**
1278               * Fires when the 'archived' status is removed from a site.
1279               *
1280               * @since MU (3.0.0)
1281               *
1282               * @param int $site_id Site ID.
1283               */
1284              do_action( 'unarchive_blog', $site_id );
1285          }
1286      }
1287  
1288      if ( $new_site->deleted !== $old_site->deleted ) {
1289          if ( '1' === $new_site->deleted ) {
1290  
1291              /**
1292               * Fires when the 'flagged for deletion' status is added to a site.
1293               *
1294               * @since 3.5.0
1295               *
1296               * @param int $site_id Site ID.
1297               */
1298              do_action( 'make_delete_blog', $site_id );
1299          } else {
1300  
1301              /**
1302               * Fires when the 'flagged for deletion' status is removed from a site.
1303               *
1304               * @since 3.5.0
1305               *
1306               * @param int $site_id Site ID.
1307               */
1308              do_action( 'make_undelete_blog', $site_id );
1309          }
1310      }
1311  
1312      if ( $new_site->public !== $old_site->public ) {
1313  
1314          /**
1315           * Fires after the current blog's 'public' setting is updated.
1316           *
1317           * @since MU (3.0.0)
1318           *
1319           * @param int    $site_id   Site ID.
1320           * @param string $is_public Whether the site is public. A numeric string,
1321           *                          for compatibility reasons. Accepts '1' or '0'.
1322           */
1323          do_action( 'update_blog_public', $site_id, $new_site->public );
1324      }
1325  }
1326  
1327  /**
1328   * Cleans the necessary caches after specific site data has been updated.
1329   *
1330   * @since 5.1.0
1331   *
1332   * @param WP_Site $new_site The site object after the update.
1333   * @param WP_Site $old_site The site object prior to the update.
1334   */
1335  function wp_maybe_clean_new_site_cache_on_update( $new_site, $old_site ) {
1336      if ( $old_site->domain !== $new_site->domain || $old_site->path !== $new_site->path ) {
1337          clean_blog_cache( $new_site );
1338      }
1339  }
1340  
1341  /**
1342   * Updates the `blog_public` option for a given site ID.
1343   *
1344   * @since 5.1.0
1345   *
1346   * @param int    $site_id   Site ID.
1347   * @param string $is_public Whether the site is public. A numeric string,
1348   *                          for compatibility reasons. Accepts '1' or '0'.
1349   */
1350  function wp_update_blog_public_option_on_site_update( $site_id, $is_public ) {
1351  
1352      // Bail if the site's database tables do not exist (yet).
1353      if ( ! wp_is_site_initialized( $site_id ) ) {
1354          return;
1355      }
1356  
1357      update_blog_option( $site_id, 'blog_public', $is_public );
1358  }
1359  
1360  /**
1361   * Sets the last changed time for the 'sites' cache group.
1362   *
1363   * @since 5.1.0
1364   */
1365  function wp_cache_set_sites_last_changed() {
1366      wp_cache_set_last_changed( 'sites' );
1367  }
1368  
1369  /**
1370   * Aborts calls to site meta if it is not supported.
1371   *
1372   * @since 5.1.0
1373   *
1374   * @global wpdb $wpdb WordPress database abstraction object.
1375   *
1376   * @param mixed $check Skip-value for whether to proceed site meta function execution.
1377   * @return mixed Original value of $check, or false if site meta is not supported.
1378   */
1379  function wp_check_site_meta_support_prefilter( $check ) {
1380      if ( ! is_site_meta_supported() ) {
1381          /* translators: %s: Database table name. */
1382          _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.1.0' );
1383          return false;
1384      }
1385  
1386      return $check;
1387  }


Generated : Sat Oct 3 08:20:34 2026 Cross-referenced by PHPXref