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


Generated : Tue Aug 12 08:20:01 2025 Cross-referenced by PHPXref