WordPress 4.2.2
[autoinstalls/wordpress.git] / wp-admin / includes / upgrade.php
1 <?php
2 /**
3  * WordPress Upgrade API
4  *
5  * Most of the functions are pluggable and can be overwritten.
6  *
7  * @package WordPress
8  * @subpackage Administration
9  */
10
11 /** Include user install customize script. */
12 if ( file_exists(WP_CONTENT_DIR . '/install.php') )
13         require (WP_CONTENT_DIR . '/install.php');
14
15 /** WordPress Administration API */
16 require_once(ABSPATH . 'wp-admin/includes/admin.php');
17
18 /** WordPress Schema API */
19 require_once(ABSPATH . 'wp-admin/includes/schema.php');
20
21 if ( !function_exists('wp_install') ) :
22 /**
23  * Installs the site.
24  *
25  * Runs the required functions to set up and populate the database,
26  * including primary admin user and initial options.
27  *
28  * @since 2.1.0
29  *
30  * @param string $blog_title    Blog title.
31  * @param string $user_name     User's username.
32  * @param string $user_email    User's email.
33  * @param bool   $public        Whether blog is public.
34  * @param string $deprecated    Optional. Not used.
35  * @param string $user_password Optional. User's chosen password. Default empty (random password).
36  * @param string $language      Optional. Language chosen. Default empty.
37  * @return array Array keys 'url', 'user_id', 'password', and 'password_message'.
38  */
39 function wp_install( $blog_title, $user_name, $user_email, $public, $deprecated = '', $user_password = '', $language = '' ) {
40         if ( !empty( $deprecated ) )
41                 _deprecated_argument( __FUNCTION__, '2.6' );
42
43         wp_check_mysql_version();
44         wp_cache_flush();
45         make_db_current_silent();
46         populate_options();
47         populate_roles();
48
49         update_option('blogname', $blog_title);
50         update_option('admin_email', $user_email);
51         update_option('blog_public', $public);
52
53         if ( $language ) {
54                 update_option( 'WPLANG', $language );
55         }
56
57         $guessurl = wp_guess_url();
58
59         update_option('siteurl', $guessurl);
60
61         // If not a public blog, don't ping.
62         if ( ! $public )
63                 update_option('default_pingback_flag', 0);
64
65         /*
66          * Create default user. If the user already exists, the user tables are
67          * being shared among blogs. Just set the role in that case.
68          */
69         $user_id = username_exists($user_name);
70         $user_password = trim($user_password);
71         $email_password = false;
72         if ( !$user_id && empty($user_password) ) {
73                 $user_password = wp_generate_password( 12, false );
74                 $message = __('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you.');
75                 $user_id = wp_create_user($user_name, $user_password, $user_email);
76                 update_user_option($user_id, 'default_password_nag', true, true);
77                 $email_password = true;
78         } elseif ( ! $user_id ) {
79                 // Password has been provided
80                 $message = '<em>'.__('Your chosen password.').'</em>';
81                 $user_id = wp_create_user($user_name, $user_password, $user_email);
82         } else {
83                 $message = __('User already exists. Password inherited.');
84         }
85
86         $user = new WP_User($user_id);
87         $user->set_role('administrator');
88
89         wp_install_defaults($user_id);
90
91         wp_install_maybe_enable_pretty_permalinks();
92
93         flush_rewrite_rules();
94
95         wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.') ) );
96
97         wp_cache_flush();
98
99         /**
100          * Fires after a site is fully installed.
101          *
102          * @since 3.9.0
103          *
104          * @param WP_User $user The site owner.
105          */
106         do_action( 'wp_install', $user );
107
108         return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message);
109 }
110 endif;
111
112 if ( !function_exists('wp_install_defaults') ) :
113 /**
114  * Creates the initial content for a newly-installed site.
115  *
116  * Adds the default "Uncategorized" category, the first post (with comment),
117  * first page, and default widgets for default theme for the current version.
118  *
119  * @since 2.1.0
120  *
121  * @param int $user_id User ID.
122  */
123 function wp_install_defaults( $user_id ) {
124         global $wpdb, $wp_rewrite, $table_prefix;
125
126         // Default category
127         $cat_name = __('Uncategorized');
128         /* translators: Default category slug */
129         $cat_slug = sanitize_title(_x('Uncategorized', 'Default category slug'));
130
131         if ( global_terms_enabled() ) {
132                 $cat_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) );
133                 if ( $cat_id == null ) {
134                         $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) );
135                         $cat_id = $wpdb->insert_id;
136                 }
137                 update_option('default_category', $cat_id);
138         } else {
139                 $cat_id = 1;
140         }
141
142         $wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) );
143         $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1));
144         $cat_tt_id = $wpdb->insert_id;
145
146         // First post
147         $now = current_time( 'mysql' );
148         $now_gmt = current_time( 'mysql', 1 );
149         $first_post_guid = get_option( 'home' ) . '/?p=1';
150
151         if ( is_multisite() ) {
152                 $first_post = get_site_option( 'first_post' );
153
154                 if ( empty($first_post) )
155                         $first_post = __( 'Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start blogging!' );
156
157                 $first_post = str_replace( "SITE_URL", esc_url( network_home_url() ), $first_post );
158                 $first_post = str_replace( "SITE_NAME", get_current_site()->site_name, $first_post );
159         } else {
160                 $first_post = __('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!');
161         }
162
163         $wpdb->insert( $wpdb->posts, array(
164                                                                 'post_author' => $user_id,
165                                                                 'post_date' => $now,
166                                                                 'post_date_gmt' => $now_gmt,
167                                                                 'post_content' => $first_post,
168                                                                 'post_excerpt' => '',
169                                                                 'post_title' => __('Hello world!'),
170                                                                 /* translators: Default post slug */
171                                                                 'post_name' => sanitize_title( _x('hello-world', 'Default post slug') ),
172                                                                 'post_modified' => $now,
173                                                                 'post_modified_gmt' => $now_gmt,
174                                                                 'guid' => $first_post_guid,
175                                                                 'comment_count' => 1,
176                                                                 'to_ping' => '',
177                                                                 'pinged' => '',
178                                                                 'post_content_filtered' => ''
179                                                                 ));
180         $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) );
181
182         // Default comment
183         $first_comment_author = __('Mr WordPress');
184         $first_comment_url = 'https://wordpress.org/';
185         $first_comment = __('Hi, this is a comment.
186 To delete a comment, just log in and view the post&#039;s comments. There you will have the option to edit or delete them.');
187         if ( is_multisite() ) {
188                 $first_comment_author = get_site_option( 'first_comment_author', $first_comment_author );
189                 $first_comment_url = get_site_option( 'first_comment_url', network_home_url() );
190                 $first_comment = get_site_option( 'first_comment', $first_comment );
191         }
192         $wpdb->insert( $wpdb->comments, array(
193                                                                 'comment_post_ID' => 1,
194                                                                 'comment_author' => $first_comment_author,
195                                                                 'comment_author_email' => '',
196                                                                 'comment_author_url' => $first_comment_url,
197                                                                 'comment_date' => $now,
198                                                                 'comment_date_gmt' => $now_gmt,
199                                                                 'comment_content' => $first_comment
200                                                                 ));
201
202         // First Page
203         $first_page = sprintf( __( "This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:
204
205 <blockquote>Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my blog. I live in Los Angeles, have a great dog named Jack, and I like pi&#241;a coladas. (And gettin' caught in the rain.)</blockquote>
206
207 ...or something like this:
208
209 <blockquote>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</blockquote>
210
211 As a new WordPress user, you should go to <a href=\"%s\">your dashboard</a> to delete this page and create new pages for your content. Have fun!" ), admin_url() );
212         if ( is_multisite() )
213                 $first_page = get_site_option( 'first_page', $first_page );
214         $first_post_guid = get_option('home') . '/?page_id=2';
215         $wpdb->insert( $wpdb->posts, array(
216                                                                 'post_author' => $user_id,
217                                                                 'post_date' => $now,
218                                                                 'post_date_gmt' => $now_gmt,
219                                                                 'post_content' => $first_page,
220                                                                 'post_excerpt' => '',
221                                                                 'post_title' => __( 'Sample Page' ),
222                                                                 /* translators: Default page slug */
223                                                                 'post_name' => __( 'sample-page' ),
224                                                                 'post_modified' => $now,
225                                                                 'post_modified_gmt' => $now_gmt,
226                                                                 'guid' => $first_post_guid,
227                                                                 'post_type' => 'page',
228                                                                 'to_ping' => '',
229                                                                 'pinged' => '',
230                                                                 'post_content_filtered' => ''
231                                                                 ));
232         $wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) );
233
234         // Set up default widgets for default theme.
235         update_option( 'widget_search', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
236         update_option( 'widget_recent-posts', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
237         update_option( 'widget_recent-comments', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
238         update_option( 'widget_archives', array ( 2 => array ( 'title' => '', 'count' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
239         update_option( 'widget_categories', array ( 2 => array ( 'title' => '', 'count' => 0, 'hierarchical' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
240         update_option( 'widget_meta', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
241         update_option( 'sidebars_widgets', array ( 'wp_inactive_widgets' => array (), 'sidebar-1' => array ( 0 => 'search-2', 1 => 'recent-posts-2', 2 => 'recent-comments-2', 3 => 'archives-2', 4 => 'categories-2', 5 => 'meta-2', ), 'array_version' => 3 ) );
242
243         if ( ! is_multisite() )
244                 update_user_meta( $user_id, 'show_welcome_panel', 1 );
245         elseif ( ! is_super_admin( $user_id ) && ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) )
246                 update_user_meta( $user_id, 'show_welcome_panel', 2 );
247
248         if ( is_multisite() ) {
249                 // Flush rules to pick up the new page.
250                 $wp_rewrite->init();
251                 $wp_rewrite->flush_rules();
252
253                 $user = new WP_User($user_id);
254                 $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') );
255
256                 // Remove all perms except for the login user.
257                 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') );
258                 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') );
259
260                 // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
261                 if ( !is_super_admin( $user_id ) && $user_id != 1 )
262                         $wpdb->delete( $wpdb->usermeta, array( 'user_id' => $user_id , 'meta_key' => $wpdb->base_prefix.'1_capabilities' ) );
263         }
264 }
265 endif;
266
267 /**
268  * Maybe enable pretty permalinks on install.
269  *
270  * If after enabling pretty permalinks don't work, fallback to query-string permalinks.
271  *
272  * @since 4.2.0
273  *
274  * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
275  *
276  * @return bool Whether pretty permalinks are enabled. False otherwise.
277  */
278 function wp_install_maybe_enable_pretty_permalinks() {
279         global $wp_rewrite;
280
281         // Bail if a permalink structure is already enabled.
282         if ( get_option( 'permalink_structure' ) ) {
283                 return true;
284         }
285
286         /*
287          * The Permalink structures to attempt.
288          *
289          * The first is designed for mod_rewrite or nginx rewriting.
290          *
291          * The second is PATHINFO-based permalinks for web server configurations
292          * without a true rewrite module enabled.
293          */
294         $permalink_structures = array(
295                 '/%year%/%monthnum%/%day%/%postname%/',
296                 '/index.php/%year%/%monthnum%/%day%/%postname%/'
297         );
298
299         foreach ( (array) $permalink_structures as $permalink_structure ) {
300                 $wp_rewrite->set_permalink_structure( $permalink_structure );
301
302                 /*
303                  * Flush rules with the hard option to force refresh of the web-server's
304                  * rewrite config file (e.g. .htaccess or web.config).
305                  */
306                 $wp_rewrite->flush_rules( true );
307
308                 // Test against a real WordPress Post, or if none were created, a random 404 page.
309                 $test_url = get_permalink( 1 );
310
311                 if ( ! $test_url ) {
312                         $test_url = home_url( '/wordpress-check-for-rewrites/' );
313                 }
314
315                 /*
316                  * Send a request to the site, and check whether
317                  * the 'x-pingback' header is returned as expected.
318                  *
319                  * Uses wp_remote_get() instead of wp_remote_head() because web servers
320                  * can block head requests.
321                  */
322                 $response          = wp_remote_get( $test_url, array( 'timeout' => 5 ) );
323                 $x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );
324                 $pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );
325
326                 if ( $pretty_permalinks ) {
327                         return true;
328                 }
329         }
330
331         /*
332          * If it makes it this far, pretty permalinks failed.
333          * Fallback to query-string permalinks.
334          */
335         $wp_rewrite->set_permalink_structure( '' );
336         $wp_rewrite->flush_rules( true );
337
338         return false;
339 }
340
341 if ( !function_exists('wp_new_blog_notification') ) :
342 /**
343  * Notifies the site admin that the setup is complete.
344  *
345  * Sends an email with wp_mail to the new administrator that the site setup is complete,
346  * and provides them with a record of their login credentials.
347  *
348  * @since 2.1.0
349  *
350  * @param string $blog_title Blog title.
351  * @param string $blog_url   Blog url.
352  * @param int    $user_id    User ID.
353  * @param string $password   User's Password.
354  */
355 function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) {
356         $user = new WP_User( $user_id );
357         $email = $user->user_email;
358         $name = $user->user_login;
359         $login_url = wp_login_url();
360         $message = sprintf( __( "Your new WordPress site has been successfully set up at:
361
362 %1\$s
363
364 You can log in to the administrator account with the following information:
365
366 Username: %2\$s
367 Password: %3\$s
368 Log in here: %4\$s
369
370 We hope you enjoy your new site. Thanks!
371
372 --The WordPress Team
373 https://wordpress.org/
374 "), $blog_url, $name, $password, $login_url );
375
376         @wp_mail($email, __('New WordPress Site'), $message);
377 }
378 endif;
379
380 if ( !function_exists('wp_upgrade') ) :
381 /**
382  * Runs WordPress Upgrade functions.
383  *
384  * Upgrades the database if needed during a site update.
385  *
386  * @since 2.1.0
387  *
388  * @return null If no update is necessary or site isn't completely installed, null.
389  */
390 function wp_upgrade() {
391         global $wp_current_db_version, $wp_db_version, $wpdb;
392
393         $wp_current_db_version = __get_option('db_version');
394
395         // We are up-to-date. Nothing to do.
396         if ( $wp_db_version == $wp_current_db_version )
397                 return;
398
399         if ( ! is_blog_installed() )
400                 return;
401
402         wp_check_mysql_version();
403         wp_cache_flush();
404         pre_schema_upgrade();
405         make_db_current_silent();
406         upgrade_all();
407         if ( is_multisite() && is_main_site() )
408                 upgrade_network();
409         wp_cache_flush();
410
411         if ( is_multisite() ) {
412                 if ( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) )
413                         $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" );
414                 else
415                         $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" );
416         }
417
418         /**
419          * Fires after a site is fully upgraded.
420          *
421          * @since 3.9.0
422          *
423          * @param int $wp_db_version         The new $wp_db_version.
424          * @param int $wp_current_db_version The old (current) $wp_db_version.
425          */
426         do_action( 'wp_upgrade', $wp_db_version, $wp_current_db_version );
427 }
428 endif;
429
430 /**
431  * Functions to be called in install and upgrade scripts.
432  *
433  * Contains conditional checks to determine which upgrade scripts to run,
434  * based on database version and WP version being updated-to.
435  *
436  * @since 1.0.1
437  *
438  * @return null If no update is necessary, null.
439  */
440 function upgrade_all() {
441         global $wp_current_db_version, $wp_db_version;
442         $wp_current_db_version = __get_option('db_version');
443
444         // We are up-to-date. Nothing to do.
445         if ( $wp_db_version == $wp_current_db_version )
446                 return;
447
448         // If the version is not set in the DB, try to guess the version.
449         if ( empty($wp_current_db_version) ) {
450                 $wp_current_db_version = 0;
451
452                 // If the template option exists, we have 1.5.
453                 $template = __get_option('template');
454                 if ( !empty($template) )
455                         $wp_current_db_version = 2541;
456         }
457
458         if ( $wp_current_db_version < 6039 )
459                 upgrade_230_options_table();
460
461         populate_options();
462
463         if ( $wp_current_db_version < 2541 ) {
464                 upgrade_100();
465                 upgrade_101();
466                 upgrade_110();
467                 upgrade_130();
468         }
469
470         if ( $wp_current_db_version < 3308 )
471                 upgrade_160();
472
473         if ( $wp_current_db_version < 4772 )
474                 upgrade_210();
475
476         if ( $wp_current_db_version < 4351 )
477                 upgrade_old_slugs();
478
479         if ( $wp_current_db_version < 5539 )
480                 upgrade_230();
481
482         if ( $wp_current_db_version < 6124 )
483                 upgrade_230_old_tables();
484
485         if ( $wp_current_db_version < 7499 )
486                 upgrade_250();
487
488         if ( $wp_current_db_version < 7935 )
489                 upgrade_252();
490
491         if ( $wp_current_db_version < 8201 )
492                 upgrade_260();
493
494         if ( $wp_current_db_version < 8989 )
495                 upgrade_270();
496
497         if ( $wp_current_db_version < 10360 )
498                 upgrade_280();
499
500         if ( $wp_current_db_version < 11958 )
501                 upgrade_290();
502
503         if ( $wp_current_db_version < 15260 )
504                 upgrade_300();
505
506         if ( $wp_current_db_version < 19389 )
507                 upgrade_330();
508
509         if ( $wp_current_db_version < 20080 )
510                 upgrade_340();
511
512         if ( $wp_current_db_version < 22422 )
513                 upgrade_350();
514
515         if ( $wp_current_db_version < 25824 )
516                 upgrade_370();
517
518         if ( $wp_current_db_version < 26148 )
519                 upgrade_372();
520
521         if ( $wp_current_db_version < 26691 )
522                 upgrade_380();
523
524         if ( $wp_current_db_version < 29630 )
525                 upgrade_400();
526
527         // Don't harsh my mellow. upgrade_422() must be called before
528         // upgrade_420() to catch bad comments prior to any auto-expansion of
529         // MySQL column widths.
530         if ( $wp_current_db_version < 31534 )
531                 upgrade_422();
532
533         if ( $wp_current_db_version < 31351 )
534                 upgrade_420();
535
536         maybe_disable_link_manager();
537
538         maybe_disable_automattic_widgets();
539
540         update_option( 'db_version', $wp_db_version );
541         update_option( 'db_upgraded', true );
542 }
543
544 /**
545  * Execute changes made in WordPress 1.0.
546  *
547  * @since 1.0.0
548  */
549 function upgrade_100() {
550         global $wpdb;
551
552         // Get the title and ID of every post, post_name to check if it already has a value
553         $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
554         if ($posts) {
555                 foreach($posts as $post) {
556                         if ('' == $post->post_name) {
557                                 $newtitle = sanitize_title($post->post_title);
558                                 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID) );
559                         }
560                 }
561         }
562
563         $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
564         foreach ($categories as $category) {
565                 if ('' == $category->category_nicename) {
566                         $newtitle = sanitize_title($category->cat_name);
567                         $wpdb->update( $wpdb->categories, array('category_nicename' => $newtitle), array('cat_ID' => $category->cat_ID) );
568                 }
569         }
570
571         $sql = "UPDATE $wpdb->options
572                 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
573                 WHERE option_name LIKE %s
574                 AND option_value LIKE %s";
575         $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) );
576
577         $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
578         if ($done_ids) :
579                 $done_posts = array();
580                 foreach ($done_ids as $done_id) :
581                         $done_posts[] = $done_id->post_id;
582                 endforeach;
583                 $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
584         else:
585                 $catwhere = '';
586         endif;
587
588         $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
589         if ($allposts) :
590                 foreach ($allposts as $post) {
591                         // Check to see if it's already been imported
592                         $cat = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category) );
593                         if (!$cat && 0 != $post->post_category) { // If there's no result
594                                 $wpdb->insert( $wpdb->post2cat, array('post_id' => $post->ID, 'category_id' => $post->post_category) );
595                         }
596                 }
597         endif;
598 }
599
600 /**
601  * Execute changes made in WordPress 1.0.1.
602  *
603  * @since 1.0.1
604  */
605 function upgrade_101() {
606         global $wpdb;
607
608         // Clean up indices, add a few
609         add_clean_index($wpdb->posts, 'post_name');
610         add_clean_index($wpdb->posts, 'post_status');
611         add_clean_index($wpdb->categories, 'category_nicename');
612         add_clean_index($wpdb->comments, 'comment_approved');
613         add_clean_index($wpdb->comments, 'comment_post_ID');
614         add_clean_index($wpdb->links , 'link_category');
615         add_clean_index($wpdb->links , 'link_visible');
616 }
617
618 /**
619  * Execute changes made in WordPress 1.2.
620  *
621  * @since 1.2.0
622  */
623 function upgrade_110() {
624         global $wpdb;
625
626         // Set user_nicename.
627         $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
628         foreach ($users as $user) {
629                 if ('' == $user->user_nicename) {
630                         $newname = sanitize_title($user->user_nickname);
631                         $wpdb->update( $wpdb->users, array('user_nicename' => $newname), array('ID' => $user->ID) );
632                 }
633         }
634
635         $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
636         foreach ($users as $row) {
637                 if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
638                         $wpdb->update( $wpdb->users, array('user_pass' => md5($row->user_pass)), array('ID' => $row->ID) );
639                 }
640         }
641
642         // Get the GMT offset, we'll use that later on
643         $all_options = get_alloptions_110();
644
645         $time_difference = $all_options->time_difference;
646
647                 $server_time = time()+date('Z');
648         $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS;
649         $gmt_time = time();
650
651         $diff_gmt_server = ($gmt_time - $server_time) / HOUR_IN_SECONDS;
652         $diff_weblogger_server = ($weblogger_time - $server_time) / HOUR_IN_SECONDS;
653         $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
654         $gmt_offset = -$diff_gmt_weblogger;
655
656         // Add a gmt_offset option, with value $gmt_offset
657         add_option('gmt_offset', $gmt_offset);
658
659         // Check if we already set the GMT fields (if we did, then
660         // MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
661         // <michel_v> I just slapped myself silly for not thinking about it earlier
662         $got_gmt_fields = ! ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00');
663
664         if (!$got_gmt_fields) {
665
666                 // Add or subtract time to all dates, to get GMT dates
667                 $add_hours = intval($diff_gmt_weblogger);
668                 $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
669                 $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
670                 $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
671                 $wpdb->query("UPDATE $wpdb->posts SET post_modified_gmt = DATE_ADD(post_modified, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE) WHERE post_modified != '0000-00-00 00:00:00'");
672                 $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
673                 $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
674         }
675
676 }
677
678 /**
679  * Execute changes made in WordPress 1.5.
680  *
681  * @since 1.5.0
682  */
683 function upgrade_130() {
684         global $wpdb;
685
686         // Remove extraneous backslashes.
687         $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
688         if ($posts) {
689                 foreach($posts as $post) {
690                         $post_content = addslashes(deslash($post->post_content));
691                         $post_title = addslashes(deslash($post->post_title));
692                         $post_excerpt = addslashes(deslash($post->post_excerpt));
693                         if ( empty($post->guid) )
694                                 $guid = get_permalink($post->ID);
695                         else
696                                 $guid = $post->guid;
697
698                         $wpdb->update( $wpdb->posts, compact('post_title', 'post_content', 'post_excerpt', 'guid'), array('ID' => $post->ID) );
699
700                 }
701         }
702
703         // Remove extraneous backslashes.
704         $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
705         if ($comments) {
706                 foreach($comments as $comment) {
707                         $comment_content = deslash($comment->comment_content);
708                         $comment_author = deslash($comment->comment_author);
709
710                         $wpdb->update($wpdb->comments, compact('comment_content', 'comment_author'), array('comment_ID' => $comment->comment_ID) );
711                 }
712         }
713
714         // Remove extraneous backslashes.
715         $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
716         if ($links) {
717                 foreach($links as $link) {
718                         $link_name = deslash($link->link_name);
719                         $link_description = deslash($link->link_description);
720
721                         $wpdb->update( $wpdb->links, compact('link_name', 'link_description'), array('link_id' => $link->link_id) );
722                 }
723         }
724
725         $active_plugins = __get_option('active_plugins');
726
727         /*
728          * If plugins are not stored in an array, they're stored in the old
729          * newline separated format. Convert to new format.
730          */
731         if ( !is_array( $active_plugins ) ) {
732                 $active_plugins = explode("\n", trim($active_plugins));
733                 update_option('active_plugins', $active_plugins);
734         }
735
736         // Obsolete tables
737         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues');
738         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes');
739         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups');
740         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options');
741
742         // Update comments table to use comment_type
743         $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
744         $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
745
746         // Some versions have multiple duplicate option_name rows with the same values
747         $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
748         foreach ( $options as $option ) {
749                 if ( 1 != $option->dupes ) { // Could this be done in the query?
750                         $limit = $option->dupes - 1;
751                         $dupe_ids = $wpdb->get_col( $wpdb->prepare("SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit) );
752                         if ( $dupe_ids ) {
753                                 $dupe_ids = join($dupe_ids, ',');
754                                 $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
755                         }
756                 }
757         }
758
759         make_site_theme();
760 }
761
762 /**
763  * Execute changes made in WordPress 2.0.
764  *
765  * @since 2.0.0
766  */
767 function upgrade_160() {
768         global $wpdb, $wp_current_db_version;
769
770         populate_roles_160();
771
772         $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
773         foreach ( $users as $user ) :
774                 if ( !empty( $user->user_firstname ) )
775                         update_user_meta( $user->ID, 'first_name', wp_slash($user->user_firstname) );
776                 if ( !empty( $user->user_lastname ) )
777                         update_user_meta( $user->ID, 'last_name', wp_slash($user->user_lastname) );
778                 if ( !empty( $user->user_nickname ) )
779                         update_user_meta( $user->ID, 'nickname', wp_slash($user->user_nickname) );
780                 if ( !empty( $user->user_level ) )
781                         update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level );
782                 if ( !empty( $user->user_icq ) )
783                         update_user_meta( $user->ID, 'icq', wp_slash($user->user_icq) );
784                 if ( !empty( $user->user_aim ) )
785                         update_user_meta( $user->ID, 'aim', wp_slash($user->user_aim) );
786                 if ( !empty( $user->user_msn ) )
787                         update_user_meta( $user->ID, 'msn', wp_slash($user->user_msn) );
788                 if ( !empty( $user->user_yim ) )
789                         update_user_meta( $user->ID, 'yim', wp_slash($user->user_icq) );
790                 if ( !empty( $user->user_description ) )
791                         update_user_meta( $user->ID, 'description', wp_slash($user->user_description) );
792
793                 if ( isset( $user->user_idmode ) ):
794                         $idmode = $user->user_idmode;
795                         if ($idmode == 'nickname') $id = $user->user_nickname;
796                         if ($idmode == 'login') $id = $user->user_login;
797                         if ($idmode == 'firstname') $id = $user->user_firstname;
798                         if ($idmode == 'lastname') $id = $user->user_lastname;
799                         if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
800                         if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
801                         if (!$idmode) $id = $user->user_nickname;
802                         $wpdb->update( $wpdb->users, array('display_name' => $id), array('ID' => $user->ID) );
803                 endif;
804
805                 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
806                 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities');
807                 if ( empty($caps) || defined('RESET_CAPS') ) {
808                         $level = get_user_meta($user->ID, $wpdb->prefix . 'user_level', true);
809                         $role = translate_level_to_role($level);
810                         update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) );
811                 }
812
813         endforeach;
814         $old_user_fields = array( 'user_firstname', 'user_lastname', 'user_icq', 'user_aim', 'user_msn', 'user_yim', 'user_idmode', 'user_ip', 'user_domain', 'user_browser', 'user_description', 'user_nickname', 'user_level' );
815         $wpdb->hide_errors();
816         foreach ( $old_user_fields as $old )
817                 $wpdb->query("ALTER TABLE $wpdb->users DROP $old");
818         $wpdb->show_errors();
819
820         // Populate comment_count field of posts table.
821         $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
822         if ( is_array( $comments ) )
823                 foreach ($comments as $comment)
824                         $wpdb->update( $wpdb->posts, array('comment_count' => $comment->c), array('ID' => $comment->comment_post_ID) );
825
826         /*
827          * Some alpha versions used a post status of object instead of attachment
828          * and put the mime type in post_type instead of post_mime_type.
829          */
830         if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
831                 $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
832                 foreach ($objects as $object) {
833                         $wpdb->update( $wpdb->posts, array(     'post_status' => 'attachment',
834                                                                                                 'post_mime_type' => $object->post_type,
835                                                                                                 'post_type' => ''),
836                                                                                  array( 'ID' => $object->ID ) );
837
838                         $meta = get_post_meta($object->ID, 'imagedata', true);
839                         if ( ! empty($meta['file']) )
840                                 update_attached_file( $object->ID, $meta['file'] );
841                 }
842         }
843 }
844
845 /**
846  * Execute changes made in WordPress 2.1.
847  *
848  * @since 2.1.0
849  */
850 function upgrade_210() {
851         global $wpdb, $wp_current_db_version;
852
853         if ( $wp_current_db_version < 3506 ) {
854                 // Update status and type.
855                 $posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts");
856
857                 if ( ! empty($posts) ) foreach ($posts as $post) {
858                         $status = $post->post_status;
859                         $type = 'post';
860
861                         if ( 'static' == $status ) {
862                                 $status = 'publish';
863                                 $type = 'page';
864                         } elseif ( 'attachment' == $status ) {
865                                 $status = 'inherit';
866                                 $type = 'attachment';
867                         }
868
869                         $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID) );
870                 }
871         }
872
873         if ( $wp_current_db_version < 3845 ) {
874                 populate_roles_210();
875         }
876
877         if ( $wp_current_db_version < 3531 ) {
878                 // Give future posts a post_status of future.
879                 $now = gmdate('Y-m-d H:i:59');
880                 $wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'");
881
882                 $posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'");
883                 if ( !empty($posts) )
884                         foreach ( $posts as $post )
885                                 wp_schedule_single_event(mysql2date('U', $post->post_date, false), 'publish_future_post', array($post->ID));
886         }
887 }
888
889 /**
890  * Execute changes made in WordPress 2.3.
891  *
892  * @since 2.3.0
893  */
894 function upgrade_230() {
895         global $wp_current_db_version, $wpdb;
896
897         if ( $wp_current_db_version < 5200 ) {
898                 populate_roles_230();
899         }
900
901         // Convert categories to terms.
902         $tt_ids = array();
903         $have_tags = false;
904         $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID");
905         foreach ($categories as $category) {
906                 $term_id = (int) $category->cat_ID;
907                 $name = $category->cat_name;
908                 $description = $category->category_description;
909                 $slug = $category->category_nicename;
910                 $parent = $category->category_parent;
911                 $term_group = 0;
912
913                 // Associate terms with the same slug in a term group and make slugs unique.
914                 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
915                         $term_group = $exists[0]->term_group;
916                         $id = $exists[0]->term_id;
917                         $num = 2;
918                         do {
919                                 $alt_slug = $slug . "-$num";
920                                 $num++;
921                                 $slug_check = $wpdb->get_var( $wpdb->prepare("SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug) );
922                         } while ( $slug_check );
923
924                         $slug = $alt_slug;
925
926                         if ( empty( $term_group ) ) {
927                                 $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
928                                 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id) );
929                         }
930                 }
931
932                 $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES
933                 (%d, %s, %s, %d)", $term_id, $name, $slug, $term_group) );
934
935                 $count = 0;
936                 if ( !empty($category->category_count) ) {
937                         $count = (int) $category->category_count;
938                         $taxonomy = 'category';
939                         $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, $count) );
940                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
941                 }
942
943                 if ( !empty($category->link_count) ) {
944                         $count = (int) $category->link_count;
945                         $taxonomy = 'link_category';
946                         $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, $count) );
947                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
948                 }
949
950                 if ( !empty($category->tag_count) ) {
951                         $have_tags = true;
952                         $count = (int) $category->tag_count;
953                         $taxonomy = 'post_tag';
954                         $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
955                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
956                 }
957
958                 if ( empty($count) ) {
959                         $count = 0;
960                         $taxonomy = 'category';
961                         $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
962                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
963                 }
964         }
965
966         $select = 'post_id, category_id';
967         if ( $have_tags )
968                 $select .= ', rel_type';
969
970         $posts = $wpdb->get_results("SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id");
971         foreach ( $posts as $post ) {
972                 $post_id = (int) $post->post_id;
973                 $term_id = (int) $post->category_id;
974                 $taxonomy = 'category';
975                 if ( !empty($post->rel_type) && 'tag' == $post->rel_type)
976                         $taxonomy = 'tag';
977                 $tt_id = $tt_ids[$term_id][$taxonomy];
978                 if ( empty($tt_id) )
979                         continue;
980
981                 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $post_id, 'term_taxonomy_id' => $tt_id) );
982         }
983
984         // < 3570 we used linkcategories. >= 3570 we used categories and link2cat.
985         if ( $wp_current_db_version < 3570 ) {
986                 /*
987                  * Create link_category terms for link categories. Create a map of link
988                  * cat IDs to link_category terms.
989                  */
990                 $link_cat_id_map = array();
991                 $default_link_cat = 0;
992                 $tt_ids = array();
993                 $link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories');
994                 foreach ( $link_cats as $category) {
995                         $cat_id = (int) $category->cat_id;
996                         $term_id = 0;
997                         $name = wp_slash($category->cat_name);
998                         $slug = sanitize_title($name);
999                         $term_group = 0;
1000
1001                         // Associate terms with the same slug in a term group and make slugs unique.
1002                         if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
1003                                 $term_group = $exists[0]->term_group;
1004                                 $term_id = $exists[0]->term_id;
1005                         }
1006
1007                         if ( empty($term_id) ) {
1008                                 $wpdb->insert( $wpdb->terms, compact('name', 'slug', 'term_group') );
1009                                 $term_id = (int) $wpdb->insert_id;
1010                         }
1011
1012                         $link_cat_id_map[$cat_id] = $term_id;
1013                         $default_link_cat = $term_id;
1014
1015                         $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $term_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 0) );
1016                         $tt_ids[$term_id] = (int) $wpdb->insert_id;
1017                 }
1018
1019                 // Associate links to cats.
1020                 $links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links");
1021                 if ( !empty($links) ) foreach ( $links as $link ) {
1022                         if ( 0 == $link->link_category )
1023                                 continue;
1024                         if ( ! isset($link_cat_id_map[$link->link_category]) )
1025                                 continue;
1026                         $term_id = $link_cat_id_map[$link->link_category];
1027                         $tt_id = $tt_ids[$term_id];
1028                         if ( empty($tt_id) )
1029                                 continue;
1030
1031                         $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link->link_id, 'term_taxonomy_id' => $tt_id) );
1032                 }
1033
1034                 // Set default to the last category we grabbed during the upgrade loop.
1035                 update_option('default_link_category', $default_link_cat);
1036         } else {
1037                 $links = $wpdb->get_results("SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id");
1038                 foreach ( $links as $link ) {
1039                         $link_id = (int) $link->link_id;
1040                         $term_id = (int) $link->category_id;
1041                         $taxonomy = 'link_category';
1042                         $tt_id = $tt_ids[$term_id][$taxonomy];
1043                         if ( empty($tt_id) )
1044                                 continue;
1045                         $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link_id, 'term_taxonomy_id' => $tt_id) );
1046                 }
1047         }
1048
1049         if ( $wp_current_db_version < 4772 ) {
1050                 // Obsolete linkcategories table
1051                 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories');
1052         }
1053
1054         // Recalculate all counts
1055         $terms = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy");
1056         foreach ( (array) $terms as $term ) {
1057                 if ( ('post_tag' == $term->taxonomy) || ('category' == $term->taxonomy) )
1058                         $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = 'post' AND term_taxonomy_id = %d", $term->term_taxonomy_id) );
1059                 else
1060                         $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id) );
1061                 $wpdb->update( $wpdb->term_taxonomy, array('count' => $count), array('term_taxonomy_id' => $term->term_taxonomy_id) );
1062         }
1063 }
1064
1065 /**
1066  * Remove old options from the database.
1067  *
1068  * @since 2.3.0
1069  */
1070 function upgrade_230_options_table() {
1071         global $wpdb;
1072         $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' );
1073         $wpdb->hide_errors();
1074         foreach ( $old_options_fields as $old )
1075                 $wpdb->query("ALTER TABLE $wpdb->options DROP $old");
1076         $wpdb->show_errors();
1077 }
1078
1079 /**
1080  * Remove old categories, link2cat, and post2cat database tables.
1081  *
1082  * @since 2.3.0
1083  */
1084 function upgrade_230_old_tables() {
1085         global $wpdb;
1086         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories');
1087         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat');
1088         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat');
1089 }
1090
1091 /**
1092  * Upgrade old slugs made in version 2.2.
1093  *
1094  * @since 2.2.0
1095  */
1096 function upgrade_old_slugs() {
1097         // Upgrade people who were using the Redirect Old Slugs plugin.
1098         global $wpdb;
1099         $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'");
1100 }
1101
1102 /**
1103  * Execute changes made in WordPress 2.5.0.
1104  *
1105  * @since 2.5.0
1106  */
1107 function upgrade_250() {
1108         global $wp_current_db_version;
1109
1110         if ( $wp_current_db_version < 6689 ) {
1111                 populate_roles_250();
1112         }
1113
1114 }
1115
1116 /**
1117  * Execute changes made in WordPress 2.5.2.
1118  *
1119  * @since 2.5.2
1120  */
1121 function upgrade_252() {
1122         global $wpdb;
1123
1124         $wpdb->query("UPDATE $wpdb->users SET user_activation_key = ''");
1125 }
1126
1127 /**
1128  * Execute changes made in WordPress 2.6.
1129  *
1130  * @since 2.6.0
1131  */
1132 function upgrade_260() {
1133         global $wp_current_db_version;
1134
1135         if ( $wp_current_db_version < 8000 )
1136                 populate_roles_260();
1137 }
1138
1139 /**
1140  * Execute changes made in WordPress 2.7.
1141  *
1142  * @since 2.7.0
1143  */
1144 function upgrade_270() {
1145         global $wpdb, $wp_current_db_version;
1146
1147         if ( $wp_current_db_version < 8980 )
1148                 populate_roles_270();
1149
1150         // Update post_date for unpublished posts with empty timestamp
1151         if ( $wp_current_db_version < 8921 )
1152                 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" );
1153 }
1154
1155 /**
1156  * Execute changes made in WordPress 2.8.
1157  *
1158  * @since 2.8.0
1159  */
1160 function upgrade_280() {
1161         global $wp_current_db_version, $wpdb;
1162
1163         if ( $wp_current_db_version < 10360 )
1164                 populate_roles_280();
1165         if ( is_multisite() ) {
1166                 $start = 0;
1167                 while( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) {
1168                         foreach( $rows as $row ) {
1169                                 $value = $row->option_value;
1170                                 if ( !@unserialize( $value ) )
1171                                         $value = stripslashes( $value );
1172                                 if ( $value !== $row->option_value ) {
1173                                         update_option( $row->option_name, $value );
1174                                 }
1175                         }
1176                         $start += 20;
1177                 }
1178                 refresh_blog_details( $wpdb->blogid );
1179         }
1180 }
1181
1182 /**
1183  * Execute changes made in WordPress 2.9.
1184  *
1185  * @since 2.9.0
1186  */
1187 function upgrade_290() {
1188         global $wp_current_db_version;
1189
1190         if ( $wp_current_db_version < 11958 ) {
1191                 // Previously, setting depth to 1 would redundantly disable threading, but now 2 is the minimum depth to avoid confusion
1192                 if ( get_option( 'thread_comments_depth' ) == '1' ) {
1193                         update_option( 'thread_comments_depth', 2 );
1194                         update_option( 'thread_comments', 0 );
1195                 }
1196         }
1197 }
1198
1199 /**
1200  * Execute changes made in WordPress 3.0.
1201  *
1202  * @since 3.0.0
1203  */
1204 function upgrade_300() {
1205         global $wp_current_db_version, $wpdb;
1206
1207         if ( $wp_current_db_version < 15093 )
1208                 populate_roles_300();
1209
1210         if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false )
1211                 add_site_option( 'siteurl', '' );
1212
1213         // 3.0 screen options key name changes.
1214         if ( is_main_site() && !defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
1215                 $sql = "DELETE FROM $wpdb->usermeta
1216                         WHERE meta_key LIKE %s
1217                         OR meta_key LIKE %s
1218                         OR meta_key LIKE %s
1219                         OR meta_key LIKE %s
1220                         OR meta_key LIKE %s
1221                         OR meta_key LIKE %s
1222                         OR meta_key = 'manageedittagscolumnshidden'
1223                         OR meta_key = 'managecategoriescolumnshidden'
1224                         OR meta_key = 'manageedit-tagscolumnshidden'
1225                         OR meta_key = 'manageeditcolumnshidden'
1226                         OR meta_key = 'categories_per_page'
1227                         OR meta_key = 'edit_tags_per_page'";
1228                 $prefix = $wpdb->esc_like( $wpdb->base_prefix );
1229                 $wpdb->query( $wpdb->prepare( $sql,
1230                         $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%',
1231                         $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%',
1232                         $prefix . '%' . $wpdb->esc_like( 'manage-'         ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%',
1233                         $prefix . '%' . $wpdb->esc_like( 'meta-box-order'  ) . '%',
1234                         $prefix . '%' . $wpdb->esc_like( 'metaboxorder'    ) . '%',
1235                         $prefix . '%' . $wpdb->esc_like( 'screen_layout'   ) . '%'
1236                 ) );
1237         }
1238
1239 }
1240
1241 /**
1242  * Execute changes made in WordPress 3.3.
1243  *
1244  * @since 3.3.0
1245  */
1246 function upgrade_330() {
1247         global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets;
1248
1249         if ( $wp_current_db_version < 19061 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1250                 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" );
1251         }
1252
1253         if ( $wp_current_db_version >= 11548 )
1254                 return;
1255
1256         $sidebars_widgets = get_option( 'sidebars_widgets', array() );
1257         $_sidebars_widgets = array();
1258
1259         if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) )
1260                 $sidebars_widgets['array_version'] = 3;
1261         elseif ( !isset($sidebars_widgets['array_version']) )
1262                 $sidebars_widgets['array_version'] = 1;
1263
1264         switch ( $sidebars_widgets['array_version'] ) {
1265                 case 1 :
1266                         foreach ( (array) $sidebars_widgets as $index => $sidebar )
1267                         if ( is_array($sidebar) )
1268                         foreach ( (array) $sidebar as $i => $name ) {
1269                                 $id = strtolower($name);
1270                                 if ( isset($wp_registered_widgets[$id]) ) {
1271                                         $_sidebars_widgets[$index][$i] = $id;
1272                                         continue;
1273                                 }
1274                                 $id = sanitize_title($name);
1275                                 if ( isset($wp_registered_widgets[$id]) ) {
1276                                         $_sidebars_widgets[$index][$i] = $id;
1277                                         continue;
1278                                 }
1279
1280                                 $found = false;
1281
1282                                 foreach ( $wp_registered_widgets as $widget_id => $widget ) {
1283                                         if ( strtolower($widget['name']) == strtolower($name) ) {
1284                                                 $_sidebars_widgets[$index][$i] = $widget['id'];
1285                                                 $found = true;
1286                                                 break;
1287                                         } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) {
1288                                                 $_sidebars_widgets[$index][$i] = $widget['id'];
1289                                                 $found = true;
1290                                                 break;
1291                                         }
1292                                 }
1293
1294                                 if ( $found )
1295                                         continue;
1296
1297                                 unset($_sidebars_widgets[$index][$i]);
1298                         }
1299                         $_sidebars_widgets['array_version'] = 2;
1300                         $sidebars_widgets = $_sidebars_widgets;
1301                         unset($_sidebars_widgets);
1302
1303                 case 2 :
1304                         $sidebars_widgets = retrieve_widgets();
1305                         $sidebars_widgets['array_version'] = 3;
1306                         update_option( 'sidebars_widgets', $sidebars_widgets );
1307         }
1308 }
1309
1310 /**
1311  * Execute changes made in WordPress 3.4.
1312  *
1313  * @since 3.4.0
1314  */
1315 function upgrade_340() {
1316         global $wp_current_db_version, $wpdb;
1317
1318         if ( $wp_current_db_version < 19798 ) {
1319                 $wpdb->hide_errors();
1320                 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" );
1321                 $wpdb->show_errors();
1322         }
1323
1324         if ( $wp_current_db_version < 19799 ) {
1325                 $wpdb->hide_errors();
1326                 $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved");
1327                 $wpdb->show_errors();
1328         }
1329
1330         if ( $wp_current_db_version < 20022 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1331                 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" );
1332         }
1333
1334         if ( $wp_current_db_version < 20080 ) {
1335                 if ( 'yes' == $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) {
1336                         $uninstall_plugins = get_option( 'uninstall_plugins' );
1337                         delete_option( 'uninstall_plugins' );
1338                         add_option( 'uninstall_plugins', $uninstall_plugins, null, 'no' );
1339                 }
1340         }
1341 }
1342
1343 /**
1344  * Execute changes made in WordPress 3.5.
1345  *
1346  * @since 3.5.0
1347  */
1348 function upgrade_350() {
1349         global $wp_current_db_version, $wpdb;
1350
1351         if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
1352                 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options()
1353
1354         if ( $wp_current_db_version < 21811 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1355                 $meta_keys = array();
1356                 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) {
1357                         if ( false !== strpos( $name, '-' ) )
1358                         $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page';
1359                 }
1360                 if ( $meta_keys ) {
1361                         $meta_keys = implode( "', '", $meta_keys );
1362                         $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" );
1363                 }
1364         }
1365
1366         if ( $wp_current_db_version < 22422 && $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ) )
1367                 wp_delete_term( $term->term_id, 'post_format' );
1368 }
1369
1370 /**
1371  * Execute changes made in WordPress 3.7.
1372  *
1373  * @since 3.7.0
1374  */
1375 function upgrade_370() {
1376         global $wp_current_db_version;
1377         if ( $wp_current_db_version < 25824 )
1378                 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' );
1379 }
1380
1381 /**
1382  * Execute changes made in WordPress 3.7.2.
1383  *
1384  * @since 3.7.2
1385  * @since 3.8.0
1386  */
1387 function upgrade_372() {
1388         global $wp_current_db_version;
1389         if ( $wp_current_db_version < 26148 )
1390                 wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
1391 }
1392
1393 /**
1394  * Execute changes made in WordPress 3.8.0.
1395  *
1396  * @since 3.8.0
1397  */
1398 function upgrade_380() {
1399         global $wp_current_db_version;
1400         if ( $wp_current_db_version < 26691 ) {
1401                 deactivate_plugins( array( 'mp6/mp6.php' ), true );
1402         }
1403 }
1404
1405 /**
1406  * Execute changes made in WordPress 4.0.0.
1407  *
1408  * @since 4.0.0
1409  */
1410 function upgrade_400() {
1411         global $wp_current_db_version;
1412         if ( $wp_current_db_version < 29630 ) {
1413                 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) {
1414                         if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages() ) ) {
1415                                 update_option( 'WPLANG', WPLANG );
1416                         } else {
1417                                 update_option( 'WPLANG', '' );
1418                         }
1419                 }
1420         }
1421 }
1422
1423 /**
1424  * Execute changes made in WordPress 4.2.0.
1425  *
1426  * @since 4.2.0
1427  */
1428 function upgrade_420() {
1429         global $wp_current_db_version, $wpdb;
1430
1431         if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1432                 if ( is_multisite() ) {
1433                         $tables = $wpdb->tables( 'blog' );
1434                 } else {
1435                         $tables = $wpdb->tables( 'all' );
1436                 }
1437
1438                 foreach ( $tables as $table ) {
1439                         maybe_convert_table_to_utf8mb4( $table );
1440                 }
1441         }
1442 }
1443
1444 /**
1445  * Execute changes made in WordPress 4.2.1.
1446  *
1447  * @since 4.2.1
1448  */
1449 function upgrade_421() {
1450 }
1451
1452 /**
1453  * Execute changes made in WordPress 4.2.2.
1454  *
1455  * @since 4.2.2
1456  */
1457 function upgrade_422() {
1458         global $wp_current_db_version, $wpdb;
1459
1460         if ( $wp_current_db_version < 31534 ) {
1461                 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' );
1462
1463                 if ( is_wp_error( $content_length ) ) {
1464                         return;
1465                 }
1466
1467                 if ( false === $content_length ) {
1468                         $content_length = array(
1469                                 'type'   => 'byte',
1470                                 'length' => 65535,
1471                         );
1472                 } elseif ( ! is_array( $content_length ) ) {
1473                         $length = (int) $content_length > 0 ? (int) $content_length : 65535;
1474                         $content_length = array(
1475                                 'type'   => 'byte',
1476                                 'length' => $length
1477                         );
1478                 }
1479
1480                 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) {
1481                         // Sites with malformed DB schemas are on their own.
1482                         return;
1483                 }
1484
1485                 $allowed_length = intval( $content_length['length'] ) - 10;
1486
1487                 $comments = $wpdb->get_results(
1488                         "SELECT `comment_ID` FROM `{$wpdb->comments}`
1489                                 WHERE `comment_date_gmt` > '2015-04-26'
1490                                 AND LENGTH( `comment_content` ) >= {$allowed_length}
1491                                 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )"
1492                 );
1493
1494                 foreach ( $comments as $comment ) {
1495                         wp_delete_comment( $comment->comment_ID, true );
1496                 }
1497         }
1498 }
1499
1500 /**
1501  * Executes network-level upgrade routines.
1502  *
1503  * @since 3.0.0
1504  */
1505 function upgrade_network() {
1506         global $wp_current_db_version, $wpdb;
1507
1508         // Always.
1509         if ( is_main_network() ) {
1510                 /*
1511                  * Deletes all expired transients. The multi-table delete syntax is used
1512                  * to delete the transient record from table a, and the corresponding
1513                  * transient_timeout record from table b.
1514                  */
1515                 $time = time();
1516                 $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
1517                         WHERE a.meta_key LIKE %s
1518                         AND a.meta_key NOT LIKE %s
1519                         AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1520                         AND b.meta_value < %d";
1521                 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
1522         }
1523
1524         // 2.8.
1525         if ( $wp_current_db_version < 11549 ) {
1526                 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' );
1527                 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' );
1528                 if ( $wpmu_sitewide_plugins ) {
1529                         if ( !$active_sitewide_plugins )
1530                                 $sitewide_plugins = (array) $wpmu_sitewide_plugins;
1531                         else
1532                                 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins );
1533
1534                         update_site_option( 'active_sitewide_plugins', $sitewide_plugins );
1535                 }
1536                 delete_site_option( 'wpmu_sitewide_plugins' );
1537                 delete_site_option( 'deactivated_sitewide_plugins' );
1538
1539                 $start = 0;
1540                 while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) {
1541                         foreach( $rows as $row ) {
1542                                 $value = $row->meta_value;
1543                                 if ( !@unserialize( $value ) )
1544                                         $value = stripslashes( $value );
1545                                 if ( $value !== $row->meta_value ) {
1546                                         update_site_option( $row->meta_key, $value );
1547                                 }
1548                         }
1549                         $start += 20;
1550                 }
1551         }
1552
1553         // 3.0
1554         if ( $wp_current_db_version < 13576 )
1555                 update_site_option( 'global_terms_enabled', '1' );
1556
1557         // 3.3
1558         if ( $wp_current_db_version < 19390 )
1559                 update_site_option( 'initial_db_version', $wp_current_db_version );
1560
1561         if ( $wp_current_db_version < 19470 ) {
1562                 if ( false === get_site_option( 'active_sitewide_plugins' ) )
1563                         update_site_option( 'active_sitewide_plugins', array() );
1564         }
1565
1566         // 3.4
1567         if ( $wp_current_db_version < 20148 ) {
1568                 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name.
1569                 $allowedthemes  = get_site_option( 'allowedthemes'  );
1570                 $allowed_themes = get_site_option( 'allowed_themes' );
1571                 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) {
1572                         $converted = array();
1573                         $themes = wp_get_themes();
1574                         foreach ( $themes as $stylesheet => $theme_data ) {
1575                                 if ( isset( $allowed_themes[ $theme_data->get('Name') ] ) )
1576                                         $converted[ $stylesheet ] = true;
1577                         }
1578                         update_site_option( 'allowedthemes', $converted );
1579                         delete_site_option( 'allowed_themes' );
1580                 }
1581         }
1582
1583         // 3.5
1584         if ( $wp_current_db_version < 21823 )
1585                 update_site_option( 'ms_files_rewriting', '1' );
1586
1587         // 3.5.2
1588         if ( $wp_current_db_version < 24448 ) {
1589                 $illegal_names = get_site_option( 'illegal_names' );
1590                 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) {
1591                         $illegal_name = reset( $illegal_names );
1592                         $illegal_names = explode( ' ', $illegal_name );
1593                         update_site_option( 'illegal_names', $illegal_names );
1594                 }
1595         }
1596
1597         // 4.2
1598         if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1599                 if ( ! ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && DO_NOT_UPGRADE_GLOBAL_TABLES ) ) {
1600                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1601                         $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1602                         $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1603                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1604
1605                         $tables = $wpdb->tables( 'global' );
1606
1607                         foreach ( $tables as $table ) {
1608                                 maybe_convert_table_to_utf8mb4( $table );
1609                         }
1610                 }
1611         }
1612
1613         // 4.2.2
1614         if ( $wp_current_db_version < 31535 && 'utf8mb4' === $wpdb->charset ) {
1615                 if ( ! ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && DO_NOT_UPGRADE_GLOBAL_TABLES ) ) {
1616                         $upgrade = false;
1617                         $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" );
1618                         foreach( $indexes as $index ) {
1619                                 if ( 'domain_path' == $index->Key_name && 'domain' == $index->Column_name && 140 != $index->Sub_part ) {
1620                                         $upgrade = true;
1621                                         break;
1622                                 }
1623                         }
1624
1625                         if ( $upgrade ) {
1626                                 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1627                         }
1628                 }
1629         }
1630 }
1631
1632 //
1633 // General functions we use to actually do stuff
1634 //
1635
1636 /**
1637  * Creates a table in the database if it doesn't already exist.
1638  *
1639  * This method checks for an existing database and creates a new one if it's not
1640  * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses
1641  * to query all tables first and then run the SQL statement creating the table.
1642  *
1643  * @since 1.0.0
1644  *
1645  * @param string $table_name Database table name to create.
1646  * @param string $create_ddl SQL statement to create table.
1647  * @return bool If table already exists or was created by function.
1648  */
1649 function maybe_create_table($table_name, $create_ddl) {
1650         global $wpdb;
1651
1652         $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
1653
1654         if ( $wpdb->get_var( $query ) == $table_name ) {
1655                 return true;
1656         }
1657
1658         // Didn't find it try to create it..
1659         $wpdb->query($create_ddl);
1660
1661         // We cannot directly tell that whether this succeeded!
1662         if ( $wpdb->get_var( $query ) == $table_name ) {
1663                 return true;
1664         }
1665         return false;
1666 }
1667
1668 /**
1669  * Drops a specified index from a table.
1670  *
1671  * @since 1.0.1
1672  *
1673  * @param string $table Database table name.
1674  * @param string $index Index name to drop.
1675  * @return bool True, when finished.
1676  */
1677 function drop_index($table, $index) {
1678         global $wpdb;
1679         $wpdb->hide_errors();
1680         $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
1681         // Now we need to take out all the extra ones we may have created
1682         for ($i = 0; $i < 25; $i++) {
1683                 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
1684         }
1685         $wpdb->show_errors();
1686         return true;
1687 }
1688
1689 /**
1690  * Adds an index to a specified table.
1691  *
1692  * @since 1.0.1
1693  *
1694  * @param string $table Database table name.
1695  * @param string $index Database table index column.
1696  * @return bool True, when done with execution.
1697  */
1698 function add_clean_index($table, $index) {
1699         global $wpdb;
1700         drop_index($table, $index);
1701         $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
1702         return true;
1703 }
1704
1705 /**
1706  * Adds column to a database table if it doesn't already exist.
1707  *
1708  * @since 1.3.0
1709  *
1710  * @param string $table_name  The table name to modify.
1711  * @param string $column_name The column name to add to the table.
1712  * @param string $create_ddl  The SQL statement used to add the column.
1713  * @return True if already exists or on successful completion, false on error.
1714  */
1715 function maybe_add_column($table_name, $column_name, $create_ddl) {
1716         global $wpdb;
1717         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1718                 if ($column == $column_name) {
1719                         return true;
1720                 }
1721         }
1722
1723         // Didn't find it try to create it.
1724         $wpdb->query($create_ddl);
1725
1726         // We cannot directly tell that whether this succeeded!
1727         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1728                 if ($column == $column_name) {
1729                         return true;
1730                 }
1731         }
1732         return false;
1733 }
1734
1735 /**
1736  * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4.
1737  *
1738  * @since 4.2.0
1739  *
1740  * @param string $table The table to convert.
1741  * @return bool true if the table was converted, false if it wasn't.
1742  */
1743 function maybe_convert_table_to_utf8mb4( $table ) {
1744         global $wpdb;
1745
1746         $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" );
1747         if ( ! $results ) {
1748                 return false;
1749         }
1750
1751         foreach ( $results as $column ) {
1752                 if ( $column->Collation ) {
1753                         list( $charset ) = explode( '_', $column->Collation );
1754                         $charset = strtolower( $charset );
1755                         if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) {
1756                                 // Don't upgrade tables that have non-utf8 columns.
1757                                 return false;
1758                         }
1759                 }
1760         }
1761
1762         return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
1763 }
1764
1765 /**
1766  * Retrieve all options as it was for 1.2.
1767  *
1768  * @since 1.2.0
1769  *
1770  * @return stdClass List of options.
1771  */
1772 function get_alloptions_110() {
1773         global $wpdb;
1774         $all_options = new stdClass;
1775         if ( $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ) ) {
1776                 foreach ( $options as $option ) {
1777                         if ( 'siteurl' == $option->option_name || 'home' == $option->option_name || 'category_base' == $option->option_name )
1778                                 $option->option_value = untrailingslashit( $option->option_value );
1779                         $all_options->{$option->option_name} = stripslashes( $option->option_value );
1780                 }
1781         }
1782         return $all_options;
1783 }
1784
1785 /**
1786  * Utility version of get_option that is private to install/upgrade.
1787  *
1788  * @ignore
1789  * @since 1.5.1
1790  * @access private
1791  *
1792  * @param string $setting Option name.
1793  * @return mixed
1794  */
1795 function __get_option($setting) {
1796         global $wpdb;
1797
1798         if ( $setting == 'home' && defined( 'WP_HOME' ) )
1799                 return untrailingslashit( WP_HOME );
1800
1801         if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) )
1802                 return untrailingslashit( WP_SITEURL );
1803
1804         $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) );
1805
1806         if ( 'home' == $setting && '' == $option )
1807                 return __get_option( 'siteurl' );
1808
1809         if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting || 'tag_base' == $setting )
1810                 $option = untrailingslashit( $option );
1811
1812         return maybe_unserialize( $option );
1813 }
1814
1815 /**
1816  * Filters for content to remove unnecessary slashes.
1817  *
1818  * @since 1.5.0
1819  *
1820  * @param string $content The content to modify.
1821  * @return string The de-slashed content.
1822  */
1823 function deslash($content) {
1824         // Note: \\\ inside a regex denotes a single backslash.
1825
1826         /*
1827          * Replace one or more backslashes followed by a single quote with
1828          * a single quote.
1829          */
1830         $content = preg_replace("/\\\+'/", "'", $content);
1831
1832         /*
1833          * Replace one or more backslashes followed by a double quote with
1834          * a double quote.
1835          */
1836         $content = preg_replace('/\\\+"/', '"', $content);
1837
1838         // Replace one or more backslashes with one backslash.
1839         $content = preg_replace("/\\\+/", "\\", $content);
1840
1841         return $content;
1842 }
1843
1844 /**
1845  * Modifies the database based on specified SQL statements.
1846  *
1847  * Useful for creating new tables and updating existing tables to a new structure.
1848  *
1849  * @since 1.5.0
1850  *
1851  * @param string|array $queries Optional. The query to run. Can be multiple queries
1852  *                              in an array, or a string of queries separated by
1853  *                              semicolons. Default empty.
1854  * @param bool         $execute Optional. Whether or not to execute the query right away.
1855  *                              Default true.
1856  * @return array Strings containing the results of the various update queries.
1857  */
1858 function dbDelta( $queries = '', $execute = true ) {
1859         global $wpdb;
1860
1861         if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) )
1862             $queries = wp_get_db_schema( $queries );
1863
1864         // Separate individual queries into an array
1865         if ( !is_array($queries) ) {
1866                 $queries = explode( ';', $queries );
1867                 $queries = array_filter( $queries );
1868         }
1869
1870         /**
1871          * Filter the dbDelta SQL queries.
1872          *
1873          * @since 3.3.0
1874          *
1875          * @param array $queries An array of dbDelta SQL queries.
1876          */
1877         $queries = apply_filters( 'dbdelta_queries', $queries );
1878
1879         $cqueries = array(); // Creation Queries
1880         $iqueries = array(); // Insertion Queries
1881         $for_update = array();
1882
1883         // Create a tablename index for an array ($cqueries) of queries
1884         foreach($queries as $qry) {
1885                 if ( preg_match( "|CREATE TABLE ([^ ]*)|", $qry, $matches ) ) {
1886                         $cqueries[ trim( $matches[1], '`' ) ] = $qry;
1887                         $for_update[$matches[1]] = 'Created table '.$matches[1];
1888                 } elseif ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
1889                         array_unshift( $cqueries, $qry );
1890                 } elseif ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
1891                         $iqueries[] = $qry;
1892                 } elseif ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
1893                         $iqueries[] = $qry;
1894                 } else {
1895                         // Unrecognized query type
1896                 }
1897         }
1898
1899         /**
1900          * Filter the dbDelta SQL queries for creating tables and/or databases.
1901          *
1902          * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE".
1903          *
1904          * @since 3.3.0
1905          *
1906          * @param array $cqueries An array of dbDelta create SQL queries.
1907          */
1908         $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries );
1909
1910         /**
1911          * Filter the dbDelta SQL queries for inserting or updating.
1912          *
1913          * Queries filterable via this hook contain "INSERT INTO" or "UPDATE".
1914          *
1915          * @since 3.3.0
1916          *
1917          * @param array $iqueries An array of dbDelta insert or update SQL queries.
1918          */
1919         $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries );
1920
1921         $global_tables = $wpdb->tables( 'global' );
1922         foreach ( $cqueries as $table => $qry ) {
1923                 // Upgrade global tables only for the main site. Don't upgrade at all if DO_NOT_UPGRADE_GLOBAL_TABLES is defined.
1924                 if ( in_array( $table, $global_tables ) && ( !is_main_site() || defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) ) {
1925                         unset( $cqueries[ $table ], $for_update[ $table ] );
1926                         continue;
1927                 }
1928
1929                 // Fetch the table column structure from the database
1930                 $suppress = $wpdb->suppress_errors();
1931                 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
1932                 $wpdb->suppress_errors( $suppress );
1933
1934                 if ( ! $tablefields )
1935                         continue;
1936
1937                 // Clear the field and index arrays.
1938                 $cfields = $indices = array();
1939
1940                 // Get all of the field names in the query from between the parentheses.
1941                 preg_match("|\((.*)\)|ms", $qry, $match2);
1942                 $qryline = trim($match2[1]);
1943
1944                 // Separate field lines into an array.
1945                 $flds = explode("\n", $qryline);
1946
1947                 // todo: Remove this?
1948                 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
1949
1950                 // For every field line specified in the query.
1951                 foreach ($flds as $fld) {
1952
1953                         // Extract the field name.
1954                         preg_match("|^([^ ]*)|", trim($fld), $fvals);
1955                         $fieldname = trim( $fvals[1], '`' );
1956
1957                         // Verify the found field name.
1958                         $validfield = true;
1959                         switch (strtolower($fieldname)) {
1960                         case '':
1961                         case 'primary':
1962                         case 'index':
1963                         case 'fulltext':
1964                         case 'unique':
1965                         case 'key':
1966                                 $validfield = false;
1967                                 $indices[] = trim(trim($fld), ", \n");
1968                                 break;
1969                         }
1970                         $fld = trim($fld);
1971
1972                         // If it's a valid field, add it to the field array.
1973                         if ($validfield) {
1974                                 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
1975                         }
1976                 }
1977
1978                 // For every field in the table.
1979                 foreach ($tablefields as $tablefield) {
1980
1981                         // If the table field exists in the field array ...
1982                         if (array_key_exists(strtolower($tablefield->Field), $cfields)) {
1983
1984                                 // Get the field type from the query.
1985                                 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
1986                                 $fieldtype = $matches[1];
1987
1988                                 // Is actual field type different from the field type in query?
1989                                 if ($tablefield->Type != $fieldtype) {
1990                                         // Add a query to change the column type
1991                                         $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
1992                                         $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
1993                                 }
1994
1995                                 // Get the default value from the array
1996                                         // todo: Remove this?
1997                                         //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
1998                                 if (preg_match("| DEFAULT '(.*?)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
1999                                         $default_value = $matches[1];
2000                                         if ($tablefield->Default != $default_value) {
2001                                                 // Add a query to change the column's default value
2002                                                 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
2003                                                 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
2004                                         }
2005                                 }
2006
2007                                 // Remove the field from the array (so it's not added).
2008                                 unset($cfields[strtolower($tablefield->Field)]);
2009                         } else {
2010                                 // This field exists in the table, but not in the creation queries?
2011                         }
2012                 }
2013
2014                 // For every remaining field specified for the table.
2015                 foreach ($cfields as $fieldname => $fielddef) {
2016                         // Push a query line into $cqueries that adds the field to that table.
2017                         $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
2018                         $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
2019                 }
2020
2021                 // Index stuff goes here. Fetch the table index structure from the database.
2022                 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
2023
2024                 if ($tableindices) {
2025                         // Clear the index array.
2026                         $index_ary = array();
2027
2028                         // For every index in the table.
2029                         foreach ($tableindices as $tableindex) {
2030
2031                                 // Add the index to the index data array.
2032                                 $keyname = $tableindex->Key_name;
2033                                 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
2034                                 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
2035                         }
2036
2037                         // For each actual index in the index array.
2038                         foreach ($index_ary as $index_name => $index_data) {
2039
2040                                 // Build a create string to compare to the query.
2041                                 $index_string = '';
2042                                 if ($index_name == 'PRIMARY') {
2043                                         $index_string .= 'PRIMARY ';
2044                                 } elseif ( $index_data['unique'] ) {
2045                                         $index_string .= 'UNIQUE ';
2046                                 }
2047                                 $index_string .= 'KEY ';
2048                                 if ($index_name != 'PRIMARY') {
2049                                         $index_string .= $index_name;
2050                                 }
2051                                 $index_columns = '';
2052
2053                                 // For each column in the index.
2054                                 foreach ($index_data['columns'] as $column_data) {
2055                                         if ($index_columns != '') $index_columns .= ',';
2056
2057                                         // Add the field to the column list string.
2058                                         $index_columns .= $column_data['fieldname'];
2059                                         if ($column_data['subpart'] != '') {
2060                                                 $index_columns .= '('.$column_data['subpart'].')';
2061                                         }
2062                                 }
2063
2064                                 // The alternative index string doesn't care about subparts
2065                                 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
2066
2067                                 // Add the column list to the index create string.
2068                                 $index_strings = array(
2069                                         "$index_string ($index_columns)",
2070                                         "$index_string ($alt_index_columns)",
2071                                 );
2072
2073                                 foreach( $index_strings as $index_string ) {
2074                                         if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
2075                                                 unset( $indices[ $aindex ] );
2076                                                 break;
2077                                                 // todo: Remove this?
2078                                                 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
2079                                         }
2080                                 }
2081                                 // todo: Remove this?
2082                                 //else echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br /><b>Did not find index:</b>".$index_string."<br />".print_r($indices, true)."</pre>\n";
2083                         }
2084                 }
2085
2086                 // For every remaining index specified for the table.
2087                 foreach ( (array) $indices as $index ) {
2088                         // Push a query line into $cqueries that adds the index to that table.
2089                         $cqueries[] = "ALTER TABLE {$table} ADD $index";
2090                         $for_update[] = 'Added index ' . $table . ' ' . $index;
2091                 }
2092
2093                 // Remove the original table creation query from processing.
2094                 unset( $cqueries[ $table ], $for_update[ $table ] );
2095         }
2096
2097         $allqueries = array_merge($cqueries, $iqueries);
2098         if ($execute) {
2099                 foreach ($allqueries as $query) {
2100                         // todo: Remove this?
2101                         //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
2102                         $wpdb->query($query);
2103                 }
2104         }
2105
2106         return $for_update;
2107 }
2108
2109 /**
2110  * Updates the database tables to a new schema.
2111  *
2112  * By default, updates all the tables to use the latest defined schema, but can also
2113  * be used to update a specific set of tables in wp_get_db_schema().
2114  *
2115  * @since 1.5.0
2116  *
2117  * @uses dbDelta
2118  *
2119  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2120  */
2121 function make_db_current( $tables = 'all' ) {
2122         $alterations = dbDelta( $tables );
2123         echo "<ol>\n";
2124         foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
2125         echo "</ol>\n";
2126 }
2127
2128 /**
2129  * Updates the database tables to a new schema, but without displaying results.
2130  *
2131  * By default, updates all the tables to use the latest defined schema, but can
2132  * also be used to update a specific set of tables in wp_get_db_schema().
2133  *
2134  * @since 1.5.0
2135  *
2136  * @see make_db_current()
2137  *
2138  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2139  */
2140 function make_db_current_silent( $tables = 'all' ) {
2141         dbDelta( $tables );
2142 }
2143
2144 /**
2145  * Creates a site theme from an existing theme.
2146  *
2147  * {@internal Missing Long Description}}
2148  *
2149  * @since 1.5.0
2150  *
2151  * @param string $theme_name The name of the theme.
2152  * @param string $template   The directory name of the theme.
2153  * @return bool
2154  */
2155 function make_site_theme_from_oldschool($theme_name, $template) {
2156         $home_path = get_home_path();
2157         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2158
2159         if (! file_exists("$home_path/index.php"))
2160                 return false;
2161
2162         /*
2163          * Copy files from the old locations to the site theme.
2164          * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
2165          */
2166         $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
2167
2168         foreach ($files as $oldfile => $newfile) {
2169                 if ($oldfile == 'index.php')
2170                         $oldpath = $home_path;
2171                 else
2172                         $oldpath = ABSPATH;
2173
2174                 // Check to make sure it's not a new index.
2175                 if ($oldfile == 'index.php') {
2176                         $index = implode('', file("$oldpath/$oldfile"));
2177                         if (strpos($index, 'WP_USE_THEMES') !== false) {
2178                                 if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile"))
2179                                         return false;
2180
2181                                 // Don't copy anything.
2182                                 continue;
2183                                 }
2184                 }
2185
2186                 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
2187                         return false;
2188
2189                 chmod("$site_dir/$newfile", 0777);
2190
2191                 // Update the blog header include in each file.
2192                 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
2193                 if ($lines) {
2194                         $f = fopen("$site_dir/$newfile", 'w');
2195
2196                         foreach ($lines as $line) {
2197                                 if (preg_match('/require.*wp-blog-header/', $line))
2198                                         $line = '//' . $line;
2199
2200                                 // Update stylesheet references.
2201                                 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
2202
2203                                 // Update comments template inclusion.
2204                                 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
2205
2206                                 fwrite($f, "{$line}\n");
2207                         }
2208                         fclose($f);
2209                 }
2210         }
2211
2212         // Add a theme header.
2213         $header = "/*\nTheme Name: $theme_name\nTheme URI: " . __get_option('siteurl') . "\nDescription: A theme automatically created by the update.\nVersion: 1.0\nAuthor: Moi\n*/\n";
2214
2215         $stylelines = file_get_contents("$site_dir/style.css");
2216         if ($stylelines) {
2217                 $f = fopen("$site_dir/style.css", 'w');
2218
2219                 fwrite($f, $header);
2220                 fwrite($f, $stylelines);
2221                 fclose($f);
2222         }
2223
2224         return true;
2225 }
2226
2227 /**
2228  * Creates a site theme from the default theme.
2229  *
2230  * {@internal Missing Long Description}}
2231  *
2232  * @since 1.5.0
2233  *
2234  * @param string $theme_name The name of the theme.
2235  * @param string $template   The directory name of the theme.
2236  * @return null|false
2237  */
2238 function make_site_theme_from_default($theme_name, $template) {
2239         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2240         $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
2241
2242         // Copy files from the default theme to the site theme.
2243         //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
2244
2245         $theme_dir = @ opendir($default_dir);
2246         if ($theme_dir) {
2247                 while(($theme_file = readdir( $theme_dir )) !== false) {
2248                         if (is_dir("$default_dir/$theme_file"))
2249                                 continue;
2250                         if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
2251                                 return;
2252                         chmod("$site_dir/$theme_file", 0777);
2253                 }
2254         }
2255         @closedir($theme_dir);
2256
2257         // Rewrite the theme header.
2258         $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
2259         if ($stylelines) {
2260                 $f = fopen("$site_dir/style.css", 'w');
2261
2262                 foreach ($stylelines as $line) {
2263                         if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
2264                         elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
2265                         elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
2266                         elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
2267                         elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
2268                         fwrite($f, $line . "\n");
2269                 }
2270                 fclose($f);
2271         }
2272
2273         // Copy the images.
2274         umask(0);
2275         if (! mkdir("$site_dir/images", 0777)) {
2276                 return false;
2277         }
2278
2279         $images_dir = @ opendir("$default_dir/images");
2280         if ($images_dir) {
2281                 while(($image = readdir($images_dir)) !== false) {
2282                         if (is_dir("$default_dir/images/$image"))
2283                                 continue;
2284                         if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
2285                                 return;
2286                         chmod("$site_dir/images/$image", 0777);
2287                 }
2288         }
2289         @closedir($images_dir);
2290 }
2291
2292 /**
2293  * Creates a site theme.
2294  *
2295  * {@internal Missing Long Description}}
2296  *
2297  * @since 1.5.0
2298  *
2299  * @return false|string
2300  */
2301 function make_site_theme() {
2302         // Name the theme after the blog.
2303         $theme_name = __get_option('blogname');
2304         $template = sanitize_title($theme_name);
2305         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2306
2307         // If the theme already exists, nothing to do.
2308         if ( is_dir($site_dir)) {
2309                 return false;
2310         }
2311
2312         // We must be able to write to the themes dir.
2313         if (! is_writable(WP_CONTENT_DIR . "/themes")) {
2314                 return false;
2315         }
2316
2317         umask(0);
2318         if (! mkdir($site_dir, 0777)) {
2319                 return false;
2320         }
2321
2322         if (file_exists(ABSPATH . 'wp-layout.css')) {
2323                 if (! make_site_theme_from_oldschool($theme_name, $template)) {
2324                         // TODO: rm -rf the site theme directory.
2325                         return false;
2326                 }
2327         } else {
2328                 if (! make_site_theme_from_default($theme_name, $template))
2329                         // TODO: rm -rf the site theme directory.
2330                         return false;
2331         }
2332
2333         // Make the new site theme active.
2334         $current_template = __get_option('template');
2335         if ($current_template == WP_DEFAULT_THEME) {
2336                 update_option('template', $template);
2337                 update_option('stylesheet', $template);
2338         }
2339         return $template;
2340 }
2341
2342 /**
2343  * Translate user level to user role name.
2344  *
2345  * @since 2.0.0
2346  *
2347  * @param int $level User level.
2348  * @return string User role name.
2349  */
2350 function translate_level_to_role($level) {
2351         switch ($level) {
2352         case 10:
2353         case 9:
2354         case 8:
2355                 return 'administrator';
2356         case 7:
2357         case 6:
2358         case 5:
2359                 return 'editor';
2360         case 4:
2361         case 3:
2362         case 2:
2363                 return 'author';
2364         case 1:
2365                 return 'contributor';
2366         case 0:
2367                 return 'subscriber';
2368         }
2369 }
2370
2371 /**
2372  * Checks the version of the installed MySQL binary.
2373  *
2374  * @since 2.1.0
2375  */
2376 function wp_check_mysql_version() {
2377         global $wpdb;
2378         $result = $wpdb->check_database_version();
2379         if ( is_wp_error( $result ) )
2380                 die( $result->get_error_message() );
2381 }
2382
2383 /**
2384  * Disables the Automattic widgets plugin, which was merged into core.
2385  *
2386  * @since 2.2.0
2387  */
2388 function maybe_disable_automattic_widgets() {
2389         $plugins = __get_option( 'active_plugins' );
2390
2391         foreach ( (array) $plugins as $plugin ) {
2392                 if ( basename( $plugin ) == 'widgets.php' ) {
2393                         array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
2394                         update_option( 'active_plugins', $plugins );
2395                         break;
2396                 }
2397         }
2398 }
2399
2400 /**
2401  * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
2402  *
2403  * @since 3.5.0
2404  */
2405 function maybe_disable_link_manager() {
2406         global $wp_current_db_version, $wpdb;
2407
2408         if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
2409                 update_option( 'link_manager_enabled', 0 );
2410 }
2411
2412 /**
2413  * Runs before the schema is upgraded.
2414  *
2415  * @since 2.9.0
2416  */
2417 function pre_schema_upgrade() {
2418         global $wp_current_db_version, $wpdb;
2419
2420         // Upgrade versions prior to 2.9
2421         if ( $wp_current_db_version < 11557 ) {
2422                 // Delete duplicate options. Keep the option with the highest option_id.
2423                 $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id");
2424
2425                 // Drop the old primary key and add the new.
2426                 $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)");
2427
2428                 // Drop the old option_name index. dbDelta() doesn't do the drop.
2429                 $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name");
2430         }
2431
2432         // Multisite schema upgrades.
2433         if ( $wp_current_db_version < 25448 && is_multisite() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && is_main_network() ) {
2434
2435                 // Upgrade verions prior to 3.7
2436                 if ( $wp_current_db_version < 25179 ) {
2437                         // New primary key for signups.
2438                         $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
2439                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
2440                 }
2441
2442                 if ( $wp_current_db_version < 25448 ) {
2443                         // Convert archived from enum to tinyint.
2444                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
2445                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
2446                 }
2447         }
2448
2449         if ( $wp_current_db_version < 30133 ) {
2450                 // dbDelta() can recreate but can't drop the index.
2451                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug" );
2452         }
2453
2454         // Upgrade versions prior to 4.2.
2455         if ( $wp_current_db_version < 31351 ) {
2456                 if ( ! is_multisite() ) {
2457                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2458                 }
2459                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
2460                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
2461                 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2462                 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2463                 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
2464         }
2465 }
2466
2467 /**
2468  * Install global terms.
2469  *
2470  * @since 3.0.0
2471  *
2472  */
2473 if ( !function_exists( 'install_global_terms' ) ) :
2474 function install_global_terms() {
2475         global $wpdb, $charset_collate;
2476         $ms_queries = "
2477 CREATE TABLE $wpdb->sitecategories (
2478   cat_ID bigint(20) NOT NULL auto_increment,
2479   cat_name varchar(55) NOT NULL default '',
2480   category_nicename varchar(200) NOT NULL default '',
2481   last_updated timestamp NOT NULL,
2482   PRIMARY KEY  (cat_ID),
2483   KEY category_nicename (category_nicename),
2484   KEY last_updated (last_updated)
2485 ) $charset_collate;
2486 ";
2487 // now create tables
2488         dbDelta( $ms_queries );
2489 }
2490 endif;