Make WordPress Core

source: branches/4.8/src/wp-admin/includes/schema.php @ 57407

Last change on this file since 57407 was 57407, checked in by jorbin, 6 months ago

Grouped Backports to the 4.8 branch.

  • Install: When populating options, maybe_serialize instead of always serialize.
  • Uploads: Check for and verify ZIP archives.

Merges [57388] and [57389] to the 4.8 branch.

Props costdev, peterwilsoncc, azaozz, tykoted, johnbillion, desrosj, afragen, jorbin, xknown.

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