[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/includes/ -> schema.php (source)

   1  <?php
   2  /**
   3   * WordPress Administration Scheme API
   4   *
   5   * Here we keep the DB structure and option values.
   6   *
   7   * @package WordPress
   8   * @subpackage Administration
   9   */
  10  
  11  /**
  12   * Declare these as global in case schema.php is included from a function.
  13   *
  14   * @global wpdb   $wpdb            WordPress database abstraction object.
  15   * @global array  $wp_queries      Global database queries array.
  16   * @global string $charset_collate Database charset and collation.
  17   */
  18  global $wpdb, $wp_queries, $charset_collate;
  19  
  20  /**
  21   * The database character collate.
  22   */
  23  $charset_collate = $wpdb->get_charset_collate();
  24  
  25  /**
  26   * Retrieve the SQL for creating database tables.
  27   *
  28   * @since 3.3.0
  29   *
  30   * @global wpdb $wpdb WordPress database abstraction object.
  31   *
  32   * @param string $scope   Optional. The tables for which to retrieve SQL. Can be all, global, ms_global, or blog tables. Defaults to all.
  33   * @param int    $blog_id Optional. The site ID for which to retrieve SQL. Default is the current site ID.
  34   * @return string The SQL needed to create the requested tables.
  35   */
  36  function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
  37      global $wpdb;
  38  
  39      $charset_collate = $wpdb->get_charset_collate();
  40  
  41      if ( $blog_id && (int) $blog_id !== $wpdb->blogid ) {
  42          $old_blog_id = $wpdb->set_blog_id( $blog_id );
  43      }
  44  
  45      // Engage multisite if in the middle of turning it on from network.php.
  46      $is_multisite = is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK );
  47  
  48      /*
  49       * Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
  50       * As of 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
  51       * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
  52       */
  53      $max_index_length = 191;
  54  
  55      // Blog-specific tables.
  56      $blog_tables = "CREATE TABLE $wpdb->termmeta (
  57      meta_id bigint(20) unsigned NOT NULL auto_increment,
  58      term_id bigint(20) unsigned NOT NULL default '0',
  59      meta_key varchar(255) default NULL,
  60      meta_value longtext,
  61      PRIMARY KEY  (meta_id),
  62      KEY term_id (term_id),
  63      KEY meta_key (meta_key($max_index_length))
  64  ) $charset_collate;
  65  CREATE TABLE $wpdb->terms (
  66   term_id bigint(20) unsigned NOT NULL auto_increment,
  67   name varchar(200) NOT NULL default '',
  68   slug varchar(200) NOT NULL default '',
  69   term_group bigint(10) NOT NULL default 0,
  70   PRIMARY KEY  (term_id),
  71   KEY slug (slug($max_index_length)),
  72   KEY name (name($max_index_length))
  73  ) $charset_collate;
  74  CREATE TABLE $wpdb->term_taxonomy (
  75   term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment,
  76   term_id bigint(20) unsigned NOT NULL default 0,
  77   taxonomy varchar(32) NOT NULL default '',
  78   description longtext NOT NULL,
  79   parent bigint(20) unsigned NOT NULL default 0,
  80   count bigint(20) NOT NULL default 0,
  81   PRIMARY KEY  (term_taxonomy_id),
  82   UNIQUE KEY term_id_taxonomy (term_id,taxonomy),
  83   KEY taxonomy (taxonomy)
  84  ) $charset_collate;
  85  CREATE TABLE $wpdb->term_relationships (
  86   object_id bigint(20) unsigned NOT NULL default 0,
  87   term_taxonomy_id bigint(20) unsigned NOT NULL default 0,
  88   term_order int(11) NOT NULL default 0,
  89   PRIMARY KEY  (object_id,term_taxonomy_id),
  90   KEY term_taxonomy_id (term_taxonomy_id)
  91  ) $charset_collate;
  92  CREATE TABLE $wpdb->commentmeta (
  93      meta_id bigint(20) unsigned NOT NULL auto_increment,
  94      comment_id bigint(20) unsigned NOT NULL default '0',
  95      meta_key varchar(255) default NULL,
  96      meta_value longtext,
  97      PRIMARY KEY  (meta_id),
  98      KEY comment_id (comment_id),
  99      KEY meta_key (meta_key($max_index_length))
 100  ) $charset_collate;
 101  CREATE TABLE $wpdb->comments (
 102      comment_ID bigint(20) unsigned NOT NULL auto_increment,
 103      comment_post_ID bigint(20) unsigned NOT NULL default '0',
 104      comment_author tinytext NOT NULL,
 105      comment_author_email varchar(100) NOT NULL default '',
 106      comment_author_url varchar(200) NOT NULL default '',
 107      comment_author_IP varchar(100) NOT NULL default '',
 108      comment_date datetime NOT NULL default '0000-00-00 00:00:00',
 109      comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
 110      comment_content text NOT NULL,
 111      comment_karma int(11) NOT NULL default '0',
 112      comment_approved varchar(20) NOT NULL default '1',
 113      comment_agent varchar(255) NOT NULL default '',
 114      comment_type varchar(20) NOT NULL default 'comment',
 115      comment_parent bigint(20) unsigned NOT NULL default '0',
 116      user_id bigint(20) unsigned NOT NULL default '0',
 117      PRIMARY KEY  (comment_ID),
 118      KEY comment_post_ID (comment_post_ID),
 119      KEY comment_approved_date_gmt (comment_approved,comment_date_gmt),
 120      KEY comment_date_gmt (comment_date_gmt),
 121      KEY comment_parent (comment_parent),
 122      KEY comment_author_email (comment_author_email(10))
 123  ) $charset_collate;
 124  CREATE TABLE $wpdb->links (
 125      link_id bigint(20) unsigned NOT NULL auto_increment,
 126      link_url varchar(255) NOT NULL default '',
 127      link_name varchar(255) NOT NULL default '',
 128      link_image varchar(255) NOT NULL default '',
 129      link_target varchar(25) NOT NULL default '',
 130      link_description varchar(255) NOT NULL default '',
 131      link_visible varchar(20) NOT NULL default 'Y',
 132      link_owner bigint(20) unsigned NOT NULL default '1',
 133      link_rating int(11) NOT NULL default '0',
 134      link_updated datetime NOT NULL default '0000-00-00 00:00:00',
 135      link_rel varchar(255) NOT NULL default '',
 136      link_notes mediumtext NOT NULL,
 137      link_rss varchar(255) NOT NULL default '',
 138      PRIMARY KEY  (link_id),
 139      KEY link_visible (link_visible)
 140  ) $charset_collate;
 141  CREATE TABLE $wpdb->options (
 142      option_id bigint(20) unsigned NOT NULL auto_increment,
 143      option_name varchar(191) NOT NULL default '',
 144      option_value longtext NOT NULL,
 145      autoload varchar(20) NOT NULL default 'yes',
 146      PRIMARY KEY  (option_id),
 147      UNIQUE KEY option_name (option_name),
 148      KEY autoload (autoload)
 149  ) $charset_collate;
 150  CREATE TABLE $wpdb->postmeta (
 151      meta_id bigint(20) unsigned NOT NULL auto_increment,
 152      post_id bigint(20) unsigned NOT NULL default '0',
 153      meta_key varchar(255) default NULL,
 154      meta_value longtext,
 155      PRIMARY KEY  (meta_id),
 156      KEY post_id (post_id),
 157      KEY meta_key (meta_key($max_index_length))
 158  ) $charset_collate;
 159  CREATE TABLE $wpdb->posts (
 160      ID bigint(20) unsigned NOT NULL auto_increment,
 161      post_author bigint(20) unsigned NOT NULL default '0',
 162      post_date datetime NOT NULL default '0000-00-00 00:00:00',
 163      post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
 164      post_content longtext NOT NULL,
 165      post_title text NOT NULL,
 166      post_excerpt text NOT NULL,
 167      post_status varchar(20) NOT NULL default 'publish',
 168      comment_status varchar(20) NOT NULL default 'open',
 169      ping_status varchar(20) NOT NULL default 'open',
 170      post_password varchar(255) NOT NULL default '',
 171      post_name varchar(200) NOT NULL default '',
 172      to_ping text NOT NULL,
 173      pinged text NOT NULL,
 174      post_modified datetime NOT NULL default '0000-00-00 00:00:00',
 175      post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
 176      post_content_filtered longtext NOT NULL,
 177      post_parent bigint(20) unsigned NOT NULL default '0',
 178      guid varchar(255) NOT NULL default '',
 179      menu_order int(11) NOT NULL default '0',
 180      post_type varchar(20) NOT NULL default 'post',
 181      post_mime_type varchar(100) NOT NULL default '',
 182      comment_count bigint(20) NOT NULL default '0',
 183      PRIMARY KEY  (ID),
 184      KEY post_name (post_name($max_index_length)),
 185      KEY type_status_date (post_type,post_status,post_date,ID),
 186      KEY post_parent (post_parent),
 187      KEY post_author (post_author),
 188      KEY type_status_author (post_type,post_status,post_author)
 189  ) $charset_collate;\n";
 190  
 191      // Single site users table. The multisite flavor of the users table is handled below.
 192      $users_single_table = "CREATE TABLE $wpdb->users (
 193      ID bigint(20) unsigned NOT NULL auto_increment,
 194      user_login varchar(60) NOT NULL default '',
 195      user_pass varchar(255) NOT NULL default '',
 196      user_nicename varchar(50) NOT NULL default '',
 197      user_email varchar(100) NOT NULL default '',
 198      user_url varchar(100) NOT NULL default '',
 199      user_registered datetime NOT NULL default '0000-00-00 00:00:00',
 200      user_activation_key varchar(255) NOT NULL default '',
 201      user_status int(11) NOT NULL default '0',
 202      display_name varchar(250) NOT NULL default '',
 203      PRIMARY KEY  (ID),
 204      KEY user_login_key (user_login),
 205      KEY user_nicename (user_nicename),
 206      KEY user_email (user_email)
 207  ) $charset_collate;\n";
 208  
 209      // Multisite users table.
 210      $users_multi_table = "CREATE TABLE $wpdb->users (
 211      ID bigint(20) unsigned NOT NULL auto_increment,
 212      user_login varchar(60) NOT NULL default '',
 213      user_pass varchar(255) NOT NULL default '',
 214      user_nicename varchar(50) NOT NULL default '',
 215      user_email varchar(100) NOT NULL default '',
 216      user_url varchar(100) NOT NULL default '',
 217      user_registered datetime NOT NULL default '0000-00-00 00:00:00',
 218      user_activation_key varchar(255) NOT NULL default '',
 219      user_status int(11) NOT NULL default '0',
 220      display_name varchar(250) NOT NULL default '',
 221      spam tinyint(2) NOT NULL default '0',
 222      deleted tinyint(2) NOT NULL default '0',
 223      PRIMARY KEY  (ID),
 224      KEY user_login_key (user_login),
 225      KEY user_nicename (user_nicename),
 226      KEY user_email (user_email)
 227  ) $charset_collate;\n";
 228  
 229      // Usermeta.
 230      $usermeta_table = "CREATE TABLE $wpdb->usermeta (
 231      umeta_id bigint(20) unsigned NOT NULL auto_increment,
 232      user_id bigint(20) unsigned NOT NULL default '0',
 233      meta_key varchar(255) default NULL,
 234      meta_value longtext,
 235      PRIMARY KEY  (umeta_id),
 236      KEY user_id (user_id),
 237      KEY meta_key (meta_key($max_index_length))
 238  ) $charset_collate;\n";
 239  
 240      // Global tables.
 241      if ( $is_multisite ) {
 242          $global_tables = $users_multi_table . $usermeta_table;
 243      } else {
 244          $global_tables = $users_single_table . $usermeta_table;
 245      }
 246  
 247      // Multisite global tables.
 248      $ms_global_tables = "CREATE TABLE $wpdb->blogs (
 249      blog_id bigint(20) unsigned NOT NULL auto_increment,
 250      site_id bigint(20) unsigned NOT NULL default '0',
 251      domain varchar(200) NOT NULL default '',
 252      path varchar(100) NOT NULL default '',
 253      registered datetime NOT NULL default '0000-00-00 00:00:00',
 254      last_updated datetime NOT NULL default '0000-00-00 00:00:00',
 255      public tinyint(2) NOT NULL default '1',
 256      archived tinyint(2) NOT NULL default '0',
 257      mature tinyint(2) NOT NULL default '0',
 258      spam tinyint(2) NOT NULL default '0',
 259      deleted tinyint(2) NOT NULL default '0',
 260      lang_id int(11) NOT NULL default '0',
 261      PRIMARY KEY  (blog_id),
 262      KEY domain (domain(50),path(5)),
 263      KEY lang_id (lang_id)
 264  ) $charset_collate;
 265  CREATE TABLE $wpdb->blogmeta (
 266      meta_id bigint(20) unsigned NOT NULL auto_increment,
 267      blog_id bigint(20) unsigned NOT NULL default '0',
 268      meta_key varchar(255) default NULL,
 269      meta_value longtext,
 270      PRIMARY KEY  (meta_id),
 271      KEY meta_key (meta_key($max_index_length)),
 272      KEY blog_id (blog_id)
 273  ) $charset_collate;
 274  CREATE TABLE $wpdb->registration_log (
 275      ID bigint(20) unsigned NOT NULL auto_increment,
 276      email varchar(255) NOT NULL default '',
 277      IP varchar(30) NOT NULL default '',
 278      blog_id bigint(20) unsigned NOT NULL default '0',
 279      date_registered datetime NOT NULL default '0000-00-00 00:00:00',
 280      PRIMARY KEY  (ID),
 281      KEY IP (IP)
 282  ) $charset_collate;
 283  CREATE TABLE $wpdb->site (
 284      id bigint(20) unsigned NOT NULL auto_increment,
 285      domain varchar(200) NOT NULL default '',
 286      path varchar(100) NOT NULL default '',
 287      PRIMARY KEY  (id),
 288      KEY domain (domain(140),path(51))
 289  ) $charset_collate;
 290  CREATE TABLE $wpdb->sitemeta (
 291      meta_id bigint(20) unsigned NOT NULL auto_increment,
 292      site_id bigint(20) unsigned NOT NULL default '0',
 293      meta_key varchar(255) default NULL,
 294      meta_value longtext,
 295      PRIMARY KEY  (meta_id),
 296      KEY meta_key (meta_key($max_index_length)),
 297      KEY site_id (site_id)
 298  ) $charset_collate;
 299  CREATE TABLE $wpdb->signups (
 300      signup_id bigint(20) unsigned NOT NULL auto_increment,
 301      domain varchar(200) NOT NULL default '',
 302      path varchar(100) NOT NULL default '',
 303      title longtext NOT NULL,
 304      user_login varchar(60) NOT NULL default '',
 305      user_email varchar(100) NOT NULL default '',
 306      registered datetime NOT NULL default '0000-00-00 00:00:00',
 307      activated datetime NOT NULL default '0000-00-00 00:00:00',
 308      active tinyint(1) NOT NULL default '0',
 309      activation_key varchar(50) NOT NULL default '',
 310      meta longtext,
 311      PRIMARY KEY  (signup_id),
 312      KEY activation_key (activation_key),
 313      KEY user_email (user_email),
 314      KEY user_login_email (user_login,user_email),
 315      KEY domain_path (domain(140),path(51))
 316  ) $charset_collate;";
 317  
 318      switch ( $scope ) {
 319          case 'blog':
 320              $queries = $blog_tables;
 321              break;
 322          case 'global':
 323              $queries = $global_tables;
 324              if ( $is_multisite ) {
 325                  $queries .= $ms_global_tables;
 326              }
 327              break;
 328          case 'ms_global':
 329              $queries = $ms_global_tables;
 330              break;
 331          case 'all':
 332          default:
 333              $queries = $global_tables . $blog_tables;
 334              if ( $is_multisite ) {
 335                  $queries .= $ms_global_tables;
 336              }
 337              break;
 338      }
 339  
 340      if ( isset( $old_blog_id ) ) {
 341          $wpdb->set_blog_id( $old_blog_id );
 342      }
 343  
 344      return $queries;
 345  }
 346  
 347  // Populate for back compat.
 348  $wp_queries = wp_get_db_schema( 'all' );
 349  
 350  /**
 351   * Create WordPress options and set the default values.
 352   *
 353   * @since 1.5.0
 354   * @since 5.1.0 The $options parameter has been added.
 355   *
 356   * @global wpdb $wpdb                  WordPress database abstraction object.
 357   * @global int  $wp_db_version         WordPress database version.
 358   * @global int  $wp_current_db_version The old (current) database version.
 359   *
 360   * @param array $options Optional. Custom option $key => $value pairs to use. Default empty array.
 361   */
 362  function populate_options( array $options = array() ) {
 363      global $wpdb, $wp_db_version, $wp_current_db_version;
 364  
 365      $guessurl = wp_guess_url();
 366      /**
 367       * Fires before creating WordPress options and populating their default values.
 368       *
 369       * @since 2.6.0
 370       */
 371      do_action( 'populate_options' );
 372  
 373      // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
 374      $stylesheet = WP_DEFAULT_THEME;
 375      $template   = WP_DEFAULT_THEME;
 376      $theme      = wp_get_theme( WP_DEFAULT_THEME );
 377      if ( ! $theme->exists() ) {
 378          $theme = WP_Theme::get_core_default_theme();
 379      }
 380  
 381      // If we can't find a core default theme, WP_DEFAULT_THEME is the best we can do.
 382      if ( $theme ) {
 383          $stylesheet = $theme->get_stylesheet();
 384          $template   = $theme->get_template();
 385      }
 386  
 387      $timezone_string = '';
 388      $gmt_offset      = 0;
 389      /*
 390       * translators: default GMT offset or timezone string. Must be either a valid offset (-12 to 14)
 391       * or a valid timezone string (America/New_York). See https://www.php.net/manual/en/timezones.php
 392       * for all timezone strings currently supported by PHP.
 393       *
 394       * Important: When a previous timezone string, like `Europe/Kiev`, has been superseded by an
 395       * updated one, like `Europe/Kyiv`, as a rule of thumb, the **old** timezone name should be used
 396       * in the "translation" to allow for the default timezone setting to be PHP cross-version compatible,
 397       * as old timezone names will be recognized in new PHP versions, while new timezone names cannot
 398       * be recognized in old PHP versions.
 399       *
 400       * To verify which timezone strings are available in the _oldest_ PHP version supported, you can
 401       * use https://3v4l.org/6YQAt#v5.6.20 and replace the "BR" (Brazil) in the code line with the
 402       * country code for which you want to look up the supported timezone names.
 403       */
 404      $offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
 405      if ( is_numeric( $offset_or_tz ) ) {
 406          $gmt_offset = $offset_or_tz;
 407      } elseif ( $offset_or_tz && in_array( $offset_or_tz, timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true ) ) {
 408          $timezone_string = $offset_or_tz;
 409      }
 410  
 411      $defaults = array(
 412          'siteurl'                         => $guessurl,
 413          'home'                            => $guessurl,
 414          'blogname'                        => __( 'My Site' ),
 415          'blogdescription'                 => '',
 416          'users_can_register'              => 0,
 417          'admin_email'                     => 'you@example.com',
 418          /* translators: Default start of the week. 0 = Sunday, 1 = Monday. */
 419          'start_of_week'                   => _x( '1', 'start of week' ),
 420          'use_balanceTags'                 => 0,
 421          'use_smilies'                     => 1,
 422          'require_name_email'              => 1,
 423          'comments_notify'                 => 1,
 424          'posts_per_rss'                   => 10,
 425          'rss_use_excerpt'                 => 0,
 426          'mailserver_url'                  => 'mail.example.com',
 427          'mailserver_login'                => 'login@example.com',
 428          'mailserver_pass'                 => '',
 429          'mailserver_port'                 => 110,
 430          'default_category'                => 1,
 431          'default_comment_status'          => 'open',
 432          'default_ping_status'             => 'open',
 433          'default_pingback_flag'           => 1,
 434          'posts_per_page'                  => 10,
 435          /* translators: Default date format, see https://www.php.net/manual/datetime.format.php */
 436          'date_format'                     => __( 'F j, Y' ),
 437          /* translators: Default time format, see https://www.php.net/manual/datetime.format.php */
 438          'time_format'                     => __( 'g:i a' ),
 439          /* translators: Links last updated date format, see https://www.php.net/manual/datetime.format.php */
 440          'links_updated_date_format'       => __( 'F j, Y g:i a' ),
 441          'comment_moderation'              => 0,
 442          'moderation_notify'               => 1,
 443          'permalink_structure'             => '',
 444          'rewrite_rules'                   => '',
 445          'hack_file'                       => 0,
 446          'blog_charset'                    => 'UTF-8',
 447          'moderation_keys'                 => '',
 448          'active_plugins'                  => array(),
 449          'category_base'                   => '',
 450          'ping_sites'                      => 'https://rpc.pingomatic.com/',
 451          'comment_max_links'               => 2,
 452          'gmt_offset'                      => $gmt_offset,
 453  
 454          // 1.5.0
 455          'default_email_category'          => 1,
 456          'recently_edited'                 => '',
 457          'template'                        => $template,
 458          'stylesheet'                      => $stylesheet,
 459          'comment_registration'            => 0,
 460          'html_type'                       => 'text/html',
 461  
 462          // 1.5.1
 463          'use_trackback'                   => 0,
 464  
 465          // 2.0.0
 466          'default_role'                    => 'subscriber',
 467          'db_version'                      => $wp_db_version,
 468  
 469          // 2.0.1
 470          'uploads_use_yearmonth_folders'   => 1,
 471          'upload_path'                     => '',
 472  
 473          // 2.1.0
 474          'blog_public'                     => '1',
 475          'default_link_category'           => 2,
 476          'show_on_front'                   => 'posts',
 477  
 478          // 2.2.0
 479          'tag_base'                        => '',
 480  
 481          // 2.5.0
 482          'show_avatars'                    => '1',
 483          'avatar_rating'                   => 'G',
 484          'upload_url_path'                 => '',
 485          'thumbnail_size_w'                => 150,
 486          'thumbnail_size_h'                => 150,
 487          'thumbnail_crop'                  => 1,
 488          'medium_size_w'                   => 300,
 489          'medium_size_h'                   => 300,
 490  
 491          // 2.6.0
 492          'avatar_default'                  => 'mystery',
 493  
 494          // 2.7.0
 495          'large_size_w'                    => 1024,
 496          'large_size_h'                    => 1024,
 497          'image_default_link_type'         => 'none',
 498          'image_default_size'              => '',
 499          'image_default_align'             => '',
 500          'close_comments_for_old_posts'    => 0,
 501          'close_comments_days_old'         => 14,
 502          'thread_comments'                 => 1,
 503          'thread_comments_depth'           => 5,
 504          'page_comments'                   => 0,
 505          'comments_per_page'               => 50,
 506          'default_comments_page'           => 'newest',
 507          'comment_order'                   => 'asc',
 508          'sticky_posts'                    => array(),
 509          'widget_categories'               => array(),
 510          'widget_text'                     => array(),
 511          'widget_rss'                      => array(),
 512          'uninstall_plugins'               => array(),
 513  
 514          // 2.8.0
 515          'timezone_string'                 => $timezone_string,
 516  
 517          // 3.0.0
 518          'page_for_posts'                  => 0,
 519          'page_on_front'                   => 0,
 520  
 521          // 3.1.0
 522          'default_post_format'             => 0,
 523  
 524          // 3.5.0
 525          'link_manager_enabled'            => 0,
 526  
 527          // 4.3.0
 528          'finished_splitting_shared_terms' => 1,
 529          'site_icon'                       => 0,
 530  
 531          // 4.4.0
 532          'medium_large_size_w'             => 768,
 533          'medium_large_size_h'             => 0,
 534  
 535          // 4.9.6
 536          'wp_page_for_privacy_policy'      => 0,
 537  
 538          // 4.9.8
 539          'show_comments_cookies_opt_in'    => 1,
 540  
 541          // 5.3.0
 542          'admin_email_lifespan'            => ( time() + 6 * MONTH_IN_SECONDS ),
 543  
 544          // 5.5.0
 545          'disallowed_keys'                 => '',
 546          'comment_previously_approved'     => 1,
 547          'auto_plugin_theme_update_emails' => array(),
 548  
 549          // 5.6.0
 550          'auto_update_core_dev'            => 'enabled',
 551          'auto_update_core_minor'          => 'enabled',
 552          /*
 553           * Default to enabled for new installs.
 554           * See https://core.trac.wordpress.org/ticket/51742.
 555           */
 556          'auto_update_core_major'          => 'enabled',
 557  
 558          // 5.8.0
 559          'wp_force_deactivated_plugins'    => array(),
 560  
 561          // 6.4.0
 562          'wp_attachment_pages_enabled'     => 0,
 563  
 564          // 6.9.0
 565          'wp_notes_notify'                 => 1,
 566  
 567          // 7.2.0
 568          'wp_random_base'                  => '',
 569      );
 570  
 571      // 3.3.0
 572      if ( ! is_multisite() ) {
 573          $defaults['initial_db_version'] = ! empty( $wp_current_db_version ) && $wp_current_db_version < $wp_db_version
 574              ? $wp_current_db_version : $wp_db_version;
 575      }
 576  
 577      // 3.0.0 multisite.
 578      if ( is_multisite() ) {
 579          $defaults['permalink_structure'] = '/%year%/%monthnum%/%day%/%postname%/';
 580      }
 581  
 582      $options = wp_parse_args( $options, $defaults );
 583  
 584      // Set autoload to no for these options.
 585      $fat_options = array(
 586          'moderation_keys',
 587          'recently_edited',
 588          'disallowed_keys',
 589          'uninstall_plugins',
 590          'auto_plugin_theme_update_emails',
 591      );
 592  
 593      $keys             = "'" . implode( "', '", array_keys( $options ) ) . "'";
 594      $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
 595  
 596      $insert = '';
 597  
 598      foreach ( $options as $option => $value ) {
 599          if ( in_array( $option, $existing_options, true ) ) {
 600              continue;
 601          }
 602  
 603          if ( in_array( $option, $fat_options, true ) ) {
 604              $autoload = 'off';
 605          } else {
 606              $autoload = 'on';
 607          }
 608  
 609          if ( ! empty( $insert ) ) {
 610              $insert .= ', ';
 611          }
 612  
 613          $value = maybe_serialize( sanitize_option( $option, $value ) );
 614  
 615          $insert .= $wpdb->prepare( '(%s, %s, %s)', $option, $value, $autoload );
 616      }
 617  
 618      if ( ! empty( $insert ) ) {
 619          $wpdb->query( "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
 620      }
 621  
 622      // In case it is set, but blank, update "home".
 623      if ( ! __get_option( 'home' ) ) {
 624          update_option( 'home', $guessurl );
 625      }
 626  
 627      // Delete unused options.
 628      $unusedoptions = array(
 629          'blodotgsping_url',
 630          'bodyterminator',
 631          'emailtestonly',
 632          'phoneemail_separator',
 633          'smilies_directory',
 634          'subjectprefix',
 635          'use_bbcode',
 636          'use_blodotgsping',
 637          'use_phoneemail',
 638          'use_quicktags',
 639          'use_weblogsping',
 640          'weblogs_cache_file',
 641          'use_preview',
 642          'use_htmltrans',
 643          'smilies_directory',
 644          'fileupload_allowedusers',
 645          'use_phoneemail',
 646          'default_post_status',
 647          'default_post_category',
 648          'archive_mode',
 649          'time_difference',
 650          'links_minadminlevel',
 651          'links_use_adminlevels',
 652          'links_rating_type',
 653          'links_rating_char',
 654          'links_rating_ignore_zero',
 655          'links_rating_single_image',
 656          'links_rating_image0',
 657          'links_rating_image1',
 658          'links_rating_image2',
 659          'links_rating_image3',
 660          'links_rating_image4',
 661          'links_rating_image5',
 662          'links_rating_image6',
 663          'links_rating_image7',
 664          'links_rating_image8',
 665          'links_rating_image9',
 666          'links_recently_updated_time',
 667          'links_recently_updated_prepend',
 668          'links_recently_updated_append',
 669          'weblogs_cacheminutes',
 670          'comment_allowed_tags',
 671          'search_engine_friendly_urls',
 672          'default_geourl_lat',
 673          'default_geourl_lon',
 674          'use_default_geourl',
 675          'weblogs_xml_url',
 676          'new_users_can_blog',
 677          '_wpnonce',
 678          '_wp_http_referer',
 679          'Update',
 680          'action',
 681          'rich_editing',
 682          'autosave_interval',
 683          'deactivated_plugins',
 684          'can_compress_scripts',
 685          'page_uris',
 686          'update_core',
 687          'update_plugins',
 688          'update_themes',
 689          'doing_cron',
 690          'random_seed',
 691          'rss_excerpt_length',
 692          'secret',
 693          'use_linksupdate',
 694          'default_comment_status_page',
 695          'wporg_popular_tags',
 696          'what_to_show',
 697          'rss_language',
 698          'language',
 699          'enable_xmlrpc',
 700          'enable_app',
 701          'embed_autourls',
 702          'default_post_edit_rows',
 703          'gzipcompression',
 704          'advanced_edit',
 705      );
 706      foreach ( $unusedoptions as $option ) {
 707          delete_option( $option );
 708      }
 709  
 710      // Delete obsolete magpie stuff.
 711      $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'" );
 712  
 713      // Clear expired transients.
 714      delete_expired_transients( true );
 715  }
 716  
 717  /**
 718   * Execute WordPress role creation for the various WordPress versions.
 719   *
 720   * @since 2.0.0
 721   */
 722  function populate_roles() {
 723      $wp_roles = wp_roles();
 724  
 725      // Disable role updates to the database while populating roles.
 726      $original_use_db  = $wp_roles->use_db;
 727      $wp_roles->use_db = false;
 728  
 729      // Populate roles
 730      populate_roles_160();
 731      populate_roles_210();
 732      populate_roles_230();
 733      populate_roles_250();
 734      populate_roles_260();
 735      populate_roles_270();
 736      populate_roles_280();
 737      populate_roles_300();
 738      populate_roles_720();
 739  
 740      // Save the updated roles to the database.
 741      if ( $original_use_db ) {
 742          update_option( $wp_roles->role_key, $wp_roles->roles, true );
 743      }
 744  
 745      // Restore original value for writing to database.
 746      $wp_roles->use_db = $original_use_db;
 747  }
 748  
 749  /**
 750   * Create the roles for WordPress 2.0
 751   *
 752   * @since 2.0.0
 753   */
 754  function populate_roles_160() {
 755      // Add roles.
 756      add_role( 'administrator', 'Administrator' );
 757      add_role( 'editor', 'Editor' );
 758      add_role( 'author', 'Author' );
 759      add_role( 'contributor', 'Contributor' );
 760      add_role( 'subscriber', 'Subscriber' );
 761  
 762      // Add caps for Administrator role.
 763      $role = get_role( 'administrator' );
 764      $role->add_cap( 'switch_themes' );
 765      $role->add_cap( 'edit_themes' );
 766      $role->add_cap( 'activate_plugins' );
 767      $role->add_cap( 'edit_plugins' );
 768      $role->add_cap( 'edit_users' );
 769      $role->add_cap( 'edit_files' );
 770      $role->add_cap( 'manage_options' );
 771      $role->add_cap( 'moderate_comments' );
 772      $role->add_cap( 'manage_categories' );
 773      $role->add_cap( 'manage_links' );
 774      $role->add_cap( 'upload_files' );
 775      $role->add_cap( 'import' );
 776      $role->add_cap( 'unfiltered_html' );
 777      $role->add_cap( 'edit_posts' );
 778      $role->add_cap( 'edit_others_posts' );
 779      $role->add_cap( 'edit_published_posts' );
 780      $role->add_cap( 'publish_posts' );
 781      $role->add_cap( 'edit_pages' );
 782      $role->add_cap( 'read' );
 783      $role->add_cap( 'level_10' );
 784      $role->add_cap( 'level_9' );
 785      $role->add_cap( 'level_8' );
 786      $role->add_cap( 'level_7' );
 787      $role->add_cap( 'level_6' );
 788      $role->add_cap( 'level_5' );
 789      $role->add_cap( 'level_4' );
 790      $role->add_cap( 'level_3' );
 791      $role->add_cap( 'level_2' );
 792      $role->add_cap( 'level_1' );
 793      $role->add_cap( 'level_0' );
 794  
 795      // Add caps for Editor role.
 796      $role = get_role( 'editor' );
 797      $role->add_cap( 'moderate_comments' );
 798      $role->add_cap( 'manage_categories' );
 799      $role->add_cap( 'manage_links' );
 800      $role->add_cap( 'upload_files' );
 801      $role->add_cap( 'unfiltered_html' );
 802      $role->add_cap( 'edit_posts' );
 803      $role->add_cap( 'edit_others_posts' );
 804      $role->add_cap( 'edit_published_posts' );
 805      $role->add_cap( 'publish_posts' );
 806      $role->add_cap( 'edit_pages' );
 807      $role->add_cap( 'read' );
 808      $role->add_cap( 'level_7' );
 809      $role->add_cap( 'level_6' );
 810      $role->add_cap( 'level_5' );
 811      $role->add_cap( 'level_4' );
 812      $role->add_cap( 'level_3' );
 813      $role->add_cap( 'level_2' );
 814      $role->add_cap( 'level_1' );
 815      $role->add_cap( 'level_0' );
 816  
 817      // Add caps for Author role.
 818      $role = get_role( 'author' );
 819      $role->add_cap( 'upload_files' );
 820      $role->add_cap( 'edit_posts' );
 821      $role->add_cap( 'edit_published_posts' );
 822      $role->add_cap( 'publish_posts' );
 823      $role->add_cap( 'read' );
 824      $role->add_cap( 'level_2' );
 825      $role->add_cap( 'level_1' );
 826      $role->add_cap( 'level_0' );
 827  
 828      // Add caps for Contributor role.
 829      $role = get_role( 'contributor' );
 830      $role->add_cap( 'edit_posts' );
 831      $role->add_cap( 'read' );
 832      $role->add_cap( 'level_1' );
 833      $role->add_cap( 'level_0' );
 834  
 835      // Add caps for Subscriber role.
 836      $role = get_role( 'subscriber' );
 837      $role->add_cap( 'read' );
 838      $role->add_cap( 'level_0' );
 839  }
 840  
 841  /**
 842   * Create and modify WordPress roles for WordPress 2.1.
 843   *
 844   * @since 2.1.0
 845   */
 846  function populate_roles_210() {
 847      $roles = array( 'administrator', 'editor' );
 848      foreach ( $roles as $role ) {
 849          $role = get_role( $role );
 850          if ( empty( $role ) ) {
 851              continue;
 852          }
 853  
 854          $role->add_cap( 'edit_others_pages' );
 855          $role->add_cap( 'edit_published_pages' );
 856          $role->add_cap( 'publish_pages' );
 857          $role->add_cap( 'delete_pages' );
 858          $role->add_cap( 'delete_others_pages' );
 859          $role->add_cap( 'delete_published_pages' );
 860          $role->add_cap( 'delete_posts' );
 861          $role->add_cap( 'delete_others_posts' );
 862          $role->add_cap( 'delete_published_posts' );
 863          $role->add_cap( 'delete_private_posts' );
 864          $role->add_cap( 'edit_private_posts' );
 865          $role->add_cap( 'read_private_posts' );
 866          $role->add_cap( 'delete_private_pages' );
 867          $role->add_cap( 'edit_private_pages' );
 868          $role->add_cap( 'read_private_pages' );
 869      }
 870  
 871      $role = get_role( 'administrator' );
 872      if ( ! empty( $role ) ) {
 873          $role->add_cap( 'delete_users' );
 874          $role->add_cap( 'create_users' );
 875      }
 876  
 877      $role = get_role( 'author' );
 878      if ( ! empty( $role ) ) {
 879          $role->add_cap( 'delete_posts' );
 880          $role->add_cap( 'delete_published_posts' );
 881      }
 882  
 883      $role = get_role( 'contributor' );
 884      if ( ! empty( $role ) ) {
 885          $role->add_cap( 'delete_posts' );
 886      }
 887  }
 888  
 889  /**
 890   * Create and modify WordPress roles for WordPress 2.3.
 891   *
 892   * @since 2.3.0
 893   */
 894  function populate_roles_230() {
 895      $role = get_role( 'administrator' );
 896  
 897      if ( ! empty( $role ) ) {
 898          $role->add_cap( 'unfiltered_upload' );
 899      }
 900  }
 901  
 902  /**
 903   * Create and modify WordPress roles for WordPress 2.5.
 904   *
 905   * @since 2.5.0
 906   */
 907  function populate_roles_250() {
 908      $role = get_role( 'administrator' );
 909  
 910      if ( ! empty( $role ) ) {
 911          $role->add_cap( 'edit_dashboard' );
 912      }
 913  }
 914  
 915  /**
 916   * Create and modify WordPress roles for WordPress 2.6.
 917   *
 918   * @since 2.6.0
 919   */
 920  function populate_roles_260() {
 921      $role = get_role( 'administrator' );
 922  
 923      if ( ! empty( $role ) ) {
 924          $role->add_cap( 'update_plugins' );
 925          $role->add_cap( 'delete_plugins' );
 926      }
 927  }
 928  
 929  /**
 930   * Create and modify WordPress roles for WordPress 2.7.
 931   *
 932   * @since 2.7.0
 933   */
 934  function populate_roles_270() {
 935      $role = get_role( 'administrator' );
 936  
 937      if ( ! empty( $role ) ) {
 938          $role->add_cap( 'install_plugins' );
 939          $role->add_cap( 'update_themes' );
 940      }
 941  }
 942  
 943  /**
 944   * Create and modify WordPress roles for WordPress 2.8.
 945   *
 946   * @since 2.8.0
 947   */
 948  function populate_roles_280() {
 949      $role = get_role( 'administrator' );
 950  
 951      if ( ! empty( $role ) ) {
 952          $role->add_cap( 'install_themes' );
 953      }
 954  }
 955  
 956  /**
 957   * Create and modify WordPress roles for WordPress 3.0.
 958   *
 959   * @since 3.0.0
 960   */
 961  function populate_roles_300() {
 962      $role = get_role( 'administrator' );
 963  
 964      if ( ! empty( $role ) ) {
 965          $role->add_cap( 'update_core' );
 966          $role->add_cap( 'list_users' );
 967          $role->add_cap( 'remove_users' );
 968          $role->add_cap( 'promote_users' );
 969          $role->add_cap( 'edit_theme_options' );
 970          $role->add_cap( 'delete_themes' );
 971          $role->add_cap( 'export' );
 972      }
 973  }
 974  
 975  /**
 976   * Create and modify WordPress roles for WordPress 7.2.
 977   *
 978   * @since 7.2.0
 979   */
 980  function populate_roles_720(): void {
 981      $role = get_role( 'administrator' );
 982  
 983      if ( ! empty( $role ) ) {
 984          $role->add_cap( 'manage_secrets' );
 985      }
 986  }
 987  
 988  if ( ! function_exists( 'install_network' ) ) :
 989      /**
 990       * Install Network.
 991       *
 992       * @since 3.0.0
 993       */
 994  	function install_network() {
 995          if ( ! defined( 'WP_INSTALLING_NETWORK' ) ) {
 996              define( 'WP_INSTALLING_NETWORK', true );
 997          }
 998  
 999          dbDelta( wp_get_db_schema( 'global' ) );
1000      }
1001  endif;
1002  
1003  /**
1004   * Populate network settings.
1005   *
1006   * @since 3.0.0
1007   *
1008   * @global wpdb       $wpdb         WordPress database abstraction object.
1009   * @global object     $current_site
1010   * @global WP_Rewrite $wp_rewrite   WordPress rewrite component.
1011   *
1012   * @param int    $network_id        ID of network to populate.
1013   * @param string $domain            The domain name for the network. Example: "example.com".
1014   * @param string $email             Email address for the network administrator.
1015   * @param string $site_name         The name of the network.
1016   * @param string $path              Optional. The path to append to the network's domain name. Default '/'.
1017   * @param bool   $subdomain_install Optional. Whether the network is a subdomain installation or a subdirectory installation.
1018   *                                  Default false, meaning the network is a subdirectory installation.
1019   * @return true|WP_Error True on success, or WP_Error on warning (with the installation otherwise successful,
1020   *                       so the error code must be checked) or failure.
1021   */
1022  function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
1023      global $wpdb, $current_site, $wp_rewrite;
1024  
1025      $network_id = (int) $network_id;
1026  
1027      /**
1028       * Fires before a network is populated.
1029       *
1030       * @since 6.9.0
1031       *
1032       * @param int    $network_id        ID of network to populate.
1033       * @param string $domain            The domain name for the network.
1034       * @param string $email             Email address for the network administrator.
1035       * @param string $site_name         The name of the network.
1036       * @param string $path              The path to append to the network's domain name.
1037       * @param bool   $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1038       */
1039      do_action( 'before_populate_network', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1040  
1041      $errors = new WP_Error();
1042      if ( '' === $domain ) {
1043          $errors->add( 'empty_domain', __( 'You must provide a domain name.' ) );
1044      }
1045      if ( '' === $site_name ) {
1046          $errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) );
1047      }
1048  
1049      // Check for network collision.
1050      if ( is_multisite() ) {
1051          if ( get_network( $network_id ) ) {
1052              $errors->add( 'siteid_exists', __( 'The network already exists.' ) );
1053          }
1054      } else {
1055          if ( $network_id === (int) $wpdb->get_var(
1056              $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id )
1057          ) ) {
1058              $errors->add( 'siteid_exists', __( 'The network already exists.' ) );
1059          }
1060      }
1061  
1062      if ( ! is_email( $email ) ) {
1063          $errors->add( 'invalid_email', __( 'You must provide a valid email address.' ) );
1064      }
1065  
1066      if ( $errors->has_errors() ) {
1067          return $errors;
1068      }
1069  
1070      if ( 1 === $network_id ) {
1071          $wpdb->insert(
1072              $wpdb->site,
1073              array(
1074                  'domain' => $domain,
1075                  'path'   => $path,
1076              )
1077          );
1078          $network_id = $wpdb->insert_id;
1079      } else {
1080          $wpdb->insert(
1081              $wpdb->site,
1082              array(
1083                  'domain' => $domain,
1084                  'path'   => $path,
1085                  'id'     => $network_id,
1086              )
1087          );
1088      }
1089  
1090      populate_network_meta(
1091          $network_id,
1092          array(
1093              'admin_email'       => $email,
1094              'site_name'         => $site_name,
1095              'subdomain_install' => $subdomain_install,
1096          )
1097      );
1098  
1099      // Remove the cron event since Recovery Mode is not used in Multisite.
1100      if ( wp_next_scheduled( 'recovery_mode_clean_expired_keys' ) ) {
1101          wp_clear_scheduled_hook( 'recovery_mode_clean_expired_keys' );
1102      }
1103  
1104      /*
1105       * When upgrading from single to multisite, assume the current site will
1106       * become the main site of the network. When using populate_network()
1107       * to create another network in an existing multisite environment, skip
1108       * these steps since the main site of the new network has not yet been
1109       * created.
1110       */
1111      if ( ! is_multisite() ) {
1112          $current_site            = new stdClass();
1113          $current_site->domain    = $domain;
1114          $current_site->path      = $path;
1115          $current_site->site_name = ucfirst( $domain );
1116          $wpdb->insert(
1117              $wpdb->blogs,
1118              array(
1119                  'site_id'    => $network_id,
1120                  'blog_id'    => 1,
1121                  'domain'     => $domain,
1122                  'path'       => $path,
1123                  'registered' => current_time( 'mysql' ),
1124              )
1125          );
1126          $current_site->blog_id = $wpdb->insert_id;
1127  
1128          $site_user_id = (int) $wpdb->get_var(
1129              $wpdb->prepare(
1130                  "SELECT meta_value
1131                  FROM $wpdb->sitemeta
1132                  WHERE meta_key = %s AND site_id = %d",
1133                  'admin_user_id',
1134                  $network_id
1135              )
1136          );
1137  
1138          update_user_meta( $site_user_id, 'source_domain', $domain );
1139          update_user_meta( $site_user_id, 'primary_blog', $current_site->blog_id );
1140  
1141          // Unable to use update_network_option() while populating the network.
1142          $wpdb->insert(
1143              $wpdb->sitemeta,
1144              array(
1145                  'site_id'    => $network_id,
1146                  'meta_key'   => 'main_site',
1147                  'meta_value' => $current_site->blog_id,
1148              )
1149          );
1150  
1151          if ( $subdomain_install ) {
1152              $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
1153          } else {
1154              $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' );
1155          }
1156  
1157          flush_rewrite_rules();
1158  
1159          /**
1160           * Fires after a network is created when converting a single site to multisite.
1161           *
1162           * @since 6.9.0
1163           *
1164           * @param int    $network_id        ID of network created.
1165           * @param string $domain            The domain name for the network.
1166           * @param string $email             Email address for the network administrator.
1167           * @param string $site_name         The name of the network.
1168           * @param string $path              The path to append to the network's domain name.
1169           * @param bool   $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1170           */
1171          do_action( 'after_upgrade_to_multisite', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1172  
1173          if ( ! $subdomain_install ) {
1174              return true;
1175          }
1176  
1177          $vhost_ok = false;
1178          $errstr   = '';
1179          $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
1180          $page     = wp_remote_get(
1181              'http://' . $hostname,
1182              array(
1183                  'timeout'     => 5,
1184                  'httpversion' => '1.1',
1185              )
1186          );
1187          if ( is_wp_error( $page ) ) {
1188              $errstr = $page->get_error_message();
1189          } elseif ( 200 === wp_remote_retrieve_response_code( $page ) ) {
1190                  $vhost_ok = true;
1191          }
1192  
1193          if ( ! $vhost_ok ) {
1194              $msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
1195  
1196              $msg .= '<p>' . sprintf(
1197                  /* translators: %s: Host name. */
1198                  __( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
1199                  '<code>' . $hostname . '</code>'
1200              );
1201              if ( ! empty( $errstr ) ) {
1202                  /* translators: %s: Error message. */
1203                  $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
1204              }
1205              $msg .= '</p>';
1206  
1207              $msg .= '<p>' . sprintf(
1208                  /* translators: %s: Asterisk symbol (*). */
1209                  __( 'To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a %s hostname record pointing at your web server in your DNS configuration tool.' ),
1210                  '<code>*</code>'
1211              ) . '</p>';
1212  
1213              $msg .= '<p>' . __( 'You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.' ) . '</p>';
1214  
1215              return new WP_Error( 'no_wildcard_dns', $msg );
1216          }
1217      }
1218  
1219      /**
1220       * Fires after a network is fully populated.
1221       *
1222       * @since 6.9.0
1223       *
1224       * @param int    $network_id        ID of network created.
1225       * @param string $domain            The domain name for the network.
1226       * @param string $email             Email address for the network administrator.
1227       * @param string $site_name         The name of the network.
1228       * @param string $path              The path to append to the network's domain name.
1229       * @param bool   $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1230       */
1231      do_action( 'after_populate_network', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1232  
1233      return true;
1234  }
1235  
1236  /**
1237   * Creates WordPress network meta and sets the default values.
1238   *
1239   * @since 5.1.0
1240   *
1241   * @global wpdb $wpdb          WordPress database abstraction object.
1242   * @global int  $wp_db_version WordPress database version.
1243   *
1244   * @param int   $network_id Network ID to populate meta for.
1245   * @param array $meta       Optional. Custom meta $key => $value pairs to use. Default empty array.
1246   */
1247  function populate_network_meta( $network_id, array $meta = array() ) {
1248      global $wpdb, $wp_db_version;
1249  
1250      $network_id = (int) $network_id;
1251  
1252      $email             = ! empty( $meta['admin_email'] ) ? $meta['admin_email'] : '';
1253      $subdomain_install = isset( $meta['subdomain_install'] ) ? (int) $meta['subdomain_install'] : 0;
1254  
1255      // If a user with the provided email does not exist, default to the current user as the new network admin.
1256      $site_user = ! empty( $email ) ? get_user_by( 'email', $email ) : false;
1257      if ( false === $site_user ) {
1258          $site_user = wp_get_current_user();
1259      }
1260  
1261      if ( empty( $email ) ) {
1262          $email = $site_user->user_email;
1263      }
1264  
1265      $template       = get_option( 'template' );
1266      $stylesheet     = get_option( 'stylesheet' );
1267      $allowed_themes = array( $stylesheet => true );
1268  
1269      if ( $template !== $stylesheet ) {
1270          $allowed_themes[ $template ] = true;
1271      }
1272  
1273      if ( WP_DEFAULT_THEME !== $stylesheet && WP_DEFAULT_THEME !== $template ) {
1274          $allowed_themes[ WP_DEFAULT_THEME ] = true;
1275      }
1276  
1277      // If WP_DEFAULT_THEME doesn't exist, also include the latest core default theme.
1278      if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
1279          $core_default = WP_Theme::get_core_default_theme();
1280          if ( $core_default ) {
1281              $allowed_themes[ $core_default->get_stylesheet() ] = true;
1282          }
1283      }
1284  
1285      if ( function_exists( 'clean_network_cache' ) ) {
1286          clean_network_cache( $network_id );
1287      } else {
1288          wp_cache_delete( $network_id, 'networks' );
1289      }
1290  
1291      if ( ! is_multisite() ) {
1292          $site_admins = array( $site_user->user_login );
1293          $users       = get_users(
1294              array(
1295                  'fields' => array( 'user_login' ),
1296                  'role'   => 'administrator',
1297              )
1298          );
1299          if ( $users ) {
1300              foreach ( $users as $user ) {
1301                  $site_admins[] = $user->user_login;
1302              }
1303  
1304              $site_admins = array_unique( $site_admins );
1305          }
1306      } else {
1307          $site_admins = get_site_option( 'site_admins' );
1308      }
1309  
1310      /* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
1311      $welcome_email = __(
1312          'Howdy USERNAME,
1313  
1314  Your new SITE_NAME site has been successfully set up at:
1315  BLOG_URL
1316  
1317  You can log in to the administrator account with the following information:
1318  
1319  Username: USERNAME
1320  Password: PASSWORD
1321  Log in here: BLOG_URLwp-login.php
1322  
1323  We hope you enjoy your new site. Thanks!
1324  
1325  --The Team @ SITE_NAME'
1326      );
1327  
1328      $allowed_file_types = array();
1329      $all_mime_types     = get_allowed_mime_types();
1330  
1331      foreach ( $all_mime_types as $ext => $mime ) {
1332          array_push( $allowed_file_types, ...explode( '|', $ext ) );
1333      }
1334      $upload_filetypes = array_unique( $allowed_file_types );
1335  
1336      $sitemeta = array(
1337          'site_name'                   => __( 'My Network' ),
1338          'admin_email'                 => $email,
1339          'admin_user_id'               => $site_user->ID,
1340          'registration'                => 'none',
1341          'upload_filetypes'            => implode( ' ', $upload_filetypes ),
1342          'blog_upload_space'           => 100,
1343          'fileupload_maxk'             => 1500,
1344          'site_admins'                 => $site_admins,
1345          'allowedthemes'               => $allowed_themes,
1346          'illegal_names'               => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ),
1347          'wpmu_upgrade_site'           => $wp_db_version,
1348          'welcome_email'               => $welcome_email,
1349          /* translators: %s: Site link. */
1350          'first_post'                  => __( 'Welcome to %s. This is your first post. Edit or delete it, then start writing!' ),
1351          // @todo - Network admins should have a method of editing the network siteurl (used for cookie hash).
1352          'siteurl'                     => get_option( 'siteurl' ) . '/',
1353          'add_new_users'               => '0',
1354          'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
1355          'subdomain_install'           => $subdomain_install,
1356          'ms_files_rewriting'          => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
1357          'user_count'                  => get_site_option( 'user_count' ),
1358          'initial_db_version'          => get_option( 'initial_db_version' ),
1359          'active_sitewide_plugins'     => array(),
1360          'WPLANG'                      => get_locale(),
1361      );
1362      if ( ! $subdomain_install ) {
1363          $sitemeta['illegal_names'][] = 'blog';
1364      }
1365  
1366      $sitemeta = wp_parse_args( $meta, $sitemeta );
1367  
1368      /**
1369       * Filters meta for a network on creation.
1370       *
1371       * @since 3.7.0
1372       *
1373       * @param array $sitemeta   Associative array of network meta keys and values to be inserted.
1374       * @param int   $network_id ID of network to populate.
1375       */
1376      $sitemeta = apply_filters( 'populate_network_meta', $sitemeta, $network_id );
1377  
1378      $insert = '';
1379      foreach ( $sitemeta as $meta_key => $meta_value ) {
1380          if ( is_array( $meta_value ) ) {
1381              $meta_value = serialize( $meta_value );
1382          }
1383          if ( ! empty( $insert ) ) {
1384              $insert .= ', ';
1385          }
1386          $insert .= $wpdb->prepare( '( %d, %s, %s)', $network_id, $meta_key, $meta_value );
1387      }
1388      $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1389  }
1390  
1391  /**
1392   * Creates WordPress site meta and sets the default values.
1393   *
1394   * @since 5.1.0
1395   *
1396   * @global wpdb $wpdb WordPress database abstraction object.
1397   *
1398   * @param int   $site_id Site ID to populate meta for.
1399   * @param array $meta    Optional. Custom meta $key => $value pairs to use. Default empty array.
1400   */
1401  function populate_site_meta( $site_id, array $meta = array() ) {
1402      global $wpdb;
1403  
1404      $site_id = (int) $site_id;
1405  
1406      if ( ! is_site_meta_supported() ) {
1407          return;
1408      }
1409  
1410      if ( empty( $meta ) ) {
1411          return;
1412      }
1413  
1414      /**
1415       * Filters meta for a site on creation.
1416       *
1417       * @since 5.2.0
1418       *
1419       * @param array $meta    Associative array of site meta keys and values to be inserted.
1420       * @param int   $site_id ID of site to populate.
1421       */
1422      $site_meta = apply_filters( 'populate_site_meta', $meta, $site_id );
1423  
1424      $insert = '';
1425      foreach ( $site_meta as $meta_key => $meta_value ) {
1426          if ( is_array( $meta_value ) ) {
1427              $meta_value = serialize( $meta_value );
1428          }
1429          if ( ! empty( $insert ) ) {
1430              $insert .= ', ';
1431          }
1432          $insert .= $wpdb->prepare( '( %d, %s, %s)', $site_id, $meta_key, $meta_value );
1433      }
1434  
1435      $wpdb->query( "INSERT INTO $wpdb->blogmeta ( blog_id, meta_key, meta_value ) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1436  
1437      wp_cache_delete( $site_id, 'blog_meta' );
1438      wp_cache_set_sites_last_changed();
1439  }


Generated : Thu Oct 22 08:20:34 2026 Cross-referenced by PHPXref