WordPress.org

Make WordPress Core

Ticket #25498: schema.php

File schema.php, 33.0 KB (added by johnafish, 8 years ago)

Inline Hook Docs For: wp-admin/includes/schema.php

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