]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/includes/schema.php
WordPress 4.7.2-scripts
[autoinstalls/wordpress.git] / wp-admin / includes / schema.php
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
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 && $blog_id != $wpdb->blogid )
42                 $old_blog_id = $wpdb->set_blog_id( $blog_id );
43
44         // Engage multisite if in the middle of turning it on from network.php.
45         $is_multisite = is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK );
46
47         /*
48          * Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
49          * As of 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
50          * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
51          */
52         $max_index_length = 191;
53
54         // Blog specific tables.
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 (
65  term_id bigint(20) unsigned NOT NULL auto_increment,
66  name varchar(200) NOT NULL default '',
67  slug varchar(200) NOT NULL default '',
68  term_group bigint(10) NOT NULL default 0,
69  PRIMARY KEY  (term_id),
70  KEY slug (slug($max_index_length)),
71  KEY name (name($max_index_length))
72 ) $charset_collate;
73 CREATE TABLE $wpdb->term_taxonomy (
74  term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment,
75  term_id bigint(20) unsigned NOT NULL default 0,
76  taxonomy varchar(32) NOT NULL default '',
77  description longtext NOT NULL,
78  parent bigint(20) unsigned NOT NULL default 0,
79  count bigint(20) NOT NULL default 0,
80  PRIMARY KEY  (term_taxonomy_id),
81  UNIQUE KEY term_id_taxonomy (term_id,taxonomy),
82  KEY taxonomy (taxonomy)
83 ) $charset_collate;
84 CREATE TABLE $wpdb->term_relationships (
85  object_id bigint(20) unsigned NOT NULL default 0,
86  term_taxonomy_id bigint(20) unsigned NOT NULL default 0,
87  term_order int(11) NOT NULL default 0,
88  PRIMARY KEY  (object_id,term_taxonomy_id),
89  KEY term_taxonomy_id (term_taxonomy_id)
90 ) $charset_collate;
91 CREATE TABLE $wpdb->commentmeta (
92   meta_id bigint(20) unsigned NOT NULL auto_increment,
93   comment_id bigint(20) unsigned NOT NULL default '0',
94   meta_key varchar(255) default NULL,
95   meta_value longtext,
96   PRIMARY KEY  (meta_id),
97   KEY comment_id (comment_id),
98   KEY meta_key (meta_key($max_index_length))
99 ) $charset_collate;
100 CREATE TABLE $wpdb->comments (
101   comment_ID bigint(20) unsigned NOT NULL auto_increment,
102   comment_post_ID bigint(20) unsigned NOT NULL default '0',
103   comment_author tinytext NOT NULL,
104   comment_author_email varchar(100) NOT NULL default '',
105   comment_author_url varchar(200) NOT NULL default '',
106   comment_author_IP varchar(100) NOT NULL default '',
107   comment_date datetime NOT NULL default '0000-00-00 00:00:00',
108   comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
109   comment_content text NOT NULL,
110   comment_karma int(11) NOT NULL default '0',
111   comment_approved varchar(20) NOT NULL default '1',
112   comment_agent varchar(255) NOT NULL default '',
113   comment_type varchar(20) NOT NULL default '',
114   comment_parent bigint(20) unsigned NOT NULL default '0',
115   user_id bigint(20) unsigned NOT NULL default '0',
116   PRIMARY KEY  (comment_ID),
117   KEY comment_post_ID (comment_post_ID),
118   KEY comment_approved_date_gmt (comment_approved,comment_date_gmt),
119   KEY comment_date_gmt (comment_date_gmt),
120   KEY comment_parent (comment_parent),
121   KEY comment_author_email (comment_author_email(10))
122 ) $charset_collate;
123 CREATE TABLE $wpdb->links (
124   link_id bigint(20) unsigned NOT NULL auto_increment,
125   link_url varchar(255) NOT NULL default '',
126   link_name varchar(255) NOT NULL default '',
127   link_image varchar(255) NOT NULL default '',
128   link_target varchar(25) NOT NULL default '',
129   link_description varchar(255) NOT NULL default '',
130   link_visible varchar(20) NOT NULL default 'Y',
131   link_owner bigint(20) unsigned NOT NULL default '1',
132   link_rating int(11) NOT NULL default '0',
133   link_updated datetime NOT NULL default '0000-00-00 00:00:00',
134   link_rel varchar(255) NOT NULL default '',
135   link_notes mediumtext NOT NULL,
136   link_rss varchar(255) NOT NULL default '',
137   PRIMARY KEY  (link_id),
138   KEY link_visible (link_visible)
139 ) $charset_collate;
140 CREATE TABLE $wpdb->options (
141   option_id bigint(20) unsigned NOT NULL auto_increment,
142   option_name varchar(191) NOT NULL default '',
143   option_value longtext NOT NULL,
144   autoload varchar(20) NOT NULL default 'yes',
145   PRIMARY KEY  (option_id),
146   UNIQUE KEY option_name (option_name)
147 ) $charset_collate;
148 CREATE TABLE $wpdb->postmeta (
149   meta_id bigint(20) unsigned NOT NULL auto_increment,
150   post_id bigint(20) unsigned NOT NULL default '0',
151   meta_key varchar(255) default NULL,
152   meta_value longtext,
153   PRIMARY KEY  (meta_id),
154   KEY post_id (post_id),
155   KEY meta_key (meta_key($max_index_length))
156 ) $charset_collate;
157 CREATE TABLE $wpdb->posts (
158   ID bigint(20) unsigned NOT NULL auto_increment,
159   post_author bigint(20) unsigned NOT NULL default '0',
160   post_date datetime NOT NULL default '0000-00-00 00:00:00',
161   post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
162   post_content longtext NOT NULL,
163   post_title text NOT NULL,
164   post_excerpt text NOT NULL,
165   post_status varchar(20) NOT NULL default 'publish',
166   comment_status varchar(20) NOT NULL default 'open',
167   ping_status varchar(20) NOT NULL default 'open',
168   post_password varchar(255) NOT NULL default '',
169   post_name varchar(200) NOT NULL default '',
170   to_ping text NOT NULL,
171   pinged text NOT NULL,
172   post_modified datetime NOT NULL default '0000-00-00 00:00:00',
173   post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
174   post_content_filtered longtext NOT NULL,
175   post_parent bigint(20) unsigned NOT NULL default '0',
176   guid varchar(255) NOT NULL default '',
177   menu_order int(11) NOT NULL default '0',
178   post_type varchar(20) NOT NULL default 'post',
179   post_mime_type varchar(100) NOT NULL default '',
180   comment_count bigint(20) NOT NULL default '0',
181   PRIMARY KEY  (ID),
182   KEY post_name (post_name($max_index_length)),
183   KEY type_status_date (post_type,post_status,post_date,ID),
184   KEY post_parent (post_parent),
185   KEY post_author (post_author)
186 ) $charset_collate;\n";
187
188         // Single site users table. The multisite flavor of the users table is handled below.
189         $users_single_table = "CREATE TABLE $wpdb->users (
190   ID bigint(20) unsigned NOT NULL auto_increment,
191   user_login varchar(60) NOT NULL default '',
192   user_pass varchar(255) NOT NULL default '',
193   user_nicename varchar(50) NOT NULL default '',
194   user_email varchar(100) NOT NULL default '',
195   user_url varchar(100) NOT NULL default '',
196   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
197   user_activation_key varchar(255) NOT NULL default '',
198   user_status int(11) NOT NULL default '0',
199   display_name varchar(250) NOT NULL default '',
200   PRIMARY KEY  (ID),
201   KEY user_login_key (user_login),
202   KEY user_nicename (user_nicename),
203   KEY user_email (user_email)
204 ) $charset_collate;\n";
205
206         // Multisite users table
207         $users_multi_table = "CREATE TABLE $wpdb->users (
208   ID bigint(20) unsigned NOT NULL auto_increment,
209   user_login varchar(60) NOT NULL default '',
210   user_pass varchar(255) NOT NULL default '',
211   user_nicename varchar(50) NOT NULL default '',
212   user_email varchar(100) NOT NULL default '',
213   user_url varchar(100) NOT NULL default '',
214   user_registered datetime NOT NULL default '0000-00-00 00:00:00',
215   user_activation_key varchar(255) NOT NULL default '',
216   user_status int(11) NOT NULL default '0',
217   display_name varchar(250) NOT NULL default '',
218   spam tinyint(2) NOT NULL default '0',
219   deleted tinyint(2) NOT NULL default '0',
220   PRIMARY KEY  (ID),
221   KEY user_login_key (user_login),
222   KEY user_nicename (user_nicename),
223   KEY user_email (user_email)
224 ) $charset_collate;\n";
225
226         // Usermeta.
227         $usermeta_table = "CREATE TABLE $wpdb->usermeta (
228   umeta_id bigint(20) unsigned NOT NULL auto_increment,
229   user_id bigint(20) unsigned NOT NULL default '0',
230   meta_key varchar(255) default NULL,
231   meta_value longtext,
232   PRIMARY KEY  (umeta_id),
233   KEY user_id (user_id),
234   KEY meta_key (meta_key($max_index_length))
235 ) $charset_collate;\n";
236
237         // Global tables
238         if ( $is_multisite )
239                 $global_tables = $users_multi_table . $usermeta_table;
240         else
241                 $global_tables = $users_single_table . $usermeta_table;
242
243         // Multisite global tables.
244         $ms_global_tables = "CREATE TABLE $wpdb->blogs (
245   blog_id bigint(20) NOT NULL auto_increment,
246   site_id bigint(20) NOT NULL default '0',
247   domain varchar(200) NOT NULL default '',
248   path varchar(100) NOT NULL default '',
249   registered datetime NOT NULL default '0000-00-00 00:00:00',
250   last_updated datetime NOT NULL default '0000-00-00 00:00:00',
251   public tinyint(2) NOT NULL default '1',
252   archived tinyint(2) NOT NULL default '0',
253   mature tinyint(2) NOT NULL default '0',
254   spam tinyint(2) NOT NULL default '0',
255   deleted tinyint(2) NOT NULL default '0',
256   lang_id int(11) NOT NULL default '0',
257   PRIMARY KEY  (blog_id),
258   KEY domain (domain(50),path(5)),
259   KEY lang_id (lang_id)
260 ) $charset_collate;
261 CREATE TABLE $wpdb->blog_versions (
262   blog_id bigint(20) NOT NULL default '0',
263   db_version varchar(20) NOT NULL default '',
264   last_updated datetime NOT NULL default '0000-00-00 00:00:00',
265   PRIMARY KEY  (blog_id),
266   KEY db_version (db_version)
267 ) $charset_collate;
268 CREATE TABLE $wpdb->registration_log (
269   ID bigint(20) NOT NULL auto_increment,
270   email varchar(255) NOT NULL default '',
271   IP varchar(30) NOT NULL default '',
272   blog_id bigint(20) NOT NULL default '0',
273   date_registered datetime NOT NULL default '0000-00-00 00:00:00',
274   PRIMARY KEY  (ID),
275   KEY IP (IP)
276 ) $charset_collate;
277 CREATE TABLE $wpdb->site (
278   id bigint(20) NOT NULL auto_increment,
279   domain varchar(200) NOT NULL default '',
280   path varchar(100) NOT NULL default '',
281   PRIMARY KEY  (id),
282   KEY domain (domain(140),path(51))
283 ) $charset_collate;
284 CREATE TABLE $wpdb->sitemeta (
285   meta_id bigint(20) NOT NULL auto_increment,
286   site_id bigint(20) NOT NULL default '0',
287   meta_key varchar(255) default NULL,
288   meta_value longtext,
289   PRIMARY KEY  (meta_id),
290   KEY meta_key (meta_key($max_index_length)),
291   KEY site_id (site_id)
292 ) $charset_collate;
293 CREATE TABLE $wpdb->signups (
294   signup_id bigint(20) NOT NULL auto_increment,
295   domain varchar(200) NOT NULL default '',
296   path varchar(100) NOT NULL default '',
297   title longtext NOT NULL,
298   user_login varchar(60) NOT NULL default '',
299   user_email varchar(100) NOT NULL default '',
300   registered datetime NOT NULL default '0000-00-00 00:00:00',
301   activated datetime NOT NULL default '0000-00-00 00:00:00',
302   active tinyint(1) NOT NULL default '0',
303   activation_key varchar(50) NOT NULL default '',
304   meta longtext,
305   PRIMARY KEY  (signup_id),
306   KEY activation_key (activation_key),
307   KEY user_email (user_email),
308   KEY user_login_email (user_login,user_email),
309   KEY domain_path (domain(140),path(51))
310 ) $charset_collate;";
311
312         switch ( $scope ) {
313                 case 'blog' :
314                         $queries = $blog_tables;
315                         break;
316                 case 'global' :
317                         $queries = $global_tables;
318                         if ( $is_multisite )
319                                 $queries .= $ms_global_tables;
320                         break;
321                 case 'ms_global' :
322                         $queries = $ms_global_tables;
323                         break;
324                 case 'all' :
325                 default:
326                         $queries = $global_tables . $blog_tables;
327                         if ( $is_multisite )
328                                 $queries .= $ms_global_tables;
329                         break;
330         }
331
332         if ( isset( $old_blog_id ) )
333                 $wpdb->set_blog_id( $old_blog_id );
334
335         return $queries;
336 }
337
338 // Populate for back compat.
339 $wp_queries = wp_get_db_schema( 'all' );
340
341 /**
342  * Create WordPress options and set the default values.
343  *
344  * @since 1.5.0
345  *
346  * @global wpdb $wpdb WordPress database abstraction object.
347  * @global int  $wp_db_version
348  * @global int  $wp_current_db_version
349  */
350 function populate_options() {
351         global $wpdb, $wp_db_version, $wp_current_db_version;
352
353         $guessurl = wp_guess_url();
354         /**
355          * Fires before creating WordPress options and populating their default values.
356          *
357          * @since 2.6.0
358          */
359         do_action( 'populate_options' );
360
361         if ( ini_get('safe_mode') ) {
362                 // Safe mode can break mkdir() so use a flat structure by default.
363                 $uploads_use_yearmonth_folders = 0;
364         } else {
365                 $uploads_use_yearmonth_folders = 1;
366         }
367
368         // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
369         $stylesheet = $template = WP_DEFAULT_THEME;
370         $theme = wp_get_theme( WP_DEFAULT_THEME );
371         if ( ! $theme->exists() ) {
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         }
380
381         $timezone_string = '';
382         $gmt_offset = 0;
383         /* translators: default GMT offset or timezone string. Must be either a valid offset (-12 to 14)
384            or a valid timezone string (America/New_York). See https://secure.php.net/manual/en/timezones.php
385            for all timezone strings supported by PHP.
386         */
387         $offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
388         if ( is_numeric( $offset_or_tz ) )
389                 $gmt_offset = $offset_or_tz;
390         elseif ( $offset_or_tz && in_array( $offset_or_tz, timezone_identifiers_list() ) )
391                         $timezone_string = $offset_or_tz;
392
393         $options = array(
394         'siteurl' => $guessurl,
395         'home' => $guessurl,
396         'blogname' => __('My Site'),
397         /* translators: site tagline */
398         'blogdescription' => __('Just another WordPress site'),
399         'users_can_register' => 0,
400         'admin_email' => 'you@example.com',
401         /* translators: default start of the week. 0 = Sunday, 1 = Monday */
402         'start_of_week' => _x( '1', 'start of week' ),
403         'use_balanceTags' => 0,
404         'use_smilies' => 1,
405         'require_name_email' => 1,
406         'comments_notify' => 1,
407         'posts_per_rss' => 10,
408         'rss_use_excerpt' => 0,
409         'mailserver_url' => 'mail.example.com',
410         'mailserver_login' => 'login@example.com',
411         'mailserver_pass' => 'password',
412         'mailserver_port' => 110,
413         'default_category' => 1,
414         'default_comment_status' => 'open',
415         'default_ping_status' => 'open',
416         'default_pingback_flag' => 1,
417         'posts_per_page' => 10,
418         /* translators: default date format, see https://secure.php.net/date */
419         'date_format' => __('F j, Y'),
420         /* translators: default time format, see https://secure.php.net/date */
421         'time_format' => __('g:i a'),
422         /* translators: links last updated date format, see https://secure.php.net/date */
423         'links_updated_date_format' => __('F j, Y g:i a'),
424         'comment_moderation' => 0,
425         'moderation_notify' => 1,
426         'permalink_structure' => '',
427         'rewrite_rules' => '',
428         'hack_file' => 0,
429         'blog_charset' => 'UTF-8',
430         'moderation_keys' => '',
431         'active_plugins' => array(),
432         'category_base' => '',
433         'ping_sites' => 'http://rpc.pingomatic.com/',
434         'comment_max_links' => 2,
435         'gmt_offset' => $gmt_offset,
436
437         // 1.5
438         'default_email_category' => 1,
439         'recently_edited' => '',
440         'template' => $template,
441         'stylesheet' => $stylesheet,
442         'comment_whitelist' => 1,
443         'blacklist_keys' => '',
444         'comment_registration' => 0,
445         'html_type' => 'text/html',
446
447         // 1.5.1
448         'use_trackback' => 0,
449
450         // 2.0
451         'default_role' => 'subscriber',
452         'db_version' => $wp_db_version,
453
454         // 2.0.1
455         'uploads_use_yearmonth_folders' => $uploads_use_yearmonth_folders,
456         'upload_path' => '',
457
458         // 2.1
459         'blog_public' => '1',
460         'default_link_category' => 2,
461         'show_on_front' => 'posts',
462
463         // 2.2
464         'tag_base' => '',
465
466         // 2.5
467         'show_avatars' => '1',
468         'avatar_rating' => 'G',
469         'upload_url_path' => '',
470         'thumbnail_size_w' => 150,
471         'thumbnail_size_h' => 150,
472         'thumbnail_crop' => 1,
473         'medium_size_w' => 300,
474         'medium_size_h' => 300,
475
476         // 2.6
477         'avatar_default' => 'mystery',
478
479         // 2.7
480         'large_size_w' => 1024,
481         'large_size_h' => 1024,
482         'image_default_link_type' => 'none',
483         'image_default_size' => '',
484         'image_default_align' => '',
485         'close_comments_for_old_posts' => 0,
486         'close_comments_days_old' => 14,
487         'thread_comments' => 1,
488         'thread_comments_depth' => 5,
489         'page_comments' => 0,
490         'comments_per_page' => 50,
491         'default_comments_page' => 'newest',
492         'comment_order' => 'asc',
493         'sticky_posts' => array(),
494         'widget_categories' => array(),
495         'widget_text' => array(),
496         'widget_rss' => array(),
497         'uninstall_plugins' => array(),
498
499         // 2.8
500         'timezone_string' => $timezone_string,
501
502         // 3.0
503         'page_for_posts' => 0,
504         'page_on_front' => 0,
505
506         // 3.1
507         'default_post_format' => 0,
508
509         // 3.5
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
521         // 3.3
522         if ( ! is_multisite() ) {
523                 $options['initial_db_version'] = ! empty( $wp_current_db_version ) && $wp_current_db_version < $wp_db_version
524                         ? $wp_current_db_version : $wp_db_version;
525         }
526
527         // 3.0 multisite
528         if ( is_multisite() ) {
529                 /* translators: site tagline */
530                 $options[ 'blogdescription' ] = sprintf(__('Just another %s site'), get_network()->site_name );
531                 $options[ 'permalink_structure' ] = '/%year%/%monthnum%/%day%/%postname%/';
532         }
533
534         // Set autoload to no for these options
535         $fat_options = array( 'moderation_keys', 'recently_edited', 'blacklist_keys', 'uninstall_plugins' );
536
537         $keys = "'" . implode( "', '", array_keys( $options ) ) . "'";
538         $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" );
539
540         $insert = '';
541         foreach ( $options as $option => $value ) {
542                 if ( in_array($option, $existing_options) )
543                         continue;
544                 if ( in_array($option, $fat_options) )
545                         $autoload = 'no';
546                 else
547                         $autoload = 'yes';
548
549                 if ( is_array($value) )
550                         $value = serialize($value);
551                 if ( !empty($insert) )
552                         $insert .= ', ';
553                 $insert .= $wpdb->prepare( "(%s, %s, %s)", $option, $value, $autoload );
554         }
555
556         if ( !empty($insert) )
557                 $wpdb->query("INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert);
558
559         // In case it is set, but blank, update "home".
560         if ( !__get_option('home') ) update_option('home', $guessurl);
561
562         // Delete unused options.
563         $unusedoptions = array(
564                 'blodotgsping_url', 'bodyterminator', 'emailtestonly', 'phoneemail_separator', 'smilies_directory',
565                 'subjectprefix', 'use_bbcode', 'use_blodotgsping', 'use_phoneemail', 'use_quicktags', 'use_weblogsping',
566                 'weblogs_cache_file', 'use_preview', 'use_htmltrans', 'smilies_directory', 'fileupload_allowedusers',
567                 'use_phoneemail', 'default_post_status', 'default_post_category', 'archive_mode', 'time_difference',
568                 'links_minadminlevel', 'links_use_adminlevels', 'links_rating_type', 'links_rating_char',
569                 'links_rating_ignore_zero', 'links_rating_single_image', 'links_rating_image0', 'links_rating_image1',
570                 'links_rating_image2', 'links_rating_image3', 'links_rating_image4', 'links_rating_image5',
571                 'links_rating_image6', 'links_rating_image7', 'links_rating_image8', 'links_rating_image9',
572                 'links_recently_updated_time', 'links_recently_updated_prepend', 'links_recently_updated_append',
573                 'weblogs_cacheminutes', 'comment_allowed_tags', 'search_engine_friendly_urls', 'default_geourl_lat',
574                 'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce',
575                 '_wp_http_referer', 'Update', 'action', 'rich_editing', 'autosave_interval', 'deactivated_plugins',
576                 'can_compress_scripts', 'page_uris', 'update_core', 'update_plugins', 'update_themes', 'doing_cron',
577                 'random_seed', 'rss_excerpt_length', 'secret', 'use_linksupdate', 'default_comment_status_page',
578                 'wporg_popular_tags', 'what_to_show', 'rss_language', 'language', 'enable_xmlrpc', 'enable_app',
579                 'embed_autourls', 'default_post_edit_rows', 'gzipcompression', 'advanced_edit'
580         );
581         foreach ( $unusedoptions as $option )
582                 delete_option($option);
583
584         // Delete obsolete magpie stuff.
585         $wpdb->query("DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'");
586
587         /*
588          * Deletes all expired transients. The multi-table delete syntax is used
589          * to delete the transient record from table a, and the corresponding
590          * transient_timeout record from table b.
591          */
592         $time = time();
593         $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
594                 WHERE a.option_name LIKE %s
595                 AND a.option_name NOT LIKE %s
596                 AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
597                 AND b.option_value < %d";
598         $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', $time ) );
599
600         if ( is_main_site() && is_main_network() ) {
601                 $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
602                         WHERE a.option_name LIKE %s
603                         AND a.option_name NOT LIKE %s
604                         AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
605                         AND b.option_value < %d";
606                 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', $time ) );
607         }
608 }
609
610 /**
611  * Execute WordPress role creation for the various WordPress versions.
612  *
613  * @since 2.0.0
614  */
615 function populate_roles() {
616         populate_roles_160();
617         populate_roles_210();
618         populate_roles_230();
619         populate_roles_250();
620         populate_roles_260();
621         populate_roles_270();
622         populate_roles_280();
623         populate_roles_300();
624 }
625
626 /**
627  * Create the roles for WordPress 2.0
628  *
629  * @since 2.0.0
630  */
631 function populate_roles_160() {
632         // Add roles
633
634         // Dummy gettext calls to get strings in the catalog.
635         /* translators: user role */
636         _x('Administrator', 'User role');
637         /* translators: user role */
638         _x('Editor', 'User role');
639         /* translators: user role */
640         _x('Author', 'User role');
641         /* translators: user role */
642         _x('Contributor', 'User role');
643         /* translators: user role */
644         _x('Subscriber', 'User role');
645
646         add_role('administrator', 'Administrator');
647         add_role('editor', 'Editor');
648         add_role('author', 'Author');
649         add_role('contributor', 'Contributor');
650         add_role('subscriber', 'Subscriber');
651
652         // Add caps for Administrator role
653         $role = get_role('administrator');
654         $role->add_cap('switch_themes');
655         $role->add_cap('edit_themes');
656         $role->add_cap('activate_plugins');
657         $role->add_cap('edit_plugins');
658         $role->add_cap('edit_users');
659         $role->add_cap('edit_files');
660         $role->add_cap('manage_options');
661         $role->add_cap('moderate_comments');
662         $role->add_cap('manage_categories');
663         $role->add_cap('manage_links');
664         $role->add_cap('upload_files');
665         $role->add_cap('import');
666         $role->add_cap('unfiltered_html');
667         $role->add_cap('edit_posts');
668         $role->add_cap('edit_others_posts');
669         $role->add_cap('edit_published_posts');
670         $role->add_cap('publish_posts');
671         $role->add_cap('edit_pages');
672         $role->add_cap('read');
673         $role->add_cap('level_10');
674         $role->add_cap('level_9');
675         $role->add_cap('level_8');
676         $role->add_cap('level_7');
677         $role->add_cap('level_6');
678         $role->add_cap('level_5');
679         $role->add_cap('level_4');
680         $role->add_cap('level_3');
681         $role->add_cap('level_2');
682         $role->add_cap('level_1');
683         $role->add_cap('level_0');
684
685         // Add caps for Editor role
686         $role = get_role('editor');
687         $role->add_cap('moderate_comments');
688         $role->add_cap('manage_categories');
689         $role->add_cap('manage_links');
690         $role->add_cap('upload_files');
691         $role->add_cap('unfiltered_html');
692         $role->add_cap('edit_posts');
693         $role->add_cap('edit_others_posts');
694         $role->add_cap('edit_published_posts');
695         $role->add_cap('publish_posts');
696         $role->add_cap('edit_pages');
697         $role->add_cap('read');
698         $role->add_cap('level_7');
699         $role->add_cap('level_6');
700         $role->add_cap('level_5');
701         $role->add_cap('level_4');
702         $role->add_cap('level_3');
703         $role->add_cap('level_2');
704         $role->add_cap('level_1');
705         $role->add_cap('level_0');
706
707         // Add caps for Author role
708         $role = get_role('author');
709         $role->add_cap('upload_files');
710         $role->add_cap('edit_posts');
711         $role->add_cap('edit_published_posts');
712         $role->add_cap('publish_posts');
713         $role->add_cap('read');
714         $role->add_cap('level_2');
715         $role->add_cap('level_1');
716         $role->add_cap('level_0');
717
718         // Add caps for Contributor role
719         $role = get_role('contributor');
720         $role->add_cap('edit_posts');
721         $role->add_cap('read');
722         $role->add_cap('level_1');
723         $role->add_cap('level_0');
724
725         // Add caps for Subscriber role
726         $role = get_role('subscriber');
727         $role->add_cap('read');
728         $role->add_cap('level_0');
729 }
730
731 /**
732  * Create and modify WordPress roles for WordPress 2.1.
733  *
734  * @since 2.1.0
735  */
736 function populate_roles_210() {
737         $roles = array('administrator', 'editor');
738         foreach ($roles as $role) {
739                 $role = get_role($role);
740                 if ( empty($role) )
741                         continue;
742
743                 $role->add_cap('edit_others_pages');
744                 $role->add_cap('edit_published_pages');
745                 $role->add_cap('publish_pages');
746                 $role->add_cap('delete_pages');
747                 $role->add_cap('delete_others_pages');
748                 $role->add_cap('delete_published_pages');
749                 $role->add_cap('delete_posts');
750                 $role->add_cap('delete_others_posts');
751                 $role->add_cap('delete_published_posts');
752                 $role->add_cap('delete_private_posts');
753                 $role->add_cap('edit_private_posts');
754                 $role->add_cap('read_private_posts');
755                 $role->add_cap('delete_private_pages');
756                 $role->add_cap('edit_private_pages');
757                 $role->add_cap('read_private_pages');
758         }
759
760         $role = get_role('administrator');
761         if ( ! empty($role) ) {
762                 $role->add_cap('delete_users');
763                 $role->add_cap('create_users');
764         }
765
766         $role = get_role('author');
767         if ( ! empty($role) ) {
768                 $role->add_cap('delete_posts');
769                 $role->add_cap('delete_published_posts');
770         }
771
772         $role = get_role('contributor');
773         if ( ! empty($role) ) {
774                 $role->add_cap('delete_posts');
775         }
776 }
777
778 /**
779  * Create and modify WordPress roles for WordPress 2.3.
780  *
781  * @since 2.3.0
782  */
783 function populate_roles_230() {
784         $role = get_role( 'administrator' );
785
786         if ( !empty( $role ) ) {
787                 $role->add_cap( 'unfiltered_upload' );
788         }
789 }
790
791 /**
792  * Create and modify WordPress roles for WordPress 2.5.
793  *
794  * @since 2.5.0
795  */
796 function populate_roles_250() {
797         $role = get_role( 'administrator' );
798
799         if ( !empty( $role ) ) {
800                 $role->add_cap( 'edit_dashboard' );
801         }
802 }
803
804 /**
805  * Create and modify WordPress roles for WordPress 2.6.
806  *
807  * @since 2.6.0
808  */
809 function populate_roles_260() {
810         $role = get_role( 'administrator' );
811
812         if ( !empty( $role ) ) {
813                 $role->add_cap( 'update_plugins' );
814                 $role->add_cap( 'delete_plugins' );
815         }
816 }
817
818 /**
819  * Create and modify WordPress roles for WordPress 2.7.
820  *
821  * @since 2.7.0
822  */
823 function populate_roles_270() {
824         $role = get_role( 'administrator' );
825
826         if ( !empty( $role ) ) {
827                 $role->add_cap( 'install_plugins' );
828                 $role->add_cap( 'update_themes' );
829         }
830 }
831
832 /**
833  * Create and modify WordPress roles for WordPress 2.8.
834  *
835  * @since 2.8.0
836  */
837 function populate_roles_280() {
838         $role = get_role( 'administrator' );
839
840         if ( !empty( $role ) ) {
841                 $role->add_cap( 'install_themes' );
842         }
843 }
844
845 /**
846  * Create and modify WordPress roles for WordPress 3.0.
847  *
848  * @since 3.0.0
849  */
850 function populate_roles_300() {
851         $role = get_role( 'administrator' );
852
853         if ( !empty( $role ) ) {
854                 $role->add_cap( 'update_core' );
855                 $role->add_cap( 'list_users' );
856                 $role->add_cap( 'remove_users' );
857                 $role->add_cap( 'promote_users' );
858                 $role->add_cap( 'edit_theme_options' );
859                 $role->add_cap( 'delete_themes' );
860                 $role->add_cap( 'export' );
861         }
862 }
863
864 /**
865  * Install Network.
866  *
867  * @since 3.0.0
868  *
869  */
870 if ( !function_exists( 'install_network' ) ) :
871 function install_network() {
872         if ( ! defined( 'WP_INSTALLING_NETWORK' ) )
873                 define( 'WP_INSTALLING_NETWORK', true );
874
875         dbDelta( wp_get_db_schema( 'global' ) );
876 }
877 endif;
878
879 /**
880  * Populate network settings.
881  *
882  * @since 3.0.0
883  *
884  * @global wpdb       $wpdb
885  * @global object     $current_site
886  * @global int        $wp_db_version
887  * @global WP_Rewrite $wp_rewrite
888  *
889  * @param int    $network_id        ID of network to populate.
890  * @param string $domain            The domain name for the network (eg. "example.com").
891  * @param string $email             Email address for the network administrator.
892  * @param string $site_name         The name of the network.
893  * @param string $path              Optional. The path to append to the network's domain name. Default '/'.
894  * @param bool   $subdomain_install Optional. Whether the network is a subdomain install or a subdirectory install.
895  *                                  Default false, meaning the network is a subdirectory install.
896  * @return bool|WP_Error True on success, or WP_Error on warning (with the install otherwise successful,
897  *                       so the error code must be checked) or failure.
898  */
899 function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
900         global $wpdb, $current_site, $wp_db_version, $wp_rewrite;
901
902         $errors = new WP_Error();
903         if ( '' == $domain )
904                 $errors->add( 'empty_domain', __( 'You must provide a domain name.' ) );
905         if ( '' == $site_name )
906                 $errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) );
907
908         // Check for network collision.
909         if ( $network_id == $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id ) ) )
910                 $errors->add( 'siteid_exists', __( 'The network already exists.' ) );
911
912         if ( ! is_email( $email ) )
913                 $errors->add( 'invalid_email', __( 'You must provide a valid email address.' ) );
914
915         if ( $errors->get_error_code() )
916                 return $errors;
917
918         // If a user with the provided email does not exist, default to the current user as the new network admin.
919         $site_user = get_user_by( 'email', $email );
920         if ( false === $site_user ) {
921                 $site_user = wp_get_current_user();
922         }
923
924         // Set up site tables.
925         $template = get_option( 'template' );
926         $stylesheet = get_option( 'stylesheet' );
927         $allowed_themes = array( $stylesheet => true );
928
929         if ( $template != $stylesheet ) {
930                 $allowed_themes[ $template ] = true;
931         }
932
933         if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) {
934                 $allowed_themes[ WP_DEFAULT_THEME ] = true;
935         }
936
937         // If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme.
938         if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
939                 if ( $core_default = WP_Theme::get_core_default_theme() ) {
940                         $allowed_themes[ $core_default->get_stylesheet() ] = true;
941                 }
942         }
943
944         if ( 1 == $network_id ) {
945                 $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) );
946                 $network_id = $wpdb->insert_id;
947         } else {
948                 $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path, 'id' => $network_id ) );
949         }
950
951         wp_cache_delete( 'networks_have_paths', 'site-options' );
952
953         if ( !is_multisite() ) {
954                 $site_admins = array( $site_user->user_login );
955                 $users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) );
956                 if ( $users ) {
957                         foreach ( $users as $user ) {
958                                 if ( is_super_admin( $user->ID ) && !in_array( $user->user_login, $site_admins ) )
959                                         $site_admins[] = $user->user_login;
960                         }
961                 }
962         } else {
963                 $site_admins = get_site_option( 'site_admins' );
964         }
965
966         /* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
967         $welcome_email = __( 'Howdy USERNAME,
968
969 Your new SITE_NAME site has been successfully set up at:
970 BLOG_URL
971
972 You can log in to the administrator account with the following information:
973
974 Username: USERNAME
975 Password: PASSWORD
976 Log in here: BLOG_URLwp-login.php
977
978 We hope you enjoy your new site. Thanks!
979
980 --The Team @ SITE_NAME' );
981
982         $misc_exts = array(
983                 // Images.
984                 'jpg', 'jpeg', 'png', 'gif',
985                 // Video.
986                 'mov', 'avi', 'mpg', '3gp', '3g2',
987                 // "audio".
988                 'midi', 'mid',
989                 // Miscellaneous.
990                 'pdf', 'doc', 'ppt', 'odt', 'pptx', 'docx', 'pps', 'ppsx', 'xls', 'xlsx', 'key',
991         );
992         $audio_exts = wp_get_audio_extensions();
993         $video_exts = wp_get_video_extensions();
994         $upload_filetypes = array_unique( array_merge( $misc_exts, $audio_exts, $video_exts ) );
995
996         $sitemeta = array(
997                 'site_name' => $site_name,
998                 'admin_email' => $email,
999                 'admin_user_id' => $site_user->ID,
1000                 'registration' => 'none',
1001                 'upload_filetypes' => implode( ' ', $upload_filetypes ),
1002                 'blog_upload_space' => 100,
1003                 'fileupload_maxk' => 1500,
1004                 'site_admins' => $site_admins,
1005                 'allowedthemes' => $allowed_themes,
1006                 'illegal_names' => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ),
1007                 'wpmu_upgrade_site' => $wp_db_version,
1008                 'welcome_email' => $welcome_email,
1009                 /* translators: %s: site link */
1010                 'first_post' => __( 'Welcome to %s. This is your first post. Edit or delete it, then start blogging!' ),
1011                 // @todo - network admins should have a method of editing the network siteurl (used for cookie hash)
1012                 'siteurl' => get_option( 'siteurl' ) . '/',
1013                 'add_new_users' => '0',
1014                 'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
1015                 'subdomain_install' => intval( $subdomain_install ),
1016                 'global_terms_enabled' => global_terms_enabled() ? '1' : '0',
1017                 'ms_files_rewriting' => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
1018                 'initial_db_version' => get_option( 'initial_db_version' ),
1019                 'active_sitewide_plugins' => array(),
1020                 'WPLANG' => get_locale(),
1021         );
1022         if ( ! $subdomain_install )
1023                 $sitemeta['illegal_names'][] = 'blog';
1024
1025         /**
1026          * Filters meta for a network on creation.
1027          *
1028          * @since 3.7.0
1029          *
1030          * @param array $sitemeta   Associative array of network meta keys and values to be inserted.
1031          * @param int   $network_id ID of network to populate.
1032          */
1033         $sitemeta = apply_filters( 'populate_network_meta', $sitemeta, $network_id );
1034
1035         $insert = '';
1036         foreach ( $sitemeta as $meta_key => $meta_value ) {
1037                 if ( is_array( $meta_value ) )
1038                         $meta_value = serialize( $meta_value );
1039                 if ( !empty( $insert ) )
1040                         $insert .= ', ';
1041                 $insert .= $wpdb->prepare( "( %d, %s, %s)", $network_id, $meta_key, $meta_value );
1042         }
1043         $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert );
1044
1045         /*
1046          * When upgrading from single to multisite, assume the current site will
1047          * become the main site of the network. When using populate_network()
1048          * to create another network in an existing multisite environment, skip
1049          * these steps since the main site of the new network has not yet been
1050          * created.
1051          */
1052         if ( ! is_multisite() ) {
1053                 $current_site = new stdClass;
1054                 $current_site->domain = $domain;
1055                 $current_site->path = $path;
1056                 $current_site->site_name = ucfirst( $domain );
1057                 $wpdb->insert( $wpdb->blogs, array( 'site_id' => $network_id, 'blog_id' => 1, 'domain' => $domain, 'path' => $path, 'registered' => current_time( 'mysql' ) ) );
1058                 $current_site->blog_id = $blog_id = $wpdb->insert_id;
1059                 update_user_meta( $site_user->ID, 'source_domain', $domain );
1060                 update_user_meta( $site_user->ID, 'primary_blog', $blog_id );
1061
1062                 if ( $subdomain_install )
1063                         $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
1064                 else
1065                         $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' );
1066
1067                 flush_rewrite_rules();
1068
1069                 if ( ! $subdomain_install )
1070                         return true;
1071
1072                 $vhost_ok = false;
1073                 $errstr = '';
1074                 $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
1075                 $page = wp_remote_get( 'http://' . $hostname, array( 'timeout' => 5, 'httpversion' => '1.1' ) );
1076                 if ( is_wp_error( $page ) )
1077                         $errstr = $page->get_error_message();
1078                 elseif ( 200 == wp_remote_retrieve_response_code( $page ) )
1079                                 $vhost_ok = true;
1080
1081                 if ( ! $vhost_ok ) {
1082                         $msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
1083
1084                         $msg .= '<p>' . sprintf(
1085                                 /* translators: %s: host name */
1086                                 __( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
1087                                 '<code>' . $hostname . '</code>'
1088                         );
1089                         if ( ! empty ( $errstr ) ) {
1090                                 /* translators: %s: error message */
1091                                 $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
1092                         }
1093                         $msg .= '</p>';
1094
1095                         $msg .= '<p>' . sprintf(
1096                                 /* translators: %s: asterisk symbol (*) */
1097                                 __( '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.' ),
1098                                 '<code>*</code>'
1099                         ) . '</p>';
1100
1101                         $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>';
1102
1103                         return new WP_Error( 'no_wildcard_dns', $msg );
1104                 }
1105         }
1106
1107         return true;
1108 }