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