Diff: STRATO-apps/wordpress_03/app/wp-admin/includes/schema.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
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 WordPress database abstraction object.
15 + * @global array $wp_queries
16 + * @global string $charset_collate
17 + */
18 + global $wpdb, $wp_queries, $charset_collate;
19 +
20 + /**
21 + * The database character collate.
22 + */
23 + $charset_collate = $wpdb->get_charset_collate();
24 +
25 + /**
26 + * Retrieve the SQL for creating database tables.
27 + *
28 + * @since 3.3.0
29 + *
30 + * @global wpdb $wpdb WordPress database abstraction object.
31 + *
32 + * @param string $scope Optional. The tables for which to retrieve SQL. Can be all, global, ms_global, or blog tables. Defaults to all.
33 + * @param int $blog_id Optional. The site ID for which to retrieve SQL. Default is the current site ID.
34 + * @return string The SQL needed to create the requested tables.
35 + */
36 + function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
37 + global $wpdb;
38 +
39 + $charset_collate = $wpdb->get_charset_collate();
40 +
41 + if ( $blog_id && (int) $blog_id !== $wpdb->blogid ) {
42 + $old_blog_id = $wpdb->set_blog_id( $blog_id );
43 + }
44 +
45 + // Engage multisite if in the middle of turning it on from network.php.
46 + $is_multisite = is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK );
47 +
48 + /*
49 + * Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
50 + * As of 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
51 + * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
52 + */
53 + $max_index_length = 191;
54 +
55 + // Blog-specific tables.
56 + $blog_tables = "CREATE TABLE $wpdb->termmeta (
57 + meta_id bigint(20) unsigned NOT NULL auto_increment,
58 + term_id bigint(20) unsigned NOT NULL default '0',
59 + meta_key varchar(255) default NULL,
60 + meta_value longtext,
61 + PRIMARY KEY (meta_id),
62 + KEY term_id (term_id),
63 + KEY meta_key (meta_key($max_index_length))
64 + ) $charset_collate;
65 + CREATE TABLE $wpdb->terms (
66 + term_id bigint(20) unsigned NOT NULL auto_increment,
67 + name varchar(200) NOT NULL default '',
68 + slug varchar(200) NOT NULL default '',
69 + term_group bigint(10) NOT NULL default 0,
70 + PRIMARY KEY (term_id),
71 + KEY slug (slug($max_index_length)),
72 + KEY name (name($max_index_length))
73 + ) $charset_collate;
74 + CREATE TABLE $wpdb->term_taxonomy (
75 + term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment,
76 + term_id bigint(20) unsigned NOT NULL default 0,
77 + taxonomy varchar(32) NOT NULL default '',
78 + description longtext NOT NULL,
79 + parent bigint(20) unsigned NOT NULL default 0,
80 + count bigint(20) NOT NULL default 0,
81 + PRIMARY KEY (term_taxonomy_id),
82 + UNIQUE KEY term_id_taxonomy (term_id,taxonomy),
83 + KEY taxonomy (taxonomy)
84 + ) $charset_collate;
85 + CREATE TABLE $wpdb->term_relationships (
86 + object_id bigint(20) unsigned NOT NULL default 0,
87 + term_taxonomy_id bigint(20) unsigned NOT NULL default 0,
88 + term_order int(11) NOT NULL default 0,
89 + PRIMARY KEY (object_id,term_taxonomy_id),
90 + KEY term_taxonomy_id (term_taxonomy_id)
91 + ) $charset_collate;
92 + CREATE TABLE $wpdb->commentmeta (
93 + meta_id bigint(20) unsigned NOT NULL auto_increment,
94 + comment_id bigint(20) unsigned NOT NULL default '0',
95 + meta_key varchar(255) default NULL,
96 + meta_value longtext,
97 + PRIMARY KEY (meta_id),
98 + KEY comment_id (comment_id),
99 + KEY meta_key (meta_key($max_index_length))
100 + ) $charset_collate;
101 + CREATE TABLE $wpdb->comments (
102 + comment_ID bigint(20) unsigned NOT NULL auto_increment,
103 + comment_post_ID bigint(20) unsigned NOT NULL default '0',
104 + comment_author tinytext NOT NULL,
105 + comment_author_email varchar(100) NOT NULL default '',
106 + comment_author_url varchar(200) NOT NULL default '',
107 + comment_author_IP varchar(100) NOT NULL default '',
108 + comment_date datetime NOT NULL default '0000-00-00 00:00:00',
109 + comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
110 + comment_content text NOT NULL,
111 + comment_karma int(11) NOT NULL default '0',
112 + comment_approved varchar(20) NOT NULL default '1',
113 + comment_agent varchar(255) NOT NULL default '',
114 + comment_type varchar(20) NOT NULL default 'comment',
115 + comment_parent bigint(20) unsigned NOT NULL default '0',
116 + user_id bigint(20) unsigned NOT NULL default '0',
117 + PRIMARY KEY (comment_ID),
118 + KEY comment_post_ID (comment_post_ID),
119 + KEY comment_approved_date_gmt (comment_approved,comment_date_gmt),
120 + KEY comment_date_gmt (comment_date_gmt),
121 + KEY comment_parent (comment_parent),
122 + KEY comment_author_email (comment_author_email(10))
123 + ) $charset_collate;
124 + CREATE TABLE $wpdb->links (
125 + link_id bigint(20) unsigned NOT NULL auto_increment,
126 + link_url varchar(255) NOT NULL default '',
127 + link_name varchar(255) NOT NULL default '',
128 + link_image varchar(255) NOT NULL default '',
129 + link_target varchar(25) NOT NULL default '',
130 + link_description varchar(255) NOT NULL default '',
131 + link_visible varchar(20) NOT NULL default 'Y',
132 + link_owner bigint(20) unsigned NOT NULL default '1',
133 + link_rating int(11) NOT NULL default '0',
134 + link_updated datetime NOT NULL default '0000-00-00 00:00:00',
135 + link_rel varchar(255) NOT NULL default '',
136 + link_notes mediumtext NOT NULL,
137 + link_rss varchar(255) NOT NULL default '',
138 + PRIMARY KEY (link_id),
139 + KEY link_visible (link_visible)
140 + ) $charset_collate;
141 + CREATE TABLE $wpdb->options (
142 + option_id bigint(20) unsigned NOT NULL auto_increment,
143 + option_name varchar(191) NOT NULL default '',
144 + option_value longtext NOT NULL,
145 + autoload varchar(20) NOT NULL default 'yes',
146 + PRIMARY KEY (option_id),
147 + UNIQUE KEY option_name (option_name),
148 + KEY autoload (autoload)
149 + ) $charset_collate;
150 + CREATE TABLE $wpdb->postmeta (
151 + meta_id bigint(20) unsigned NOT NULL auto_increment,
152 + post_id bigint(20) unsigned NOT NULL default '0',
153 + meta_key varchar(255) default NULL,
154 + meta_value longtext,
155 + PRIMARY KEY (meta_id),
156 + KEY post_id (post_id),
157 + KEY meta_key (meta_key($max_index_length))
158 + ) $charset_collate;
159 + CREATE TABLE $wpdb->posts (
160 + ID bigint(20) unsigned NOT NULL auto_increment,
161 + post_author bigint(20) unsigned NOT NULL default '0',
162 + post_date datetime NOT NULL default '0000-00-00 00:00:00',
163 + post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
164 + post_content longtext NOT NULL,
165 + post_title text NOT NULL,
166 + post_excerpt text NOT NULL,
167 + post_status varchar(20) NOT NULL default 'publish',
168 + comment_status varchar(20) NOT NULL default 'open',
169 + ping_status varchar(20) NOT NULL default 'open',
170 + post_password varchar(255) NOT NULL default '',
171 + post_name varchar(200) NOT NULL default '',
172 + to_ping text NOT NULL,
173 + pinged text NOT NULL,
174 + post_modified datetime NOT NULL default '0000-00-00 00:00:00',
175 + post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
176 + post_content_filtered longtext NOT NULL,
177 + post_parent bigint(20) unsigned NOT NULL default '0',
178 + guid varchar(255) NOT NULL default '',
179 + menu_order int(11) NOT NULL default '0',
180 + post_type varchar(20) NOT NULL default 'post',
181 + post_mime_type varchar(100) NOT NULL default '',
182 + comment_count bigint(20) NOT NULL default '0',
183 + PRIMARY KEY (ID),
184 + KEY post_name (post_name($max_index_length)),
185 + KEY type_status_date (post_type,post_status,post_date,ID),
186 + KEY post_parent (post_parent),
187 + KEY post_author (post_author),
188 + KEY type_status_author (post_type,post_status,post_author)
189 + ) $charset_collate;\n";
190 +
191 + // Single site users table. The multisite flavor of the users table is handled below.
192 + $users_single_table = "CREATE TABLE $wpdb->users (
193 + ID bigint(20) unsigned NOT NULL auto_increment,
194 + user_login varchar(60) NOT NULL default '',
195 + user_pass varchar(255) NOT NULL default '',
196 + user_nicename varchar(50) NOT NULL default '',
197 + user_email varchar(100) NOT NULL default '',
198 + user_url varchar(100) NOT NULL default '',
199 + user_registered datetime NOT NULL default '0000-00-00 00:00:00',
200 + user_activation_key varchar(255) NOT NULL default '',
201 + user_status int(11) NOT NULL default '0',
202 + display_name varchar(250) NOT NULL default '',
203 + PRIMARY KEY (ID),
204 + KEY user_login_key (user_login),
205 + KEY user_nicename (user_nicename),
206 + KEY user_email (user_email)
207 + ) $charset_collate;\n";
208 +
209 + // Multisite users table.
210 + $users_multi_table = "CREATE TABLE $wpdb->users (
211 + ID bigint(20) unsigned NOT NULL auto_increment,
212 + user_login varchar(60) NOT NULL default '',
213 + user_pass varchar(255) NOT NULL default '',
214 + user_nicename varchar(50) NOT NULL default '',
215 + user_email varchar(100) NOT NULL default '',
216 + user_url varchar(100) NOT NULL default '',
217 + user_registered datetime NOT NULL default '0000-00-00 00:00:00',
218 + user_activation_key varchar(255) NOT NULL default '',
219 + user_status int(11) NOT NULL default '0',
220 + display_name varchar(250) NOT NULL default '',
221 + spam tinyint(2) NOT NULL default '0',
222 + deleted tinyint(2) NOT NULL default '0',
223 + PRIMARY KEY (ID),
224 + KEY user_login_key (user_login),
225 + KEY user_nicename (user_nicename),
226 + KEY user_email (user_email)
227 + ) $charset_collate;\n";
228 +
229 + // Usermeta.
230 + $usermeta_table = "CREATE TABLE $wpdb->usermeta (
231 + umeta_id bigint(20) unsigned NOT NULL auto_increment,
232 + user_id bigint(20) unsigned NOT NULL default '0',
233 + meta_key varchar(255) default NULL,
234 + meta_value longtext,
235 + PRIMARY KEY (umeta_id),
236 + KEY user_id (user_id),
237 + KEY meta_key (meta_key($max_index_length))
238 + ) $charset_collate;\n";
239 +
240 + // Global tables.
241 + if ( $is_multisite ) {
242 + $global_tables = $users_multi_table . $usermeta_table;
243 + } else {
244 + $global_tables = $users_single_table . $usermeta_table;
245 + }
246 +
247 + // Multisite global tables.
248 + $ms_global_tables = "CREATE TABLE $wpdb->blogs (
249 + blog_id bigint(20) unsigned NOT NULL auto_increment,
250 + site_id bigint(20) unsigned NOT NULL default '0',
251 + domain varchar(200) NOT NULL default '',
252 + path varchar(100) NOT NULL default '',
253 + registered datetime NOT NULL default '0000-00-00 00:00:00',
254 + last_updated datetime NOT NULL default '0000-00-00 00:00:00',
255 + public tinyint(2) NOT NULL default '1',
256 + archived tinyint(2) NOT NULL default '0',
257 + mature tinyint(2) NOT NULL default '0',
258 + spam tinyint(2) NOT NULL default '0',
259 + deleted tinyint(2) NOT NULL default '0',
260 + lang_id int(11) NOT NULL default '0',
261 + PRIMARY KEY (blog_id),
262 + KEY domain (domain(50),path(5)),
263 + KEY lang_id (lang_id)
264 + ) $charset_collate;
265 + CREATE TABLE $wpdb->blogmeta (
266 + meta_id bigint(20) unsigned NOT NULL auto_increment,
267 + blog_id bigint(20) unsigned NOT NULL default '0',
268 + meta_key varchar(255) default NULL,
269 + meta_value longtext,
270 + PRIMARY KEY (meta_id),
271 + KEY meta_key (meta_key($max_index_length)),
272 + KEY blog_id (blog_id)
273 + ) $charset_collate;
274 + CREATE TABLE $wpdb->registration_log (
275 + ID bigint(20) unsigned NOT NULL auto_increment,
276 + email varchar(255) NOT NULL default '',
277 + IP varchar(30) NOT NULL default '',
278 + blog_id bigint(20) unsigned NOT NULL default '0',
279 + date_registered datetime NOT NULL default '0000-00-00 00:00:00',
280 + PRIMARY KEY (ID),
281 + KEY IP (IP)
282 + ) $charset_collate;
283 + CREATE TABLE $wpdb->site (
284 + id bigint(20) unsigned NOT NULL auto_increment,
285 + domain varchar(200) NOT NULL default '',
286 + path varchar(100) NOT NULL default '',
287 + PRIMARY KEY (id),
288 + KEY domain (domain(140),path(51))
289 + ) $charset_collate;
290 + CREATE TABLE $wpdb->sitemeta (
291 + meta_id bigint(20) unsigned NOT NULL auto_increment,
292 + site_id bigint(20) unsigned NOT NULL default '0',
293 + meta_key varchar(255) default NULL,
294 + meta_value longtext,
295 + PRIMARY KEY (meta_id),
296 + KEY meta_key (meta_key($max_index_length)),
297 + KEY site_id (site_id)
298 + ) $charset_collate;
299 + CREATE TABLE $wpdb->signups (
300 + signup_id bigint(20) unsigned NOT NULL auto_increment,
301 + domain varchar(200) NOT NULL default '',
302 + path varchar(100) NOT NULL default '',
303 + title longtext NOT NULL,
304 + user_login varchar(60) NOT NULL default '',
305 + user_email varchar(100) NOT NULL default '',
306 + registered datetime NOT NULL default '0000-00-00 00:00:00',
307 + activated datetime NOT NULL default '0000-00-00 00:00:00',
308 + active tinyint(1) NOT NULL default '0',
309 + activation_key varchar(50) NOT NULL default '',
310 + meta longtext,
311 + PRIMARY KEY (signup_id),
312 + KEY activation_key (activation_key),
313 + KEY user_email (user_email),
314 + KEY user_login_email (user_login,user_email),
315 + KEY domain_path (domain(140),path(51))
316 + ) $charset_collate;";
317 +
318 + switch ( $scope ) {
319 + case 'blog':
320 + $queries = $blog_tables;
321 + break;
322 + case 'global':
323 + $queries = $global_tables;
324 + if ( $is_multisite ) {
325 + $queries .= $ms_global_tables;
326 + }
327 + break;
328 + case 'ms_global':
329 + $queries = $ms_global_tables;
330 + break;
331 + case 'all':
332 + default:
333 + $queries = $global_tables . $blog_tables;
334 + if ( $is_multisite ) {
335 + $queries .= $ms_global_tables;
336 + }
337 + break;
338 + }
339 +
340 + if ( isset( $old_blog_id ) ) {
341 + $wpdb->set_blog_id( $old_blog_id );
342 + }
343 +
344 + return $queries;
345 + }
346 +
347 + // Populate for back compat.
348 + $wp_queries = wp_get_db_schema( 'all' );
349 +
350 + /**
351 + * Create WordPress options and set the default values.
352 + *
353 + * @since 1.5.0
354 + * @since 5.1.0 The $options parameter has been added.
355 + *
356 + * @global wpdb $wpdb WordPress database abstraction object.
357 + * @global int $wp_db_version WordPress database version.
358 + * @global int $wp_current_db_version The old (current) database version.
359 + *
360 + * @param array $options Optional. Custom option $key => $value pairs to use. Default empty array.
361 + */
362 + function populate_options( array $options = array() ) {
363 + global $wpdb, $wp_db_version, $wp_current_db_version;
364 +
365 + $guessurl = wp_guess_url();
366 + /**
367 + * Fires before creating WordPress options and populating their default values.
368 + *
369 + * @since 2.6.0
370 + */
371 + do_action( 'populate_options' );
372 +
373 + // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
374 + $stylesheet = WP_DEFAULT_THEME;
375 + $template = WP_DEFAULT_THEME;
376 + $theme = wp_get_theme( WP_DEFAULT_THEME );
377 + if ( ! $theme->exists() ) {
378 + $theme = WP_Theme::get_core_default_theme();
379 + }
380 +
381 + // If we can't find a core default theme, WP_DEFAULT_THEME is the best we can do.
382 + if ( $theme ) {
383 + $stylesheet = $theme->get_stylesheet();
384 + $template = $theme->get_template();
385 + }
386 +
387 + $timezone_string = '';
388 + $gmt_offset = 0;
389 + /*
390 + * translators: default GMT offset or timezone string. Must be either a valid offset (-12 to 14)
391 + * or a valid timezone string (America/New_York). See https://www.php.net/manual/en/timezones.php
392 + * for all timezone strings currently supported by PHP.
393 + *
394 + * Important: When a previous timezone string, like `Europe/Kiev`, has been superseded by an
395 + * updated one, like `Europe/Kyiv`, as a rule of thumb, the **old** timezone name should be used
396 + * in the "translation" to allow for the default timezone setting to be PHP cross-version compatible,
397 + * as old timezone names will be recognized in new PHP versions, while new timezone names cannot
398 + * be recognized in old PHP versions.
399 + *
400 + * To verify which timezone strings are available in the _oldest_ PHP version supported, you can
401 + * use https://3v4l.org/6YQAt#v5.6.20 and replace the "BR" (Brazil) in the code line with the
402 + * country code for which you want to look up the supported timezone names.
403 + */
404 + $offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
405 + if ( is_numeric( $offset_or_tz ) ) {
406 + $gmt_offset = $offset_or_tz;
407 + } elseif ( $offset_or_tz && in_array( $offset_or_tz, timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true ) ) {
408 + $timezone_string = $offset_or_tz;
409 + }
410 +
411 + $defaults = array(
412 + 'siteurl' => $guessurl,
413 + 'home' => $guessurl,
414 + 'blogname' => __( 'My Site' ),
415 + 'blogdescription' => '',
416 + 'users_can_register' => 0,
417 + 'admin_email' => 'you@example.com',
418 + /* translators: Default start of the week. 0 = Sunday, 1 = Monday. */
419 + 'start_of_week' => _x( '1', 'start of week' ),
420 + 'use_balanceTags' => 0,
421 + 'use_smilies' => 1,
422 + 'require_name_email' => 1,
423 + 'comments_notify' => 1,
424 + 'posts_per_rss' => 10,
425 + 'rss_use_excerpt' => 0,
426 + 'mailserver_url' => 'mail.example.com',
427 + 'mailserver_login' => 'login@example.com',
428 + 'mailserver_pass' => '',
429 + 'mailserver_port' => 110,
430 + 'default_category' => 1,
431 + 'default_comment_status' => 'open',
432 + 'default_ping_status' => 'open',
433 + 'default_pingback_flag' => 1,
434 + 'posts_per_page' => 10,
435 + /* translators: Default date format, see https://www.php.net/manual/datetime.format.php */
436 + 'date_format' => __( 'F j, Y' ),
437 + /* translators: Default time format, see https://www.php.net/manual/datetime.format.php */
438 + 'time_format' => __( 'g:i a' ),
439 + /* translators: Links last updated date format, see https://www.php.net/manual/datetime.format.php */
440 + 'links_updated_date_format' => __( 'F j, Y g:i a' ),
441 + 'comment_moderation' => 0,
442 + 'moderation_notify' => 1,
443 + 'permalink_structure' => '',
444 + 'rewrite_rules' => '',
445 + 'hack_file' => 0,
446 + 'blog_charset' => 'UTF-8',
447 + 'moderation_keys' => '',
448 + 'active_plugins' => array(),
449 + 'category_base' => '',
450 + 'ping_sites' => 'https://rpc.pingomatic.com/',
451 + 'comment_max_links' => 2,
452 + 'gmt_offset' => $gmt_offset,
453 +
454 + // 1.5.0
455 + 'default_email_category' => 1,
456 + 'recently_edited' => '',
457 + 'template' => $template,
458 + 'stylesheet' => $stylesheet,
459 + 'comment_registration' => 0,
460 + 'html_type' => 'text/html',
461 +
462 + // 1.5.1
463 + 'use_trackback' => 0,
464 +
465 + // 2.0.0
466 + 'default_role' => 'subscriber',
467 + 'db_version' => $wp_db_version,
468 +
469 + // 2.0.1
470 + 'uploads_use_yearmonth_folders' => 1,
471 + 'upload_path' => '',
472 +
473 + // 2.1.0
474 + 'blog_public' => '1',
475 + 'default_link_category' => 2,
476 + 'show_on_front' => 'posts',
477 +
478 + // 2.2.0
479 + 'tag_base' => '',
480 +
481 + // 2.5.0
482 + 'show_avatars' => '1',
483 + 'avatar_rating' => 'G',
484 + 'upload_url_path' => '',
485 + 'thumbnail_size_w' => 150,
486 + 'thumbnail_size_h' => 150,
487 + 'thumbnail_crop' => 1,
488 + 'medium_size_w' => 300,
489 + 'medium_size_h' => 300,
490 +
491 + // 2.6.0
492 + 'avatar_default' => 'mystery',
493 +
494 + // 2.7.0
495 + 'large_size_w' => 1024,
496 + 'large_size_h' => 1024,
497 + 'image_default_link_type' => 'none',
498 + 'image_default_size' => '',
499 + 'image_default_align' => '',
500 + 'close_comments_for_old_posts' => 0,
501 + 'close_comments_days_old' => 14,
502 + 'thread_comments' => 1,
503 + 'thread_comments_depth' => 5,
504 + 'page_comments' => 0,
505 + 'comments_per_page' => 50,
506 + 'default_comments_page' => 'newest',
507 + 'comment_order' => 'asc',
508 + 'sticky_posts' => array(),
509 + 'widget_categories' => array(),
510 + 'widget_text' => array(),
511 + 'widget_rss' => array(),
512 + 'uninstall_plugins' => array(),
513 +
514 + // 2.8.0
515 + 'timezone_string' => $timezone_string,
516 +
517 + // 3.0.0
518 + 'page_for_posts' => 0,
519 + 'page_on_front' => 0,
520 +
521 + // 3.1.0
522 + 'default_post_format' => 0,
523 +
524 + // 3.5.0
525 + 'link_manager_enabled' => 0,
526 +
527 + // 4.3.0
528 + 'finished_splitting_shared_terms' => 1,
529 + 'site_icon' => 0,
530 +
531 + // 4.4.0
532 + 'medium_large_size_w' => 768,
533 + 'medium_large_size_h' => 0,
534 +
535 + // 4.9.6
536 + 'wp_page_for_privacy_policy' => 0,
537 +
538 + // 4.9.8
539 + 'show_comments_cookies_opt_in' => 1,
540 +
541 + // 5.3.0
542 + 'admin_email_lifespan' => ( time() + 6 * MONTH_IN_SECONDS ),
543 +
544 + // 5.5.0
545 + 'disallowed_keys' => '',
546 + 'comment_previously_approved' => 1,
547 + 'auto_plugin_theme_update_emails' => array(),
548 +
549 + // 5.6.0
550 + 'auto_update_core_dev' => 'enabled',
551 + 'auto_update_core_minor' => 'enabled',
552 + /*
553 + * Default to enabled for new installs.
554 + * See https://core.trac.wordpress.org/ticket/51742.
555 + */
556 + 'auto_update_core_major' => 'enabled',
557 +
558 + // 5.8.0
559 + 'wp_force_deactivated_plugins' => array(),
560 +
561 + // 6.4.0
562 + 'wp_attachment_pages_enabled' => 0,
563 +
564 + // 6.9.0
565 + 'wp_notes_notify' => 1,
566 + );
567 +
568 + // 3.3.0
569 + if ( ! is_multisite() ) {
570 + $defaults['initial_db_version'] = ! empty( $wp_current_db_version ) && $wp_current_db_version < $wp_db_version
571 + ? $wp_current_db_version : $wp_db_version;
572 + }
573 +
574 + // 3.0.0 multisite.
575 + if ( is_multisite() ) {
576 + $defaults['permalink_structure'] = '/%year%/%monthnum%/%day%/%postname%/';
577 + }
578 +
579 + $options = wp_parse_args( $options, $defaults );
580 +
581 + // Set autoload to no for these options.
582 + $fat_options = array(
583 + 'moderation_keys',
584 + 'recently_edited',
585 + 'disallowed_keys',
586 + 'uninstall_plugins',
587 + 'auto_plugin_theme_update_emails',
588 + );
589 +
590 + $keys = "'" . implode( "', '", array_keys( $options ) ) . "'";
591 + $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
592 +
593 + $insert = '';
594 +
595 + foreach ( $options as $option => $value ) {
596 + if ( in_array( $option, $existing_options, true ) ) {
597 + continue;
598 + }
599 +
600 + if ( in_array( $option, $fat_options, true ) ) {
601 + $autoload = 'off';
602 + } else {
603 + $autoload = 'on';
604 + }
605 +
606 + if ( ! empty( $insert ) ) {
607 + $insert .= ', ';
608 + }
609 +
610 + $value = maybe_serialize( sanitize_option( $option, $value ) );
611 +
612 + $insert .= $wpdb->prepare( '(%s, %s, %s)', $option, $value, $autoload );
613 + }
614 +
615 + if ( ! empty( $insert ) ) {
616 + $wpdb->query( "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
617 + }
618 +
619 + // In case it is set, but blank, update "home".
620 + if ( ! __get_option( 'home' ) ) {
621 + update_option( 'home', $guessurl );
622 + }
623 +
624 + // Delete unused options.
625 + $unusedoptions = array(
626 + 'blodotgsping_url',
627 + 'bodyterminator',
628 + 'emailtestonly',
629 + 'phoneemail_separator',
630 + 'smilies_directory',
631 + 'subjectprefix',
632 + 'use_bbcode',
633 + 'use_blodotgsping',
634 + 'use_phoneemail',
635 + 'use_quicktags',
636 + 'use_weblogsping',
637 + 'weblogs_cache_file',
638 + 'use_preview',
639 + 'use_htmltrans',
640 + 'smilies_directory',
641 + 'fileupload_allowedusers',
642 + 'use_phoneemail',
643 + 'default_post_status',
644 + 'default_post_category',
645 + 'archive_mode',
646 + 'time_difference',
647 + 'links_minadminlevel',
648 + 'links_use_adminlevels',
649 + 'links_rating_type',
650 + 'links_rating_char',
651 + 'links_rating_ignore_zero',
652 + 'links_rating_single_image',
653 + 'links_rating_image0',
654 + 'links_rating_image1',
655 + 'links_rating_image2',
656 + 'links_rating_image3',
657 + 'links_rating_image4',
658 + 'links_rating_image5',
659 + 'links_rating_image6',
660 + 'links_rating_image7',
661 + 'links_rating_image8',
662 + 'links_rating_image9',
663 + 'links_recently_updated_time',
664 + 'links_recently_updated_prepend',
665 + 'links_recently_updated_append',
666 + 'weblogs_cacheminutes',
667 + 'comment_allowed_tags',
668 + 'search_engine_friendly_urls',
669 + 'default_geourl_lat',
670 + 'default_geourl_lon',
671 + 'use_default_geourl',
672 + 'weblogs_xml_url',
673 + 'new_users_can_blog',
674 + '_wpnonce',
675 + '_wp_http_referer',
676 + 'Update',
677 + 'action',
678 + 'rich_editing',
679 + 'autosave_interval',
680 + 'deactivated_plugins',
681 + 'can_compress_scripts',
682 + 'page_uris',
683 + 'update_core',
684 + 'update_plugins',
685 + 'update_themes',
686 + 'doing_cron',
687 + 'random_seed',
688 + 'rss_excerpt_length',
689 + 'secret',
690 + 'use_linksupdate',
691 + 'default_comment_status_page',
692 + 'wporg_popular_tags',
693 + 'what_to_show',
694 + 'rss_language',
695 + 'language',
696 + 'enable_xmlrpc',
697 + 'enable_app',
698 + 'embed_autourls',
699 + 'default_post_edit_rows',
700 + 'gzipcompression',
701 + 'advanced_edit',
702 + );
703 + foreach ( $unusedoptions as $option ) {
704 + delete_option( $option );
705 + }
706 +
707 + // Delete obsolete magpie stuff.
708 + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'" );
709 +
710 + // Clear expired transients.
711 + delete_expired_transients( true );
712 + }
713 +
714 + /**
715 + * Execute WordPress role creation for the various WordPress versions.
716 + *
717 + * @since 2.0.0
718 + */
719 + function populate_roles() {
720 + $wp_roles = wp_roles();
721 +
722 + // Disable role updates to the database while populating roles.
723 + $original_use_db = $wp_roles->use_db;
724 + $wp_roles->use_db = false;
725 +
726 + // Populate roles
727 + populate_roles_160();
728 + populate_roles_210();
729 + populate_roles_230();
730 + populate_roles_250();
731 + populate_roles_260();
732 + populate_roles_270();
733 + populate_roles_280();
734 + populate_roles_300();
735 +
736 + // Save the updated roles to the database.
737 + if ( $original_use_db ) {
738 + update_option( $wp_roles->role_key, $wp_roles->roles, true );
739 + }
740 +
741 + // Restore original value for writing to database.
742 + $wp_roles->use_db = $original_use_db;
743 + }
744 +
745 + /**
746 + * Create the roles for WordPress 2.0
747 + *
748 + * @since 2.0.0
749 + */
750 + function populate_roles_160() {
751 + // Add roles.
752 + add_role( 'administrator', 'Administrator' );
753 + add_role( 'editor', 'Editor' );
754 + add_role( 'author', 'Author' );
755 + add_role( 'contributor', 'Contributor' );
756 + add_role( 'subscriber', 'Subscriber' );
757 +
758 + // Add caps for Administrator role.
759 + $role = get_role( 'administrator' );
760 + $role->add_cap( 'switch_themes' );
761 + $role->add_cap( 'edit_themes' );
762 + $role->add_cap( 'activate_plugins' );
763 + $role->add_cap( 'edit_plugins' );
764 + $role->add_cap( 'edit_users' );
765 + $role->add_cap( 'edit_files' );
766 + $role->add_cap( 'manage_options' );
767 + $role->add_cap( 'moderate_comments' );
768 + $role->add_cap( 'manage_categories' );
769 + $role->add_cap( 'manage_links' );
770 + $role->add_cap( 'upload_files' );
771 + $role->add_cap( 'import' );
772 + $role->add_cap( 'unfiltered_html' );
773 + $role->add_cap( 'edit_posts' );
774 + $role->add_cap( 'edit_others_posts' );
775 + $role->add_cap( 'edit_published_posts' );
776 + $role->add_cap( 'publish_posts' );
777 + $role->add_cap( 'edit_pages' );
778 + $role->add_cap( 'read' );
779 + $role->add_cap( 'level_10' );
780 + $role->add_cap( 'level_9' );
781 + $role->add_cap( 'level_8' );
782 + $role->add_cap( 'level_7' );
783 + $role->add_cap( 'level_6' );
784 + $role->add_cap( 'level_5' );
785 + $role->add_cap( 'level_4' );
786 + $role->add_cap( 'level_3' );
787 + $role->add_cap( 'level_2' );
788 + $role->add_cap( 'level_1' );
789 + $role->add_cap( 'level_0' );
790 +
791 + // Add caps for Editor role.
792 + $role = get_role( 'editor' );
793 + $role->add_cap( 'moderate_comments' );
794 + $role->add_cap( 'manage_categories' );
795 + $role->add_cap( 'manage_links' );
796 + $role->add_cap( 'upload_files' );
797 + $role->add_cap( 'unfiltered_html' );
798 + $role->add_cap( 'edit_posts' );
799 + $role->add_cap( 'edit_others_posts' );
800 + $role->add_cap( 'edit_published_posts' );
801 + $role->add_cap( 'publish_posts' );
802 + $role->add_cap( 'edit_pages' );
803 + $role->add_cap( 'read' );
804 + $role->add_cap( 'level_7' );
805 + $role->add_cap( 'level_6' );
806 + $role->add_cap( 'level_5' );
807 + $role->add_cap( 'level_4' );
808 + $role->add_cap( 'level_3' );
809 + $role->add_cap( 'level_2' );
810 + $role->add_cap( 'level_1' );
811 + $role->add_cap( 'level_0' );
812 +
813 + // Add caps for Author role.
814 + $role = get_role( 'author' );
815 + $role->add_cap( 'upload_files' );
816 + $role->add_cap( 'edit_posts' );
817 + $role->add_cap( 'edit_published_posts' );
818 + $role->add_cap( 'publish_posts' );
819 + $role->add_cap( 'read' );
820 + $role->add_cap( 'level_2' );
821 + $role->add_cap( 'level_1' );
822 + $role->add_cap( 'level_0' );
823 +
824 + // Add caps for Contributor role.
825 + $role = get_role( 'contributor' );
826 + $role->add_cap( 'edit_posts' );
827 + $role->add_cap( 'read' );
828 + $role->add_cap( 'level_1' );
829 + $role->add_cap( 'level_0' );
830 +
831 + // Add caps for Subscriber role.
832 + $role = get_role( 'subscriber' );
833 + $role->add_cap( 'read' );
834 + $role->add_cap( 'level_0' );
835 + }
836 +
837 + /**
838 + * Create and modify WordPress roles for WordPress 2.1.
839 + *
840 + * @since 2.1.0
841 + */
842 + function populate_roles_210() {
843 + $roles = array( 'administrator', 'editor' );
844 + foreach ( $roles as $role ) {
845 + $role = get_role( $role );
846 + if ( empty( $role ) ) {
847 + continue;
848 + }
849 +
850 + $role->add_cap( 'edit_others_pages' );
851 + $role->add_cap( 'edit_published_pages' );
852 + $role->add_cap( 'publish_pages' );
853 + $role->add_cap( 'delete_pages' );
854 + $role->add_cap( 'delete_others_pages' );
855 + $role->add_cap( 'delete_published_pages' );
856 + $role->add_cap( 'delete_posts' );
857 + $role->add_cap( 'delete_others_posts' );
858 + $role->add_cap( 'delete_published_posts' );
859 + $role->add_cap( 'delete_private_posts' );
860 + $role->add_cap( 'edit_private_posts' );
861 + $role->add_cap( 'read_private_posts' );
862 + $role->add_cap( 'delete_private_pages' );
863 + $role->add_cap( 'edit_private_pages' );
864 + $role->add_cap( 'read_private_pages' );
865 + }
866 +
867 + $role = get_role( 'administrator' );
868 + if ( ! empty( $role ) ) {
869 + $role->add_cap( 'delete_users' );
870 + $role->add_cap( 'create_users' );
871 + }
872 +
873 + $role = get_role( 'author' );
874 + if ( ! empty( $role ) ) {
875 + $role->add_cap( 'delete_posts' );
876 + $role->add_cap( 'delete_published_posts' );
877 + }
878 +
879 + $role = get_role( 'contributor' );
880 + if ( ! empty( $role ) ) {
881 + $role->add_cap( 'delete_posts' );
882 + }
883 + }
884 +
885 + /**
886 + * Create and modify WordPress roles for WordPress 2.3.
887 + *
888 + * @since 2.3.0
889 + */
890 + function populate_roles_230() {
891 + $role = get_role( 'administrator' );
892 +
893 + if ( ! empty( $role ) ) {
894 + $role->add_cap( 'unfiltered_upload' );
895 + }
896 + }
897 +
898 + /**
899 + * Create and modify WordPress roles for WordPress 2.5.
900 + *
901 + * @since 2.5.0
902 + */
903 + function populate_roles_250() {
904 + $role = get_role( 'administrator' );
905 +
906 + if ( ! empty( $role ) ) {
907 + $role->add_cap( 'edit_dashboard' );
908 + }
909 + }
910 +
911 + /**
912 + * Create and modify WordPress roles for WordPress 2.6.
913 + *
914 + * @since 2.6.0
915 + */
916 + function populate_roles_260() {
917 + $role = get_role( 'administrator' );
918 +
919 + if ( ! empty( $role ) ) {
920 + $role->add_cap( 'update_plugins' );
921 + $role->add_cap( 'delete_plugins' );
922 + }
923 + }
924 +
925 + /**
926 + * Create and modify WordPress roles for WordPress 2.7.
927 + *
928 + * @since 2.7.0
929 + */
930 + function populate_roles_270() {
931 + $role = get_role( 'administrator' );
932 +
933 + if ( ! empty( $role ) ) {
934 + $role->add_cap( 'install_plugins' );
935 + $role->add_cap( 'update_themes' );
936 + }
937 + }
938 +
939 + /**
940 + * Create and modify WordPress roles for WordPress 2.8.
941 + *
942 + * @since 2.8.0
943 + */
944 + function populate_roles_280() {
945 + $role = get_role( 'administrator' );
946 +
947 + if ( ! empty( $role ) ) {
948 + $role->add_cap( 'install_themes' );
949 + }
950 + }
951 +
952 + /**
953 + * Create and modify WordPress roles for WordPress 3.0.
954 + *
955 + * @since 3.0.0
956 + */
957 + function populate_roles_300() {
958 + $role = get_role( 'administrator' );
959 +
960 + if ( ! empty( $role ) ) {
961 + $role->add_cap( 'update_core' );
962 + $role->add_cap( 'list_users' );
963 + $role->add_cap( 'remove_users' );
964 + $role->add_cap( 'promote_users' );
965 + $role->add_cap( 'edit_theme_options' );
966 + $role->add_cap( 'delete_themes' );
967 + $role->add_cap( 'export' );
968 + }
969 + }
970 +
971 + if ( ! function_exists( 'install_network' ) ) :
972 + /**
973 + * Install Network.
974 + *
975 + * @since 3.0.0
976 + */
977 + function install_network() {
978 + if ( ! defined( 'WP_INSTALLING_NETWORK' ) ) {
979 + define( 'WP_INSTALLING_NETWORK', true );
980 + }
981 +
982 + dbDelta( wp_get_db_schema( 'global' ) );
983 + }
984 + endif;
985 +
986 + /**
987 + * Populate network settings.
988 + *
989 + * @since 3.0.0
990 + *
991 + * @global wpdb $wpdb WordPress database abstraction object.
992 + * @global object $current_site
993 + * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
994 + *
995 + * @param int $network_id ID of network to populate.
996 + * @param string $domain The domain name for the network. Example: "example.com".
997 + * @param string $email Email address for the network administrator.
998 + * @param string $site_name The name of the network.
999 + * @param string $path Optional. The path to append to the network's domain name. Default '/'.
1000 + * @param bool $subdomain_install Optional. Whether the network is a subdomain installation or a subdirectory installation.
1001 + * Default false, meaning the network is a subdirectory installation.
1002 + * @return true|WP_Error True on success, or WP_Error on warning (with the installation otherwise successful,
1003 + * so the error code must be checked) or failure.
1004 + */
1005 + function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
1006 + global $wpdb, $current_site, $wp_rewrite;
1007 +
1008 + $network_id = (int) $network_id;
1009 +
1010 + /**
1011 + * Fires before a network is populated.
1012 + *
1013 + * @since 6.9.0
1014 + *
1015 + * @param int $network_id ID of network to populate.
1016 + * @param string $domain The domain name for the network.
1017 + * @param string $email Email address for the network administrator.
1018 + * @param string $site_name The name of the network.
1019 + * @param string $path The path to append to the network's domain name.
1020 + * @param bool $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1021 + */
1022 + do_action( 'before_populate_network', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1023 +
1024 + $errors = new WP_Error();
1025 + if ( '' === $domain ) {
1026 + $errors->add( 'empty_domain', __( 'You must provide a domain name.' ) );
1027 + }
1028 + if ( '' === $site_name ) {
1029 + $errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) );
1030 + }
1031 +
1032 + // Check for network collision.
1033 + $network_exists = false;
1034 + if ( is_multisite() ) {
1035 + if ( get_network( $network_id ) ) {
1036 + $errors->add( 'siteid_exists', __( 'The network already exists.' ) );
1037 + }
1038 + } else {
1039 + if ( $network_id === (int) $wpdb->get_var(
1040 + $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id )
1041 + ) ) {
1042 + $errors->add( 'siteid_exists', __( 'The network already exists.' ) );
1043 + }
1044 + }
1045 +
1046 + if ( ! is_email( $email ) ) {
1047 + $errors->add( 'invalid_email', __( 'You must provide a valid email address.' ) );
1048 + }
1049 +
1050 + if ( $errors->has_errors() ) {
1051 + return $errors;
1052 + }
1053 +
1054 + if ( 1 === $network_id ) {
1055 + $wpdb->insert(
1056 + $wpdb->site,
1057 + array(
1058 + 'domain' => $domain,
1059 + 'path' => $path,
1060 + )
1061 + );
1062 + $network_id = $wpdb->insert_id;
1063 + } else {
1064 + $wpdb->insert(
1065 + $wpdb->site,
1066 + array(
1067 + 'domain' => $domain,
1068 + 'path' => $path,
1069 + 'id' => $network_id,
1070 + )
1071 + );
1072 + }
1073 +
1074 + populate_network_meta(
1075 + $network_id,
1076 + array(
1077 + 'admin_email' => $email,
1078 + 'site_name' => $site_name,
1079 + 'subdomain_install' => $subdomain_install,
1080 + )
1081 + );
1082 +
1083 + // Remove the cron event since Recovery Mode is not used in Multisite.
1084 + if ( wp_next_scheduled( 'recovery_mode_clean_expired_keys' ) ) {
1085 + wp_clear_scheduled_hook( 'recovery_mode_clean_expired_keys' );
1086 + }
1087 +
1088 + /*
1089 + * When upgrading from single to multisite, assume the current site will
1090 + * become the main site of the network. When using populate_network()
1091 + * to create another network in an existing multisite environment, skip
1092 + * these steps since the main site of the new network has not yet been
1093 + * created.
1094 + */
1095 + if ( ! is_multisite() ) {
1096 + $current_site = new stdClass();
1097 + $current_site->domain = $domain;
1098 + $current_site->path = $path;
1099 + $current_site->site_name = ucfirst( $domain );
1100 + $wpdb->insert(
1101 + $wpdb->blogs,
1102 + array(
1103 + 'site_id' => $network_id,
1104 + 'blog_id' => 1,
1105 + 'domain' => $domain,
1106 + 'path' => $path,
1107 + 'registered' => current_time( 'mysql' ),
1108 + )
1109 + );
1110 + $current_site->blog_id = $wpdb->insert_id;
1111 +
1112 + $site_user_id = (int) $wpdb->get_var(
1113 + $wpdb->prepare(
1114 + "SELECT meta_value
1115 + FROM $wpdb->sitemeta
1116 + WHERE meta_key = %s AND site_id = %d",
1117 + 'admin_user_id',
1118 + $network_id
1119 + )
1120 + );
1121 +
1122 + update_user_meta( $site_user_id, 'source_domain', $domain );
1123 + update_user_meta( $site_user_id, 'primary_blog', $current_site->blog_id );
1124 +
1125 + // Unable to use update_network_option() while populating the network.
1126 + $wpdb->insert(
1127 + $wpdb->sitemeta,
1128 + array(
1129 + 'site_id' => $network_id,
1130 + 'meta_key' => 'main_site',
1131 + 'meta_value' => $current_site->blog_id,
1132 + )
1133 + );
1134 +
1135 + if ( $subdomain_install ) {
1136 + $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
1137 + } else {
1138 + $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' );
1139 + }
1140 +
1141 + flush_rewrite_rules();
1142 +
1143 + /**
1144 + * Fires after a network is created when converting a single site to multisite.
1145 + *
1146 + * @since 6.9.0
1147 + *
1148 + * @param int $network_id ID of network created.
1149 + * @param string $domain The domain name for the network.
1150 + * @param string $email Email address for the network administrator.
1151 + * @param string $site_name The name of the network.
1152 + * @param string $path The path to append to the network's domain name.
1153 + * @param bool $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1154 + */
1155 + do_action( 'after_upgrade_to_multisite', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1156 +
1157 + if ( ! $subdomain_install ) {
1158 + return true;
1159 + }
1160 +
1161 + $vhost_ok = false;
1162 + $errstr = '';
1163 + $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
1164 + $page = wp_remote_get(
1165 + 'http://' . $hostname,
1166 + array(
1167 + 'timeout' => 5,
1168 + 'httpversion' => '1.1',
1169 + )
1170 + );
1171 + if ( is_wp_error( $page ) ) {
1172 + $errstr = $page->get_error_message();
1173 + } elseif ( 200 === wp_remote_retrieve_response_code( $page ) ) {
1174 + $vhost_ok = true;
1175 + }
1176 +
1177 + if ( ! $vhost_ok ) {
1178 + $msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
1179 +
1180 + $msg .= '<p>' . sprintf(
1181 + /* translators: %s: Host name. */
1182 + __( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
1183 + '<code>' . $hostname . '</code>'
1184 + );
1185 + if ( ! empty( $errstr ) ) {
1186 + /* translators: %s: Error message. */
1187 + $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
1188 + }
1189 + $msg .= '</p>';
1190 +
1191 + $msg .= '<p>' . sprintf(
1192 + /* translators: %s: Asterisk symbol (*). */
1193 + __( '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.' ),
1194 + '<code>*</code>'
1195 + ) . '</p>';
1196 +
1197 + $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>';
1198 +
1199 + return new WP_Error( 'no_wildcard_dns', $msg );
1200 + }
1201 + }
1202 +
1203 + /**
1204 + * Fires after a network is fully populated.
1205 + *
1206 + * @since 6.9.0
1207 + *
1208 + * @param int $network_id ID of network created.
1209 + * @param string $domain The domain name for the network.
1210 + * @param string $email Email address for the network administrator.
1211 + * @param string $site_name The name of the network.
1212 + * @param string $path The path to append to the network's domain name.
1213 + * @param bool $subdomain_install Whether the network is a subdomain installation or a subdirectory installation.
1214 + */
1215 + do_action( 'after_populate_network', $network_id, $domain, $email, $site_name, $path, $subdomain_install );
1216 +
1217 + return true;
1218 + }
1219 +
1220 + /**
1221 + * Creates WordPress network meta and sets the default values.
1222 + *
1223 + * @since 5.1.0
1224 + *
1225 + * @global wpdb $wpdb WordPress database abstraction object.
1226 + * @global int $wp_db_version WordPress database version.
1227 + *
1228 + * @param int $network_id Network ID to populate meta for.
1229 + * @param array $meta Optional. Custom meta $key => $value pairs to use. Default empty array.
1230 + */
1231 + function populate_network_meta( $network_id, array $meta = array() ) {
1232 + global $wpdb, $wp_db_version;
1233 +
1234 + $network_id = (int) $network_id;
1235 +
1236 + $email = ! empty( $meta['admin_email'] ) ? $meta['admin_email'] : '';
1237 + $subdomain_install = isset( $meta['subdomain_install'] ) ? (int) $meta['subdomain_install'] : 0;
1238 +
1239 + // If a user with the provided email does not exist, default to the current user as the new network admin.
1240 + $site_user = ! empty( $email ) ? get_user_by( 'email', $email ) : false;
1241 + if ( false === $site_user ) {
1242 + $site_user = wp_get_current_user();
1243 + }
1244 +
1245 + if ( empty( $email ) ) {
1246 + $email = $site_user->user_email;
1247 + }
1248 +
1249 + $template = get_option( 'template' );
1250 + $stylesheet = get_option( 'stylesheet' );
1251 + $allowed_themes = array( $stylesheet => true );
1252 +
1253 + if ( $template !== $stylesheet ) {
1254 + $allowed_themes[ $template ] = true;
1255 + }
1256 +
1257 + if ( WP_DEFAULT_THEME !== $stylesheet && WP_DEFAULT_THEME !== $template ) {
1258 + $allowed_themes[ WP_DEFAULT_THEME ] = true;
1259 + }
1260 +
1261 + // If WP_DEFAULT_THEME doesn't exist, also include the latest core default theme.
1262 + if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
1263 + $core_default = WP_Theme::get_core_default_theme();
1264 + if ( $core_default ) {
1265 + $allowed_themes[ $core_default->get_stylesheet() ] = true;
1266 + }
1267 + }
1268 +
1269 + if ( function_exists( 'clean_network_cache' ) ) {
1270 + clean_network_cache( $network_id );
1271 + } else {
1272 + wp_cache_delete( $network_id, 'networks' );
1273 + }
1274 +
1275 + if ( ! is_multisite() ) {
1276 + $site_admins = array( $site_user->user_login );
1277 + $users = get_users(
1278 + array(
1279 + 'fields' => array( 'user_login' ),
1280 + 'role' => 'administrator',
1281 + )
1282 + );
1283 + if ( $users ) {
1284 + foreach ( $users as $user ) {
1285 + $site_admins[] = $user->user_login;
1286 + }
1287 +
1288 + $site_admins = array_unique( $site_admins );
1289 + }
1290 + } else {
1291 + $site_admins = get_site_option( 'site_admins' );
1292 + }
1293 +
1294 + /* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
1295 + $welcome_email = __(
1296 + 'Howdy USERNAME,
1297 +
1298 + Your new SITE_NAME site has been successfully set up at:
1299 + BLOG_URL
1300 +
1301 + You can log in to the administrator account with the following information:
1302 +
1303 + Username: USERNAME
1304 + Password: PASSWORD
1305 + Log in here: BLOG_URLwp-login.php
1306 +
1307 + We hope you enjoy your new site. Thanks!
1308 +
1309 + --The Team @ SITE_NAME'
1310 + );
1311 +
1312 + $allowed_file_types = array();
1313 + $all_mime_types = get_allowed_mime_types();
1314 +
1315 + foreach ( $all_mime_types as $ext => $mime ) {
1316 + array_push( $allowed_file_types, ...explode( '|', $ext ) );
1317 + }
1318 + $upload_filetypes = array_unique( $allowed_file_types );
1319 +
1320 + $sitemeta = array(
1321 + 'site_name' => __( 'My Network' ),
1322 + 'admin_email' => $email,
1323 + 'admin_user_id' => $site_user->ID,
1324 + 'registration' => 'none',
1325 + 'upload_filetypes' => implode( ' ', $upload_filetypes ),
1326 + 'blog_upload_space' => 100,
1327 + 'fileupload_maxk' => 1500,
1328 + 'site_admins' => $site_admins,
1329 + 'allowedthemes' => $allowed_themes,
1330 + 'illegal_names' => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ),
1331 + 'wpmu_upgrade_site' => $wp_db_version,
1332 + 'welcome_email' => $welcome_email,
1333 + /* translators: %s: Site link. */
1334 + 'first_post' => __( 'Welcome to %s. This is your first post. Edit or delete it, then start writing!' ),
1335 + // @todo - Network admins should have a method of editing the network siteurl (used for cookie hash).
1336 + 'siteurl' => get_option( 'siteurl' ) . '/',
1337 + 'add_new_users' => '0',
1338 + 'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
1339 + 'subdomain_install' => $subdomain_install,
1340 + 'ms_files_rewriting' => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
1341 + 'user_count' => get_site_option( 'user_count' ),
1342 + 'initial_db_version' => get_option( 'initial_db_version' ),
1343 + 'active_sitewide_plugins' => array(),
1344 + 'WPLANG' => get_locale(),
1345 + );
1346 + if ( ! $subdomain_install ) {
1347 + $sitemeta['illegal_names'][] = 'blog';
1348 + }
1349 +
1350 + $sitemeta = wp_parse_args( $meta, $sitemeta );
1351 +
1352 + /**
1353 + * Filters meta for a network on creation.
1354 + *
1355 + * @since 3.7.0
1356 + *
1357 + * @param array $sitemeta Associative array of network meta keys and values to be inserted.
1358 + * @param int $network_id ID of network to populate.
1359 + */
1360 + $sitemeta = apply_filters( 'populate_network_meta', $sitemeta, $network_id );
1361 +
1362 + $insert = '';
1363 + foreach ( $sitemeta as $meta_key => $meta_value ) {
1364 + if ( is_array( $meta_value ) ) {
1365 + $meta_value = serialize( $meta_value );
1366 + }
1367 + if ( ! empty( $insert ) ) {
1368 + $insert .= ', ';
1369 + }
1370 + $insert .= $wpdb->prepare( '( %d, %s, %s)', $network_id, $meta_key, $meta_value );
1371 + }
1372 + $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1373 + }
1374 +
1375 + /**
1376 + * Creates WordPress site meta and sets the default values.
1377 + *
1378 + * @since 5.1.0
1379 + *
1380 + * @global wpdb $wpdb WordPress database abstraction object.
1381 + *
1382 + * @param int $site_id Site ID to populate meta for.
1383 + * @param array $meta Optional. Custom meta $key => $value pairs to use. Default empty array.
1384 + */
1385 + function populate_site_meta( $site_id, array $meta = array() ) {
1386 + global $wpdb;
1387 +
1388 + $site_id = (int) $site_id;
1389 +
1390 + if ( ! is_site_meta_supported() ) {
1391 + return;
1392 + }
1393 +
1394 + if ( empty( $meta ) ) {
1395 + return;
1396 + }
1397 +
1398 + /**
1399 + * Filters meta for a site on creation.
1400 + *
1401 + * @since 5.2.0
1402 + *
1403 + * @param array $meta Associative array of site meta keys and values to be inserted.
1404 + * @param int $site_id ID of site to populate.
1405 + */
1406 + $site_meta = apply_filters( 'populate_site_meta', $meta, $site_id );
1407 +
1408 + $insert = '';
1409 + foreach ( $site_meta as $meta_key => $meta_value ) {
1410 + if ( is_array( $meta_value ) ) {
1411 + $meta_value = serialize( $meta_value );
1412 + }
1413 + if ( ! empty( $insert ) ) {
1414 + $insert .= ', ';
1415 + }
1416 + $insert .= $wpdb->prepare( '( %d, %s, %s)', $site_id, $meta_key, $meta_value );
1417 + }
1418 +
1419 + $wpdb->query( "INSERT INTO $wpdb->blogmeta ( blog_id, meta_key, meta_value ) VALUES " . $insert ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1420 +
1421 + wp_cache_delete( $site_id, 'blog_meta' );
1422 + wp_cache_set_sites_last_changed();
1423 + }
1424 +