3 * WordPress Administration Scheme API
5 * Here we keep the DB structure and option values.
8 * @subpackage Administration
11 // Declare these as global in case schema.php is included from a function.
12 global $wpdb, $wp_queries, $charset_collate;
15 * The database character collate.
18 * @name $charset_collate
20 $charset_collate = '';
22 if ( ! empty( $wpdb->charset ) )
23 $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
24 if ( ! empty( $wpdb->collate ) )
25 $charset_collate .= " COLLATE $wpdb->collate";
28 * Retrieve the SQL for creating database tables.
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.
36 function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
39 $charset_collate = '';
41 if ( ! empty($wpdb->charset) )
42 $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
43 if ( ! empty($wpdb->collate) )
44 $charset_collate .= " COLLATE $wpdb->collate";
46 if ( $blog_id && $blog_id != $wpdb->blogid )
47 $old_blog_id = $wpdb->set_blog_id( $blog_id );
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 );
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),
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)
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)
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,
85 PRIMARY KEY (meta_id),
86 KEY comment_id (comment_id),
87 KEY meta_key (meta_key)
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)
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)
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)
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,
143 PRIMARY KEY (meta_id),
144 KEY post_id (post_id),
145 KEY meta_key (meta_key)
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',
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";
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 '',
191 KEY user_login_key (user_login),
192 KEY user_nicename (user_nicename)
193 ) $charset_collate;\n";
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',
210 KEY user_login_key (user_login),
211 KEY user_nicename (user_nicename)
212 ) $charset_collate;\n";
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,
220 PRIMARY KEY (umeta_id),
221 KEY user_id (user_id),
222 KEY meta_key (meta_key)
223 ) $charset_collate;\n";
227 $global_tables = $users_multi_table . $usermeta_table;
229 $global_tables = $users_single_table . $usermeta_table;
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)
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)
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',
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 '',
270 KEY domain (domain,path)
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,
277 PRIMARY KEY (meta_id),
278 KEY meta_key (meta_key),
279 KEY site_id (site_id)
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 '',
292 KEY activation_key (activation_key),
294 ) $charset_collate;";
298 $queries = $blog_tables;
301 $queries = $global_tables;
303 $queries .= $ms_global_tables;
306 $queries = $ms_global_tables;
310 $queries = $global_tables . $blog_tables;
312 $queries .= $ms_global_tables;
316 if ( isset( $old_blog_id ) )
317 $wpdb->set_blog_id( $old_blog_id );
322 // Populate for back compat.
323 $wp_queries = wp_get_db_schema( 'all' );
326 * Create WordPress options and set the default values.
330 * @uses $wp_db_version
332 function populate_options() {
333 global $wpdb, $wp_db_version, $current_site, $wp_current_db_version;
335 $guessurl = wp_guess_url();
337 do_action('populate_options');
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;
343 $uploads_use_yearmonth_folders = 1;
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'];
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,
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,
393 'blog_charset' => 'UTF-8',
394 'moderation_keys' => '',
395 'active_plugins' => array(),
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,
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',
415 'use_trackback' => 0,
418 'default_role' => 'subscriber',
419 'db_version' => $wp_db_version,
422 'uploads_use_yearmonth_folders' => $uploads_use_yearmonth_folders,
426 'blog_public' => '1',
427 'default_link_category' => 2,
428 'show_on_front' => 'posts',
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,
444 'avatar_default' => 'mystery',
446 'enable_xmlrpc' => 0,
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(),
468 'timezone_string' => '',
471 'embed_autourls' => 1,
472 'embed_size_w' => '',
473 'embed_size_h' => 600,
476 'page_for_posts' => 0,
477 'page_on_front' => 0,
480 'default_post_format' => 0,
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;
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%/';
496 // Set autoload to no for these options
497 $fat_options = array( 'moderation_keys', 'recently_edited', 'blacklist_keys' );
499 $existing_options = $wpdb->get_col("SELECT option_name FROM $wpdb->options");
502 foreach ( $options as $option => $value ) {
503 if ( in_array($option, $existing_options) )
505 if ( in_array($option, $fat_options) )
510 $option = $wpdb->escape($option);
511 if ( is_array($value) )
512 $value = serialize($value);
513 $value = $wpdb->escape($value);
514 if ( !empty($insert) )
516 $insert .= "('$option', '$value', '$autoload')";
519 if ( !empty($insert) )
520 $wpdb->query("INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert);
522 // in case it is set, but blank, update "home"
523 if ( !__get_option('home') ) update_option('home', $guessurl);
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);
530 // delete obsolete magpie stuff
531 $wpdb->query("DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'");
535 * Execute WordPress role creation for the various WordPress versions.
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();
551 * Create the roles for WordPress 2.0
555 function populate_roles_160() {
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');
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');
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');
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');
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');
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');
649 // Add caps for Subscriber role
650 $role =& get_role('subscriber');
651 $role->add_cap('read');
652 $role->add_cap('level_0');
656 * Create and modify WordPress roles for WordPress 2.1.
660 function populate_roles_210() {
661 $roles = array('administrator', 'editor');
662 foreach ($roles as $role) {
663 $role =& get_role($role);
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');
684 $role =& get_role('administrator');
685 if ( ! empty($role) ) {
686 $role->add_cap('delete_users');
687 $role->add_cap('create_users');
690 $role =& get_role('author');
691 if ( ! empty($role) ) {
692 $role->add_cap('delete_posts');
693 $role->add_cap('delete_published_posts');
696 $role =& get_role('contributor');
697 if ( ! empty($role) ) {
698 $role->add_cap('delete_posts');
703 * Create and modify WordPress roles for WordPress 2.3.
707 function populate_roles_230() {
708 $role =& get_role( 'administrator' );
710 if ( !empty( $role ) ) {
711 $role->add_cap( 'unfiltered_upload' );
716 * Create and modify WordPress roles for WordPress 2.5.
720 function populate_roles_250() {
721 $role =& get_role( 'administrator' );
723 if ( !empty( $role ) ) {
724 $role->add_cap( 'edit_dashboard' );
729 * Create and modify WordPress roles for WordPress 2.6.
733 function populate_roles_260() {
734 $role =& get_role( 'administrator' );
736 if ( !empty( $role ) ) {
737 $role->add_cap( 'update_plugins' );
738 $role->add_cap( 'delete_plugins' );
743 * Create and modify WordPress roles for WordPress 2.7.
747 function populate_roles_270() {
748 $role =& get_role( 'administrator' );
750 if ( !empty( $role ) ) {
751 $role->add_cap( 'install_plugins' );
752 $role->add_cap( 'update_themes' );
757 * Create and modify WordPress roles for WordPress 2.8.
761 function populate_roles_280() {
762 $role =& get_role( 'administrator' );
764 if ( !empty( $role ) ) {
765 $role->add_cap( 'install_themes' );
770 * Create and modify WordPress roles for WordPress 3.0.
774 function populate_roles_300() {
775 $role =& get_role( 'administrator' );
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' );
795 if ( !function_exists( 'install_network' ) ) :
796 function install_network() {
797 if ( ! defined( 'WP_INSTALLING_NETWORK' ) )
798 define( 'WP_INSTALLING_NETWORK', true );
800 dbDelta( wp_get_db_schema( 'global' ) );
805 * populate network settings
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.
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;
816 $errors = new WP_Error();
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.' ) );
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.' ) );
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.' ) );
830 if ( $errors->get_error_code() )
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;
842 if ( 1 == $network_id ) {
843 $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) );
844 $network_id = $wpdb->insert_id;
846 $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path, 'id' => $network_id ) );
849 if ( !is_multisite() ) {
850 $site_admins = array( $site_user->user_login );
851 $users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) );
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;
859 $site_admins = get_site_option( 'site_admins' );
862 $welcome_email = __( 'Dear User,
864 Your new SITE_NAME site has been successfully set up at:
867 You can log in to the administrator account with the following information:
870 Log in here: BLOG_URLwp-login.php
872 We hope you enjoy your new site. Thanks!
874 --The Team @ SITE_NAME' );
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(),
899 if ( ! $subdomain_install )
900 $sitemeta['illegal_names'][] = 'blog';
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 ) )
910 $insert .= "( $network_id, '$meta_key', '$meta_value')";
912 $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert );
914 $current_site->domain = $domain;
915 $current_site->path = $path;
916 $current_site->site_name = ucfirst( $domain );
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 );
927 update_option( 'fileupload_url', get_option( 'siteurl' ) . '/' . $upload_path );
930 if ( $subdomain_install )
931 update_option( 'permalink_structure', '/%year%/%monthnum%/%day%/%postname%/');
933 update_option( 'permalink_structure', '/blog/%year%/%monthnum%/%day%/%postname%/');
935 $wp_rewrite->flush_rules();
937 if ( $subdomain_install ) {
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 ) )
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>' );
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 );