wp/wp-admin/includes/schema.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     6  *
     6  *
     7  * @package WordPress
     7  * @package WordPress
     8  * @subpackage Administration
     8  * @subpackage Administration
     9  */
     9  */
    10 
    10 
    11 // Declare these as global in case schema.php is included from a function.
    11 /**
       
    12  * Declare these as global in case schema.php is included from a function.
       
    13  *
       
    14  * @global wpdb   $wpdb
       
    15  * @global array  $wp_queries
       
    16  * @global string $charset_collate
       
    17  */
    12 global $wpdb, $wp_queries, $charset_collate;
    18 global $wpdb, $wp_queries, $charset_collate;
    13 
    19 
    14 /**
    20 /**
    15  * The database character collate.
    21  * The database character collate.
    16  * @var string
       
    17  * @global string
       
    18  * @name $charset_collate
       
    19  */
    22  */
    20 $charset_collate = $wpdb->get_charset_collate();
    23 $charset_collate = $wpdb->get_charset_collate();
    21 
    24 
    22 /**
    25 /**
    23  * Retrieve the SQL for creating database tables.
    26  * Retrieve the SQL for creating database tables.
    24  *
    27  *
    25  * @since 3.3.0
    28  * @since 3.3.0
    26  *
    29  *
       
    30  * @global wpdb $wpdb WordPress database abstraction object.
       
    31  *
    27  * @param string $scope Optional. The tables for which to retrieve SQL. Can be all, global, ms_global, or blog tables. Defaults to all.
    32  * @param string $scope Optional. The tables for which to retrieve SQL. Can be all, global, ms_global, or blog tables. Defaults to all.
    28  * @param int $blog_id Optional. The blog ID for which to retrieve SQL. Default is the current blog ID.
    33  * @param int $blog_id Optional. The site ID for which to retrieve SQL. Default is the current site ID.
    29  * @return string The SQL needed to create the requested tables.
    34  * @return string The SQL needed to create the requested tables.
    30  */
    35  */
    31 function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
    36 function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
    32 	global $wpdb;
    37 	global $wpdb;
    33 
    38 
    34 	$charset_collate = '';
    39 	$charset_collate = $wpdb->get_charset_collate();
    35 
       
    36 	if ( ! empty($wpdb->charset) )
       
    37 		$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
       
    38 	if ( ! empty($wpdb->collate) )
       
    39 		$charset_collate .= " COLLATE $wpdb->collate";
       
    40 
    40 
    41 	if ( $blog_id && $blog_id != $wpdb->blogid )
    41 	if ( $blog_id && $blog_id != $wpdb->blogid )
    42 		$old_blog_id = $wpdb->set_blog_id( $blog_id );
    42 		$old_blog_id = $wpdb->set_blog_id( $blog_id );
    43 
    43 
    44 	// Engage multisite if in the middle of turning it on from network.php.
    44 	// Engage multisite if in the middle of turning it on from network.php.
    50 	 * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
    50 	 * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
    51 	 */
    51 	 */
    52 	$max_index_length = 191;
    52 	$max_index_length = 191;
    53 
    53 
    54 	// Blog specific tables.
    54 	// Blog specific tables.
    55 	$blog_tables = "CREATE TABLE $wpdb->terms (
    55 	$blog_tables = "CREATE TABLE $wpdb->termmeta (
       
    56   meta_id bigint(20) unsigned NOT NULL auto_increment,
       
    57   term_id bigint(20) unsigned NOT NULL default '0',
       
    58   meta_key varchar(255) default NULL,
       
    59   meta_value longtext,
       
    60   PRIMARY KEY  (meta_id),
       
    61   KEY term_id (term_id),
       
    62   KEY meta_key (meta_key($max_index_length))
       
    63 ) $charset_collate;
       
    64 CREATE TABLE $wpdb->terms (
    56  term_id bigint(20) unsigned NOT NULL auto_increment,
    65  term_id bigint(20) unsigned NOT NULL auto_increment,
    57  name varchar(200) NOT NULL default '',
    66  name varchar(200) NOT NULL default '',
    58  slug varchar(200) NOT NULL default '',
    67  slug varchar(200) NOT NULL default '',
    59  term_group bigint(10) NOT NULL default 0,
    68  term_group bigint(10) NOT NULL default 0,
    60  PRIMARY KEY  (term_id),
    69  PRIMARY KEY  (term_id),
   128   PRIMARY KEY  (link_id),
   137   PRIMARY KEY  (link_id),
   129   KEY link_visible (link_visible)
   138   KEY link_visible (link_visible)
   130 ) $charset_collate;
   139 ) $charset_collate;
   131 CREATE TABLE $wpdb->options (
   140 CREATE TABLE $wpdb->options (
   132   option_id bigint(20) unsigned NOT NULL auto_increment,
   141   option_id bigint(20) unsigned NOT NULL auto_increment,
   133   option_name varchar(64) NOT NULL default '',
   142   option_name varchar(191) NOT NULL default '',
   134   option_value longtext NOT NULL,
   143   option_value longtext NOT NULL,
   135   autoload varchar(20) NOT NULL default 'yes',
   144   autoload varchar(20) NOT NULL default 'yes',
   136   PRIMARY KEY  (option_id),
   145   PRIMARY KEY  (option_id),
   137   UNIQUE KEY option_name (option_name)
   146   UNIQUE KEY option_name (option_name)
   138 ) $charset_collate;
   147 ) $charset_collate;
   154   post_title text NOT NULL,
   163   post_title text NOT NULL,
   155   post_excerpt text NOT NULL,
   164   post_excerpt text NOT NULL,
   156   post_status varchar(20) NOT NULL default 'publish',
   165   post_status varchar(20) NOT NULL default 'publish',
   157   comment_status varchar(20) NOT NULL default 'open',
   166   comment_status varchar(20) NOT NULL default 'open',
   158   ping_status varchar(20) NOT NULL default 'open',
   167   ping_status varchar(20) NOT NULL default 'open',
   159   post_password varchar(20) NOT NULL default '',
   168   post_password varchar(255) NOT NULL default '',
   160   post_name varchar(200) NOT NULL default '',
   169   post_name varchar(200) NOT NULL default '',
   161   to_ping text NOT NULL,
   170   to_ping text NOT NULL,
   162   pinged text NOT NULL,
   171   pinged text NOT NULL,
   163   post_modified datetime NOT NULL default '0000-00-00 00:00:00',
   172   post_modified datetime NOT NULL default '0000-00-00 00:00:00',
   164   post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
   173   post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
   178 
   187 
   179 	// Single site users table. The multisite flavor of the users table is handled below.
   188 	// Single site users table. The multisite flavor of the users table is handled below.
   180 	$users_single_table = "CREATE TABLE $wpdb->users (
   189 	$users_single_table = "CREATE TABLE $wpdb->users (
   181   ID bigint(20) unsigned NOT NULL auto_increment,
   190   ID bigint(20) unsigned NOT NULL auto_increment,
   182   user_login varchar(60) NOT NULL default '',
   191   user_login varchar(60) NOT NULL default '',
   183   user_pass varchar(64) NOT NULL default '',
   192   user_pass varchar(255) NOT NULL default '',
   184   user_nicename varchar(50) NOT NULL default '',
   193   user_nicename varchar(50) NOT NULL default '',
   185   user_email varchar(100) NOT NULL default '',
   194   user_email varchar(100) NOT NULL default '',
   186   user_url varchar(100) NOT NULL default '',
   195   user_url varchar(100) NOT NULL default '',
   187   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
   196   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
   188   user_activation_key varchar(60) NOT NULL default '',
   197   user_activation_key varchar(255) NOT NULL default '',
   189   user_status int(11) NOT NULL default '0',
   198   user_status int(11) NOT NULL default '0',
   190   display_name varchar(250) NOT NULL default '',
   199   display_name varchar(250) NOT NULL default '',
   191   PRIMARY KEY  (ID),
   200   PRIMARY KEY  (ID),
   192   KEY user_login_key (user_login),
   201   KEY user_login_key (user_login),
   193   KEY user_nicename (user_nicename)
   202   KEY user_nicename (user_nicename),
       
   203   KEY user_email (user_email)
   194 ) $charset_collate;\n";
   204 ) $charset_collate;\n";
   195 
   205 
   196 	// Multisite users table
   206 	// Multisite users table
   197 	$users_multi_table = "CREATE TABLE $wpdb->users (
   207 	$users_multi_table = "CREATE TABLE $wpdb->users (
   198   ID bigint(20) unsigned NOT NULL auto_increment,
   208   ID bigint(20) unsigned NOT NULL auto_increment,
   199   user_login varchar(60) NOT NULL default '',
   209   user_login varchar(60) NOT NULL default '',
   200   user_pass varchar(64) NOT NULL default '',
   210   user_pass varchar(255) NOT NULL default '',
   201   user_nicename varchar(50) NOT NULL default '',
   211   user_nicename varchar(50) NOT NULL default '',
   202   user_email varchar(100) NOT NULL default '',
   212   user_email varchar(100) NOT NULL default '',
   203   user_url varchar(100) NOT NULL default '',
   213   user_url varchar(100) NOT NULL default '',
   204   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
   214   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
   205   user_activation_key varchar(60) NOT NULL default '',
   215   user_activation_key varchar(255) NOT NULL default '',
   206   user_status int(11) NOT NULL default '0',
   216   user_status int(11) NOT NULL default '0',
   207   display_name varchar(250) NOT NULL default '',
   217   display_name varchar(250) NOT NULL default '',
   208   spam tinyint(2) NOT NULL default '0',
   218   spam tinyint(2) NOT NULL default '0',
   209   deleted tinyint(2) NOT NULL default '0',
   219   deleted tinyint(2) NOT NULL default '0',
   210   PRIMARY KEY  (ID),
   220   PRIMARY KEY  (ID),
   211   KEY user_login_key (user_login),
   221   KEY user_login_key (user_login),
   212   KEY user_nicename (user_nicename)
   222   KEY user_nicename (user_nicename),
       
   223   KEY user_email (user_email)
   213 ) $charset_collate;\n";
   224 ) $charset_collate;\n";
   214 
   225 
   215 	// Usermeta.
   226 	// Usermeta.
   216 	$usermeta_table = "CREATE TABLE $wpdb->usermeta (
   227 	$usermeta_table = "CREATE TABLE $wpdb->usermeta (
   217   umeta_id bigint(20) unsigned NOT NULL auto_increment,
   228   umeta_id bigint(20) unsigned NOT NULL auto_increment,
   331  * Create WordPress options and set the default values.
   342  * Create WordPress options and set the default values.
   332  *
   343  *
   333  * @since 1.5.0
   344  * @since 1.5.0
   334  *
   345  *
   335  * @global wpdb $wpdb WordPress database abstraction object.
   346  * @global wpdb $wpdb WordPress database abstraction object.
   336  * @uses $wp_db_version
   347  * @global int  $wp_db_version
       
   348  * @global int  $wp_current_db_version
   337  */
   349  */
   338 function populate_options() {
   350 function populate_options() {
   339 	global $wpdb, $wp_db_version, $wp_current_db_version;
   351 	global $wpdb, $wp_db_version, $wp_current_db_version;
   340 
   352 
   341 	$guessurl = wp_guess_url();
   353 	$guessurl = wp_guess_url();
   351 		$uploads_use_yearmonth_folders = 0;
   363 		$uploads_use_yearmonth_folders = 0;
   352 	} else {
   364 	} else {
   353 		$uploads_use_yearmonth_folders = 1;
   365 		$uploads_use_yearmonth_folders = 1;
   354 	}
   366 	}
   355 
   367 
   356 	$template = WP_DEFAULT_THEME;
   368 	// If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
   357 	// If default theme is a child theme, we need to get its template
   369 	$stylesheet = $template = WP_DEFAULT_THEME;
   358 	$theme = wp_get_theme( $template );
   370 	$theme = wp_get_theme( WP_DEFAULT_THEME );
   359 	if ( ! $theme->errors() )
   371 	if ( ! $theme->exists() ) {
   360 		$template = $theme->get_template();
   372 		$theme = WP_Theme::get_core_default_theme();
       
   373 	}
       
   374 
       
   375 	// If we can't find a core default theme, WP_DEFAULT_THEME is the best we can do.
       
   376 	if ( $theme ) {
       
   377 		$stylesheet = $theme->get_stylesheet();
       
   378 		$template   = $theme->get_template();
       
   379 	}
   361 
   380 
   362 	$timezone_string = '';
   381 	$timezone_string = '';
   363 	$gmt_offset = 0;
   382 	$gmt_offset = 0;
   364 	/* translators: default GMT offset or timezone string. Must be either a valid offset (-12 to 14)
   383 	/* translators: default GMT offset or timezone string. Must be either a valid offset (-12 to 14)
   365 	   or a valid timezone string (America/New_York). See http://us3.php.net/manual/en/timezones.php
   384 	   or a valid timezone string (America/New_York). See https://secure.php.net/manual/en/timezones.php
   366 	   for all timezone strings supported by PHP.
   385 	   for all timezone strings supported by PHP.
   367 	*/
   386 	*/
   368 	$offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
   387 	$offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
   369 	if ( is_numeric( $offset_or_tz ) )
   388 	if ( is_numeric( $offset_or_tz ) )
   370 		$gmt_offset = $offset_or_tz;
   389 		$gmt_offset = $offset_or_tz;
   373 
   392 
   374 	$options = array(
   393 	$options = array(
   375 	'siteurl' => $guessurl,
   394 	'siteurl' => $guessurl,
   376 	'home' => $guessurl,
   395 	'home' => $guessurl,
   377 	'blogname' => __('My Site'),
   396 	'blogname' => __('My Site'),
   378 	/* translators: blog tagline */
   397 	/* translators: site tagline */
   379 	'blogdescription' => __('Just another WordPress site'),
   398 	'blogdescription' => __('Just another WordPress site'),
   380 	'users_can_register' => 0,
   399 	'users_can_register' => 0,
   381 	'admin_email' => 'you@example.com',
   400 	'admin_email' => 'you@example.com',
   382 	/* translators: default start of the week. 0 = Sunday, 1 = Monday */
   401 	/* translators: default start of the week. 0 = Sunday, 1 = Monday */
   383 	'start_of_week' => _x( '1', 'start of week' ),
   402 	'start_of_week' => _x( '1', 'start of week' ),
   394 	'default_category' => 1,
   413 	'default_category' => 1,
   395 	'default_comment_status' => 'open',
   414 	'default_comment_status' => 'open',
   396 	'default_ping_status' => 'open',
   415 	'default_ping_status' => 'open',
   397 	'default_pingback_flag' => 1,
   416 	'default_pingback_flag' => 1,
   398 	'posts_per_page' => 10,
   417 	'posts_per_page' => 10,
   399 	/* translators: default date format, see http://php.net/date */
   418 	/* translators: default date format, see https://secure.php.net/date */
   400 	'date_format' => __('F j, Y'),
   419 	'date_format' => __('F j, Y'),
   401 	/* translators: default time format, see http://php.net/date */
   420 	/* translators: default time format, see https://secure.php.net/date */
   402 	'time_format' => __('g:i a'),
   421 	'time_format' => __('g:i a'),
   403 	/* translators: links last updated date format, see http://php.net/date */
   422 	/* translators: links last updated date format, see https://secure.php.net/date */
   404 	'links_updated_date_format' => __('F j, Y g:i a'),
   423 	'links_updated_date_format' => __('F j, Y g:i a'),
   405 	'comment_moderation' => 0,
   424 	'comment_moderation' => 0,
   406 	'moderation_notify' => 1,
   425 	'moderation_notify' => 1,
   407 	'permalink_structure' => '',
   426 	'permalink_structure' => '',
   408 	'gzipcompression' => 0,
   427 	'rewrite_rules' => '',
   409 	'hack_file' => 0,
   428 	'hack_file' => 0,
   410 	'blog_charset' => 'UTF-8',
   429 	'blog_charset' => 'UTF-8',
   411 	'moderation_keys' => '',
   430 	'moderation_keys' => '',
   412 	'active_plugins' => array(),
   431 	'active_plugins' => array(),
   413 	'category_base' => '',
   432 	'category_base' => '',
   414 	'ping_sites' => 'http://rpc.pingomatic.com/',
   433 	'ping_sites' => 'http://rpc.pingomatic.com/',
   415 	'advanced_edit' => 0,
       
   416 	'comment_max_links' => 2,
   434 	'comment_max_links' => 2,
   417 	'gmt_offset' => $gmt_offset,
   435 	'gmt_offset' => $gmt_offset,
   418 
   436 
   419 	// 1.5
   437 	// 1.5
   420 	'default_email_category' => 1,
   438 	'default_email_category' => 1,
   421 	'recently_edited' => '',
   439 	'recently_edited' => '',
   422 	'template' => $template,
   440 	'template' => $template,
   423 	'stylesheet' => WP_DEFAULT_THEME,
   441 	'stylesheet' => $stylesheet,
   424 	'comment_whitelist' => 1,
   442 	'comment_whitelist' => 1,
   425 	'blacklist_keys' => '',
   443 	'blacklist_keys' => '',
   426 	'comment_registration' => 0,
   444 	'comment_registration' => 0,
   427 	'html_type' => 'text/html',
   445 	'html_type' => 'text/html',
   428 
   446 
   459 	'avatar_default' => 'mystery',
   477 	'avatar_default' => 'mystery',
   460 
   478 
   461 	// 2.7
   479 	// 2.7
   462 	'large_size_w' => 1024,
   480 	'large_size_w' => 1024,
   463 	'large_size_h' => 1024,
   481 	'large_size_h' => 1024,
   464 	'image_default_link_type' => 'file',
   482 	'image_default_link_type' => 'none',
   465 	'image_default_size' => '',
   483 	'image_default_size' => '',
   466 	'image_default_align' => '',
   484 	'image_default_align' => '',
   467 	'close_comments_for_old_posts' => 0,
   485 	'close_comments_for_old_posts' => 0,
   468 	'close_comments_days_old' => 14,
   486 	'close_comments_days_old' => 14,
   469 	'thread_comments' => 1,
   487 	'thread_comments' => 1,
   488 	// 3.1
   506 	// 3.1
   489 	'default_post_format' => 0,
   507 	'default_post_format' => 0,
   490 
   508 
   491 	// 3.5
   509 	// 3.5
   492 	'link_manager_enabled' => 0,
   510 	'link_manager_enabled' => 0,
       
   511 
       
   512 	// 4.3.0
       
   513 	'finished_splitting_shared_terms' => 1,
       
   514 	'site_icon' => 0,
       
   515 
       
   516 	// 4.4.0
       
   517 	'medium_large_size_w' => 768,
       
   518 	'medium_large_size_h' => 0,
       
   519 
       
   520 		// 4.9.6
       
   521 		'wp_page_for_privacy_policy'      => 0,
       
   522 
       
   523 		// 4.9.8
       
   524 		'show_comments_cookies_opt_in'    => 0,
   493 	);
   525 	);
   494 
   526 
   495 	// 3.3
   527 	// 3.3
   496 	if ( ! is_multisite() ) {
   528 	if ( ! is_multisite() ) {
   497 		$options['initial_db_version'] = ! empty( $wp_current_db_version ) && $wp_current_db_version < $wp_db_version
   529 		$options['initial_db_version'] = ! empty( $wp_current_db_version ) && $wp_current_db_version < $wp_db_version
   498 			? $wp_current_db_version : $wp_db_version;
   530 			? $wp_current_db_version : $wp_db_version;
   499 	}
   531 	}
   500 
   532 
   501 	// 3.0 multisite
   533 	// 3.0 multisite
   502 	if ( is_multisite() ) {
   534 	if ( is_multisite() ) {
   503 		/* translators: blog tagline */
   535 		/* translators: site tagline */
   504 		$options[ 'blogdescription' ] = sprintf(__('Just another %s site'), get_current_site()->site_name );
   536 		$options[ 'blogdescription' ] = sprintf(__('Just another %s site'), get_network()->site_name );
   505 		$options[ 'permalink_structure' ] = '/%year%/%monthnum%/%day%/%postname%/';
   537 		$options[ 'permalink_structure' ] = '/%year%/%monthnum%/%day%/%postname%/';
   506 	}
   538 	}
   507 
   539 
   508 	// Set autoload to no for these options
   540 	// Set autoload to no for these options
   509 	$fat_options = array( 'moderation_keys', 'recently_edited', 'blacklist_keys', 'uninstall_plugins' );
   541 	$fat_options = array( 'moderation_keys', 'recently_edited', 'blacklist_keys', 'uninstall_plugins' );
   548 		'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce',
   580 		'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce',
   549 		'_wp_http_referer', 'Update', 'action', 'rich_editing', 'autosave_interval', 'deactivated_plugins',
   581 		'_wp_http_referer', 'Update', 'action', 'rich_editing', 'autosave_interval', 'deactivated_plugins',
   550 		'can_compress_scripts', 'page_uris', 'update_core', 'update_plugins', 'update_themes', 'doing_cron',
   582 		'can_compress_scripts', 'page_uris', 'update_core', 'update_plugins', 'update_themes', 'doing_cron',
   551 		'random_seed', 'rss_excerpt_length', 'secret', 'use_linksupdate', 'default_comment_status_page',
   583 		'random_seed', 'rss_excerpt_length', 'secret', 'use_linksupdate', 'default_comment_status_page',
   552 		'wporg_popular_tags', 'what_to_show', 'rss_language', 'language', 'enable_xmlrpc', 'enable_app',
   584 		'wporg_popular_tags', 'what_to_show', 'rss_language', 'language', 'enable_xmlrpc', 'enable_app',
   553 		'embed_autourls', 'default_post_edit_rows',
   585 		'embed_autourls', 'default_post_edit_rows', 'gzipcompression', 'advanced_edit'
   554 	);
   586 	);
   555 	foreach ( $unusedoptions as $option )
   587 	foreach ( $unusedoptions as $option )
   556 		delete_option($option);
   588 		delete_option($option);
   557 
   589 
   558 	// Delete obsolete magpie stuff.
   590 	// Delete obsolete magpie stuff.
   559 	$wpdb->query("DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'");
   591 	$wpdb->query("DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'");
   560 
   592 
   561 	/*
   593 	// Clear expired transients
   562 	 * Deletes all expired transients. The multi-table delete syntax is used
   594 	delete_expired_transients( true );
   563 	 * to delete the transient record from table a, and the corresponding
       
   564 	 * transient_timeout record from table b.
       
   565 	 */
       
   566 	$time = time();
       
   567 	$sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
       
   568 		WHERE a.option_name LIKE %s
       
   569 		AND a.option_name NOT LIKE %s
       
   570 		AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
       
   571 		AND b.option_value < %d";
       
   572 	$wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', $time ) );
       
   573 
       
   574 	if ( is_main_site() && is_main_network() ) {
       
   575 		$sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
       
   576 			WHERE a.option_name LIKE %s
       
   577 			AND a.option_name NOT LIKE %s
       
   578 			AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
       
   579 			AND b.option_value < %d";
       
   580 		$wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', $time ) );
       
   581 	}
       
   582 }
   595 }
   583 
   596 
   584 /**
   597 /**
   585  * Execute WordPress role creation for the various WordPress versions.
   598  * Execute WordPress role creation for the various WordPress versions.
   586  *
   599  *
   826 
   839 
   827 	if ( !empty( $role ) ) {
   840 	if ( !empty( $role ) ) {
   828 		$role->add_cap( 'update_core' );
   841 		$role->add_cap( 'update_core' );
   829 		$role->add_cap( 'list_users' );
   842 		$role->add_cap( 'list_users' );
   830 		$role->add_cap( 'remove_users' );
   843 		$role->add_cap( 'remove_users' );
   831 
       
   832 		/*
       
   833 		 * Never used, will be removed. create_users or promote_users
       
   834 		 * is the capability you're looking for.
       
   835 		 */
       
   836 		$role->add_cap( 'add_users' );
       
   837 
       
   838 		$role->add_cap( 'promote_users' );
   844 		$role->add_cap( 'promote_users' );
   839 		$role->add_cap( 'edit_theme_options' );
   845 		$role->add_cap( 'edit_theme_options' );
   840 		$role->add_cap( 'delete_themes' );
   846 		$role->add_cap( 'delete_themes' );
   841 		$role->add_cap( 'export' );
   847 		$role->add_cap( 'export' );
   842 	}
   848 	}
   843 }
   849 }
   844 
   850 
       
   851 if ( !function_exists( 'install_network' ) ) :
   845 /**
   852 /**
   846  * Install Network.
   853  * Install Network.
   847  *
   854  *
   848  * @since 3.0.0
   855  * @since 3.0.0
   849  *
   856  */
   850  */
       
   851 if ( !function_exists( 'install_network' ) ) :
       
   852 function install_network() {
   857 function install_network() {
   853 	if ( ! defined( 'WP_INSTALLING_NETWORK' ) )
   858 	if ( ! defined( 'WP_INSTALLING_NETWORK' ) )
   854 		define( 'WP_INSTALLING_NETWORK', true );
   859 		define( 'WP_INSTALLING_NETWORK', true );
   855 
   860 
   856 	dbDelta( wp_get_db_schema( 'global' ) );
   861 	dbDelta( wp_get_db_schema( 'global' ) );
   860 /**
   865 /**
   861  * Populate network settings.
   866  * Populate network settings.
   862  *
   867  *
   863  * @since 3.0.0
   868  * @since 3.0.0
   864  *
   869  *
   865  * @param int $network_id ID of network to populate.
   870  * @global wpdb       $wpdb
   866  * @return bool|WP_Error True on success, or WP_Error on warning (with the install otherwise successful,
   871  * @global object     $current_site
       
   872  * @global int        $wp_db_version
       
   873  * @global WP_Rewrite $wp_rewrite
       
   874  *
       
   875  * @param int    $network_id        ID of network to populate.
       
   876  * @param string $domain            The domain name for the network (eg. "example.com").
       
   877  * @param string $email             Email address for the network administrator.
       
   878  * @param string $site_name         The name of the network.
       
   879  * @param string $path              Optional. The path to append to the network's domain name. Default '/'.
       
   880  * @param bool   $subdomain_install Optional. Whether the network is a subdomain installation or a subdirectory installation.
       
   881  *                                  Default false, meaning the network is a subdirectory installation.
       
   882  * @return bool|WP_Error True on success, or WP_Error on warning (with the installation otherwise successful,
   867  *                       so the error code must be checked) or failure.
   883  *                       so the error code must be checked) or failure.
   868  */
   884  */
   869 function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
   885 function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
   870 	global $wpdb, $current_site, $wp_db_version, $wp_rewrite;
   886 	global $wpdb, $current_site, $wp_db_version, $wp_rewrite;
   871 
   887 
   874 		$errors->add( 'empty_domain', __( 'You must provide a domain name.' ) );
   890 		$errors->add( 'empty_domain', __( 'You must provide a domain name.' ) );
   875 	if ( '' == $site_name )
   891 	if ( '' == $site_name )
   876 		$errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) );
   892 		$errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) );
   877 
   893 
   878 	// Check for network collision.
   894 	// Check for network collision.
   879 	if ( $network_id == $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id ) ) )
   895 	$network_exists = false;
   880 		$errors->add( 'siteid_exists', __( 'The network already exists.' ) );
   896 	if ( is_multisite() ) {
   881 
   897 		if ( get_network( (int) $network_id ) ) {
   882 	$site_user = get_user_by( 'email', $email );
   898 			$errors->add( 'siteid_exists', __( 'The network already exists.' ) );
       
   899 		}
       
   900 	} else {
       
   901 		if ( $network_id == $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id ) ) ) {
       
   902 			$errors->add( 'siteid_exists', __( 'The network already exists.' ) );
       
   903 		}
       
   904 	}
       
   905 
   883 	if ( ! is_email( $email ) )
   906 	if ( ! is_email( $email ) )
   884 		$errors->add( 'invalid_email', __( 'You must provide a valid e-mail address.' ) );
   907 		$errors->add( 'invalid_email', __( 'You must provide a valid email address.' ) );
   885 
   908 
   886 	if ( $errors->get_error_code() )
   909 	if ( $errors->get_error_code() )
   887 		return $errors;
   910 		return $errors;
       
   911 
       
   912 	// If a user with the provided email does not exist, default to the current user as the new network admin.
       
   913 	$site_user = get_user_by( 'email', $email );
       
   914 	if ( false === $site_user ) {
       
   915 		$site_user = wp_get_current_user();
       
   916 	}
   888 
   917 
   889 	// Set up site tables.
   918 	// Set up site tables.
   890 	$template = get_option( 'template' );
   919 	$template = get_option( 'template' );
   891 	$stylesheet = get_option( 'stylesheet' );
   920 	$stylesheet = get_option( 'stylesheet' );
   892 	$allowed_themes = array( $stylesheet => true );
   921 	$allowed_themes = array( $stylesheet => true );
   893 	if ( $template != $stylesheet )
   922 
       
   923 	if ( $template != $stylesheet ) {
   894 		$allowed_themes[ $template ] = true;
   924 		$allowed_themes[ $template ] = true;
   895 	if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template )
   925 	}
       
   926 
       
   927 	if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) {
   896 		$allowed_themes[ WP_DEFAULT_THEME ] = true;
   928 		$allowed_themes[ WP_DEFAULT_THEME ] = true;
       
   929 	}
       
   930 
       
   931 	// If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme.
       
   932 	if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
       
   933 		if ( $core_default = WP_Theme::get_core_default_theme() ) {
       
   934 			$allowed_themes[ $core_default->get_stylesheet() ] = true;
       
   935 		}
       
   936 	}
   897 
   937 
   898 	if ( 1 == $network_id ) {
   938 	if ( 1 == $network_id ) {
   899 		$wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) );
   939 		$wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) );
   900 		$network_id = $wpdb->insert_id;
   940 		$network_id = $wpdb->insert_id;
   901 	} else {
   941 	} else {
   904 
   944 
   905 	wp_cache_delete( 'networks_have_paths', 'site-options' );
   945 	wp_cache_delete( 'networks_have_paths', 'site-options' );
   906 
   946 
   907 	if ( !is_multisite() ) {
   947 	if ( !is_multisite() ) {
   908 		$site_admins = array( $site_user->user_login );
   948 		$site_admins = array( $site_user->user_login );
   909 		$users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) );
   949 		$users = get_users( array(
       
   950 			'fields' => array( 'user_login' ),
       
   951 			'role'   => 'administrator',
       
   952 		) );
   910 		if ( $users ) {
   953 		if ( $users ) {
   911 			foreach ( $users as $user ) {
   954 			foreach ( $users as $user ) {
   912 				if ( is_super_admin( $user->ID ) && !in_array( $user->user_login, $site_admins ) )
   955 				$site_admins[] = $user->user_login;
   913 					$site_admins[] = $user->user_login;
       
   914 			}
   956 			}
       
   957 
       
   958 			$site_admins = array_unique( $site_admins );
   915 		}
   959 		}
   916 	} else {
   960 	} else {
   917 		$site_admins = get_site_option( 'site_admins' );
   961 		$site_admins = get_site_option( 'site_admins' );
   918 	}
   962 	}
   919 
   963 
       
   964 	/* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
   920 	$welcome_email = __( 'Howdy USERNAME,
   965 	$welcome_email = __( 'Howdy USERNAME,
   921 
   966 
   922 Your new SITE_NAME site has been successfully set up at:
   967 Your new SITE_NAME site has been successfully set up at:
   923 BLOG_URL
   968 BLOG_URL
   924 
   969 
   946 	$video_exts = wp_get_video_extensions();
   991 	$video_exts = wp_get_video_extensions();
   947 	$upload_filetypes = array_unique( array_merge( $misc_exts, $audio_exts, $video_exts ) );
   992 	$upload_filetypes = array_unique( array_merge( $misc_exts, $audio_exts, $video_exts ) );
   948 
   993 
   949 	$sitemeta = array(
   994 	$sitemeta = array(
   950 		'site_name' => $site_name,
   995 		'site_name' => $site_name,
   951 		'admin_email' => $site_user->user_email,
   996 		'admin_email' => $email,
   952 		'admin_user_id' => $site_user->ID,
   997 		'admin_user_id' => $site_user->ID,
   953 		'registration' => 'none',
   998 		'registration' => 'none',
   954 		'upload_filetypes' => implode( ' ', $upload_filetypes ),
   999 		'upload_filetypes' => implode( ' ', $upload_filetypes ),
   955 		'blog_upload_space' => 100,
  1000 		'blog_upload_space' => 100,
   956 		'fileupload_maxk' => 1500,
  1001 		'fileupload_maxk' => 1500,
   957 		'site_admins' => $site_admins,
  1002 		'site_admins' => $site_admins,
   958 		'allowedthemes' => $allowed_themes,
  1003 		'allowedthemes' => $allowed_themes,
   959 		'illegal_names' => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ),
  1004 		'illegal_names' => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ),
   960 		'wpmu_upgrade_site' => $wp_db_version,
  1005 		'wpmu_upgrade_site' => $wp_db_version,
   961 		'welcome_email' => $welcome_email,
  1006 		'welcome_email' => $welcome_email,
   962 		'first_post' => __( 'Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start blogging!' ),
  1007 		/* translators: %s: site link */
       
  1008 		'first_post' => __( 'Welcome to %s. This is your first post. Edit or delete it, then start blogging!' ),
   963 		// @todo - network admins should have a method of editing the network siteurl (used for cookie hash)
  1009 		// @todo - network admins should have a method of editing the network siteurl (used for cookie hash)
   964 		'siteurl' => get_option( 'siteurl' ) . '/',
  1010 		'siteurl' => get_option( 'siteurl' ) . '/',
   965 		'add_new_users' => '0',
  1011 		'add_new_users' => '0',
   966 		'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
  1012 		'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
   967 		'subdomain_install' => intval( $subdomain_install ),
  1013 		'subdomain_install' => intval( $subdomain_install ),
   973 	);
  1019 	);
   974 	if ( ! $subdomain_install )
  1020 	if ( ! $subdomain_install )
   975 		$sitemeta['illegal_names'][] = 'blog';
  1021 		$sitemeta['illegal_names'][] = 'blog';
   976 
  1022 
   977 	/**
  1023 	/**
   978 	 * Filter meta for a network on creation.
  1024 	 * Filters meta for a network on creation.
   979 	 *
  1025 	 *
   980 	 * @since 3.7.0
  1026 	 * @since 3.7.0
   981 	 *
  1027 	 *
   982 	 * @param array $sitemeta   Associative array of network meta keys and values to be inserted.
  1028 	 * @param array $sitemeta   Associative array of network meta keys and values to be inserted.
   983 	 * @param int   $network_id ID of network to populate.
  1029 	 * @param int   $network_id ID of network to populate.
  1030 		elseif ( 200 == wp_remote_retrieve_response_code( $page ) )
  1076 		elseif ( 200 == wp_remote_retrieve_response_code( $page ) )
  1031 				$vhost_ok = true;
  1077 				$vhost_ok = true;
  1032 
  1078 
  1033 		if ( ! $vhost_ok ) {
  1079 		if ( ! $vhost_ok ) {
  1034 			$msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
  1080 			$msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
  1035 			$msg .= '<p>' . sprintf( __( 'The installer attempted to contact a random hostname (<code>%1$s</code>) on your domain.' ), $hostname );
  1081 
  1036 			if ( ! empty ( $errstr ) )
  1082 			$msg .= '<p>' . sprintf(
       
  1083 				/* translators: %s: host name */
       
  1084 				__( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
       
  1085 				'<code>' . $hostname . '</code>'
       
  1086 			);
       
  1087 			if ( ! empty ( $errstr ) ) {
       
  1088 				/* translators: %s: error message */
  1037 				$msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
  1089 				$msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
       
  1090 			}
  1038 			$msg .= '</p>';
  1091 			$msg .= '</p>';
  1039 			$msg .= '<p>' . __( 'To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a <code>*</code> hostname record pointing at your web server in your DNS configuration tool.' ) . '</p>';
  1092 
       
  1093 			$msg .= '<p>' . sprintf(
       
  1094 				/* translators: %s: asterisk symbol (*) */
       
  1095 				__( '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.' ),
       
  1096 				'<code>*</code>'
       
  1097 			) . '</p>';
       
  1098 
  1040 			$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>';
  1099 			$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>';
       
  1100 
  1041 			return new WP_Error( 'no_wildcard_dns', $msg );
  1101 			return new WP_Error( 'no_wildcard_dns', $msg );
  1042 		}
  1102 		}
  1043 	}
  1103 	}
  1044 
  1104 
  1045 	return true;
  1105 	return true;