]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/includes/upgrade.php
WordPress 4.2-scripts
[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         if ( $wp_current_db_version < 31351 )
528                 upgrade_420();
529
530         maybe_disable_link_manager();
531
532         maybe_disable_automattic_widgets();
533
534         update_option( 'db_version', $wp_db_version );
535         update_option( 'db_upgraded', true );
536 }
537
538 /**
539  * Execute changes made in WordPress 1.0.
540  *
541  * @since 1.0.0
542  */
543 function upgrade_100() {
544         global $wpdb;
545
546         // Get the title and ID of every post, post_name to check if it already has a value
547         $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
548         if ($posts) {
549                 foreach($posts as $post) {
550                         if ('' == $post->post_name) {
551                                 $newtitle = sanitize_title($post->post_title);
552                                 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID) );
553                         }
554                 }
555         }
556
557         $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
558         foreach ($categories as $category) {
559                 if ('' == $category->category_nicename) {
560                         $newtitle = sanitize_title($category->cat_name);
561                         $wpdb->update( $wpdb->categories, array('category_nicename' => $newtitle), array('cat_ID' => $category->cat_ID) );
562                 }
563         }
564
565         $sql = "UPDATE $wpdb->options
566                 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
567                 WHERE option_name LIKE %s
568                 AND option_value LIKE %s";
569         $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) );
570
571         $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
572         if ($done_ids) :
573                 $done_posts = array();
574                 foreach ($done_ids as $done_id) :
575                         $done_posts[] = $done_id->post_id;
576                 endforeach;
577                 $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
578         else:
579                 $catwhere = '';
580         endif;
581
582         $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
583         if ($allposts) :
584                 foreach ($allposts as $post) {
585                         // Check to see if it's already been imported
586                         $cat = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category) );
587                         if (!$cat && 0 != $post->post_category) { // If there's no result
588                                 $wpdb->insert( $wpdb->post2cat, array('post_id' => $post->ID, 'category_id' => $post->post_category) );
589                         }
590                 }
591         endif;
592 }
593
594 /**
595  * Execute changes made in WordPress 1.0.1.
596  *
597  * @since 1.0.1
598  */
599 function upgrade_101() {
600         global $wpdb;
601
602         // Clean up indices, add a few
603         add_clean_index($wpdb->posts, 'post_name');
604         add_clean_index($wpdb->posts, 'post_status');
605         add_clean_index($wpdb->categories, 'category_nicename');
606         add_clean_index($wpdb->comments, 'comment_approved');
607         add_clean_index($wpdb->comments, 'comment_post_ID');
608         add_clean_index($wpdb->links , 'link_category');
609         add_clean_index($wpdb->links , 'link_visible');
610 }
611
612 /**
613  * Execute changes made in WordPress 1.2.
614  *
615  * @since 1.2.0
616  */
617 function upgrade_110() {
618         global $wpdb;
619
620         // Set user_nicename.
621         $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
622         foreach ($users as $user) {
623                 if ('' == $user->user_nicename) {
624                         $newname = sanitize_title($user->user_nickname);
625                         $wpdb->update( $wpdb->users, array('user_nicename' => $newname), array('ID' => $user->ID) );
626                 }
627         }
628
629         $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
630         foreach ($users as $row) {
631                 if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
632                         $wpdb->update( $wpdb->users, array('user_pass' => md5($row->user_pass)), array('ID' => $row->ID) );
633                 }
634         }
635
636         // Get the GMT offset, we'll use that later on
637         $all_options = get_alloptions_110();
638
639         $time_difference = $all_options->time_difference;
640
641                 $server_time = time()+date('Z');
642         $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS;
643         $gmt_time = time();
644
645         $diff_gmt_server = ($gmt_time - $server_time) / HOUR_IN_SECONDS;
646         $diff_weblogger_server = ($weblogger_time - $server_time) / HOUR_IN_SECONDS;
647         $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
648         $gmt_offset = -$diff_gmt_weblogger;
649
650         // Add a gmt_offset option, with value $gmt_offset
651         add_option('gmt_offset', $gmt_offset);
652
653         // Check if we already set the GMT fields (if we did, then
654         // MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
655         // <michel_v> I just slapped myself silly for not thinking about it earlier
656         $got_gmt_fields = ! ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00');
657
658         if (!$got_gmt_fields) {
659
660                 // Add or subtract time to all dates, to get GMT dates
661                 $add_hours = intval($diff_gmt_weblogger);
662                 $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
663                 $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
664                 $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
665                 $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'");
666                 $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
667                 $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
668         }
669
670 }
671
672 /**
673  * Execute changes made in WordPress 1.5.
674  *
675  * @since 1.5.0
676  */
677 function upgrade_130() {
678         global $wpdb;
679
680         // Remove extraneous backslashes.
681         $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
682         if ($posts) {
683                 foreach($posts as $post) {
684                         $post_content = addslashes(deslash($post->post_content));
685                         $post_title = addslashes(deslash($post->post_title));
686                         $post_excerpt = addslashes(deslash($post->post_excerpt));
687                         if ( empty($post->guid) )
688                                 $guid = get_permalink($post->ID);
689                         else
690                                 $guid = $post->guid;
691
692                         $wpdb->update( $wpdb->posts, compact('post_title', 'post_content', 'post_excerpt', 'guid'), array('ID' => $post->ID) );
693
694                 }
695         }
696
697         // Remove extraneous backslashes.
698         $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
699         if ($comments) {
700                 foreach($comments as $comment) {
701                         $comment_content = deslash($comment->comment_content);
702                         $comment_author = deslash($comment->comment_author);
703
704                         $wpdb->update($wpdb->comments, compact('comment_content', 'comment_author'), array('comment_ID' => $comment->comment_ID) );
705                 }
706         }
707
708         // Remove extraneous backslashes.
709         $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
710         if ($links) {
711                 foreach($links as $link) {
712                         $link_name = deslash($link->link_name);
713                         $link_description = deslash($link->link_description);
714
715                         $wpdb->update( $wpdb->links, compact('link_name', 'link_description'), array('link_id' => $link->link_id) );
716                 }
717         }
718
719         $active_plugins = __get_option('active_plugins');
720
721         /*
722          * If plugins are not stored in an array, they're stored in the old
723          * newline separated format. Convert to new format.
724          */
725         if ( !is_array( $active_plugins ) ) {
726                 $active_plugins = explode("\n", trim($active_plugins));
727                 update_option('active_plugins', $active_plugins);
728         }
729
730         // Obsolete tables
731         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues');
732         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes');
733         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups');
734         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options');
735
736         // Update comments table to use comment_type
737         $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
738         $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
739
740         // Some versions have multiple duplicate option_name rows with the same values
741         $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
742         foreach ( $options as $option ) {
743                 if ( 1 != $option->dupes ) { // Could this be done in the query?
744                         $limit = $option->dupes - 1;
745                         $dupe_ids = $wpdb->get_col( $wpdb->prepare("SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit) );
746                         if ( $dupe_ids ) {
747                                 $dupe_ids = join($dupe_ids, ',');
748                                 $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
749                         }
750                 }
751         }
752
753         make_site_theme();
754 }
755
756 /**
757  * Execute changes made in WordPress 2.0.
758  *
759  * @since 2.0.0
760  */
761 function upgrade_160() {
762         global $wpdb, $wp_current_db_version;
763
764         populate_roles_160();
765
766         $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
767         foreach ( $users as $user ) :
768                 if ( !empty( $user->user_firstname ) )
769                         update_user_meta( $user->ID, 'first_name', wp_slash($user->user_firstname) );
770                 if ( !empty( $user->user_lastname ) )
771                         update_user_meta( $user->ID, 'last_name', wp_slash($user->user_lastname) );
772                 if ( !empty( $user->user_nickname ) )
773                         update_user_meta( $user->ID, 'nickname', wp_slash($user->user_nickname) );
774                 if ( !empty( $user->user_level ) )
775                         update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level );
776                 if ( !empty( $user->user_icq ) )
777                         update_user_meta( $user->ID, 'icq', wp_slash($user->user_icq) );
778                 if ( !empty( $user->user_aim ) )
779                         update_user_meta( $user->ID, 'aim', wp_slash($user->user_aim) );
780                 if ( !empty( $user->user_msn ) )
781                         update_user_meta( $user->ID, 'msn', wp_slash($user->user_msn) );
782                 if ( !empty( $user->user_yim ) )
783                         update_user_meta( $user->ID, 'yim', wp_slash($user->user_icq) );
784                 if ( !empty( $user->user_description ) )
785                         update_user_meta( $user->ID, 'description', wp_slash($user->user_description) );
786
787                 if ( isset( $user->user_idmode ) ):
788                         $idmode = $user->user_idmode;
789                         if ($idmode == 'nickname') $id = $user->user_nickname;
790                         if ($idmode == 'login') $id = $user->user_login;
791                         if ($idmode == 'firstname') $id = $user->user_firstname;
792                         if ($idmode == 'lastname') $id = $user->user_lastname;
793                         if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
794                         if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
795                         if (!$idmode) $id = $user->user_nickname;
796                         $wpdb->update( $wpdb->users, array('display_name' => $id), array('ID' => $user->ID) );
797                 endif;
798
799                 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
800                 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities');
801                 if ( empty($caps) || defined('RESET_CAPS') ) {
802                         $level = get_user_meta($user->ID, $wpdb->prefix . 'user_level', true);
803                         $role = translate_level_to_role($level);
804                         update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) );
805                 }
806
807         endforeach;
808         $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' );
809         $wpdb->hide_errors();
810         foreach ( $old_user_fields as $old )
811                 $wpdb->query("ALTER TABLE $wpdb->users DROP $old");
812         $wpdb->show_errors();
813
814         // Populate comment_count field of posts table.
815         $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
816         if ( is_array( $comments ) )
817                 foreach ($comments as $comment)
818                         $wpdb->update( $wpdb->posts, array('comment_count' => $comment->c), array('ID' => $comment->comment_post_ID) );
819
820         /*
821          * Some alpha versions used a post status of object instead of attachment
822          * and put the mime type in post_type instead of post_mime_type.
823          */
824         if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
825                 $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
826                 foreach ($objects as $object) {
827                         $wpdb->update( $wpdb->posts, array(     'post_status' => 'attachment',
828                                                                                                 'post_mime_type' => $object->post_type,
829                                                                                                 'post_type' => ''),
830                                                                                  array( 'ID' => $object->ID ) );
831
832                         $meta = get_post_meta($object->ID, 'imagedata', true);
833                         if ( ! empty($meta['file']) )
834                                 update_attached_file( $object->ID, $meta['file'] );
835                 }
836         }
837 }
838
839 /**
840  * Execute changes made in WordPress 2.1.
841  *
842  * @since 2.1.0
843  */
844 function upgrade_210() {
845         global $wpdb, $wp_current_db_version;
846
847         if ( $wp_current_db_version < 3506 ) {
848                 // Update status and type.
849                 $posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts");
850
851                 if ( ! empty($posts) ) foreach ($posts as $post) {
852                         $status = $post->post_status;
853                         $type = 'post';
854
855                         if ( 'static' == $status ) {
856                                 $status = 'publish';
857                                 $type = 'page';
858                         } elseif ( 'attachment' == $status ) {
859                                 $status = 'inherit';
860                                 $type = 'attachment';
861                         }
862
863                         $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID) );
864                 }
865         }
866
867         if ( $wp_current_db_version < 3845 ) {
868                 populate_roles_210();
869         }
870
871         if ( $wp_current_db_version < 3531 ) {
872                 // Give future posts a post_status of future.
873                 $now = gmdate('Y-m-d H:i:59');
874                 $wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'");
875
876                 $posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'");
877                 if ( !empty($posts) )
878                         foreach ( $posts as $post )
879                                 wp_schedule_single_event(mysql2date('U', $post->post_date, false), 'publish_future_post', array($post->ID));
880         }
881 }
882
883 /**
884  * Execute changes made in WordPress 2.3.
885  *
886  * @since 2.3.0
887  */
888 function upgrade_230() {
889         global $wp_current_db_version, $wpdb;
890
891         if ( $wp_current_db_version < 5200 ) {
892                 populate_roles_230();
893         }
894
895         // Convert categories to terms.
896         $tt_ids = array();
897         $have_tags = false;
898         $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID");
899         foreach ($categories as $category) {
900                 $term_id = (int) $category->cat_ID;
901                 $name = $category->cat_name;
902                 $description = $category->category_description;
903                 $slug = $category->category_nicename;
904                 $parent = $category->category_parent;
905                 $term_group = 0;
906
907                 // Associate terms with the same slug in a term group and make slugs unique.
908                 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
909                         $term_group = $exists[0]->term_group;
910                         $id = $exists[0]->term_id;
911                         $num = 2;
912                         do {
913                                 $alt_slug = $slug . "-$num";
914                                 $num++;
915                                 $slug_check = $wpdb->get_var( $wpdb->prepare("SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug) );
916                         } while ( $slug_check );
917
918                         $slug = $alt_slug;
919
920                         if ( empty( $term_group ) ) {
921                                 $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
922                                 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id) );
923                         }
924                 }
925
926                 $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES
927                 (%d, %s, %s, %d)", $term_id, $name, $slug, $term_group) );
928
929                 $count = 0;
930                 if ( !empty($category->category_count) ) {
931                         $count = (int) $category->category_count;
932                         $taxonomy = 'category';
933                         $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) );
934                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
935                 }
936
937                 if ( !empty($category->link_count) ) {
938                         $count = (int) $category->link_count;
939                         $taxonomy = 'link_category';
940                         $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) );
941                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
942                 }
943
944                 if ( !empty($category->tag_count) ) {
945                         $have_tags = true;
946                         $count = (int) $category->tag_count;
947                         $taxonomy = 'post_tag';
948                         $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
949                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
950                 }
951
952                 if ( empty($count) ) {
953                         $count = 0;
954                         $taxonomy = 'category';
955                         $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
956                         $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
957                 }
958         }
959
960         $select = 'post_id, category_id';
961         if ( $have_tags )
962                 $select .= ', rel_type';
963
964         $posts = $wpdb->get_results("SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id");
965         foreach ( $posts as $post ) {
966                 $post_id = (int) $post->post_id;
967                 $term_id = (int) $post->category_id;
968                 $taxonomy = 'category';
969                 if ( !empty($post->rel_type) && 'tag' == $post->rel_type)
970                         $taxonomy = 'tag';
971                 $tt_id = $tt_ids[$term_id][$taxonomy];
972                 if ( empty($tt_id) )
973                         continue;
974
975                 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $post_id, 'term_taxonomy_id' => $tt_id) );
976         }
977
978         // < 3570 we used linkcategories. >= 3570 we used categories and link2cat.
979         if ( $wp_current_db_version < 3570 ) {
980                 /*
981                  * Create link_category terms for link categories. Create a map of link
982                  * cat IDs to link_category terms.
983                  */
984                 $link_cat_id_map = array();
985                 $default_link_cat = 0;
986                 $tt_ids = array();
987                 $link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories');
988                 foreach ( $link_cats as $category) {
989                         $cat_id = (int) $category->cat_id;
990                         $term_id = 0;
991                         $name = wp_slash($category->cat_name);
992                         $slug = sanitize_title($name);
993                         $term_group = 0;
994
995                         // Associate terms with the same slug in a term group and make slugs unique.
996                         if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
997                                 $term_group = $exists[0]->term_group;
998                                 $term_id = $exists[0]->term_id;
999                         }
1000
1001                         if ( empty($term_id) ) {
1002                                 $wpdb->insert( $wpdb->terms, compact('name', 'slug', 'term_group') );
1003                                 $term_id = (int) $wpdb->insert_id;
1004                         }
1005
1006                         $link_cat_id_map[$cat_id] = $term_id;
1007                         $default_link_cat = $term_id;
1008
1009                         $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $term_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 0) );
1010                         $tt_ids[$term_id] = (int) $wpdb->insert_id;
1011                 }
1012
1013                 // Associate links to cats.
1014                 $links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links");
1015                 if ( !empty($links) ) foreach ( $links as $link ) {
1016                         if ( 0 == $link->link_category )
1017                                 continue;
1018                         if ( ! isset($link_cat_id_map[$link->link_category]) )
1019                                 continue;
1020                         $term_id = $link_cat_id_map[$link->link_category];
1021                         $tt_id = $tt_ids[$term_id];
1022                         if ( empty($tt_id) )
1023                                 continue;
1024
1025                         $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link->link_id, 'term_taxonomy_id' => $tt_id) );
1026                 }
1027
1028                 // Set default to the last category we grabbed during the upgrade loop.
1029                 update_option('default_link_category', $default_link_cat);
1030         } else {
1031                 $links = $wpdb->get_results("SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id");
1032                 foreach ( $links as $link ) {
1033                         $link_id = (int) $link->link_id;
1034                         $term_id = (int) $link->category_id;
1035                         $taxonomy = 'link_category';
1036                         $tt_id = $tt_ids[$term_id][$taxonomy];
1037                         if ( empty($tt_id) )
1038                                 continue;
1039                         $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link_id, 'term_taxonomy_id' => $tt_id) );
1040                 }
1041         }
1042
1043         if ( $wp_current_db_version < 4772 ) {
1044                 // Obsolete linkcategories table
1045                 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories');
1046         }
1047
1048         // Recalculate all counts
1049         $terms = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy");
1050         foreach ( (array) $terms as $term ) {
1051                 if ( ('post_tag' == $term->taxonomy) || ('category' == $term->taxonomy) )
1052                         $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) );
1053                 else
1054                         $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id) );
1055                 $wpdb->update( $wpdb->term_taxonomy, array('count' => $count), array('term_taxonomy_id' => $term->term_taxonomy_id) );
1056         }
1057 }
1058
1059 /**
1060  * Remove old options from the database.
1061  *
1062  * @since 2.3.0
1063  */
1064 function upgrade_230_options_table() {
1065         global $wpdb;
1066         $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' );
1067         $wpdb->hide_errors();
1068         foreach ( $old_options_fields as $old )
1069                 $wpdb->query("ALTER TABLE $wpdb->options DROP $old");
1070         $wpdb->show_errors();
1071 }
1072
1073 /**
1074  * Remove old categories, link2cat, and post2cat database tables.
1075  *
1076  * @since 2.3.0
1077  */
1078 function upgrade_230_old_tables() {
1079         global $wpdb;
1080         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories');
1081         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat');
1082         $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat');
1083 }
1084
1085 /**
1086  * Upgrade old slugs made in version 2.2.
1087  *
1088  * @since 2.2.0
1089  */
1090 function upgrade_old_slugs() {
1091         // Upgrade people who were using the Redirect Old Slugs plugin.
1092         global $wpdb;
1093         $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'");
1094 }
1095
1096 /**
1097  * Execute changes made in WordPress 2.5.0.
1098  *
1099  * @since 2.5.0
1100  */
1101 function upgrade_250() {
1102         global $wp_current_db_version;
1103
1104         if ( $wp_current_db_version < 6689 ) {
1105                 populate_roles_250();
1106         }
1107
1108 }
1109
1110 /**
1111  * Execute changes made in WordPress 2.5.2.
1112  *
1113  * @since 2.5.2
1114  */
1115 function upgrade_252() {
1116         global $wpdb;
1117
1118         $wpdb->query("UPDATE $wpdb->users SET user_activation_key = ''");
1119 }
1120
1121 /**
1122  * Execute changes made in WordPress 2.6.
1123  *
1124  * @since 2.6.0
1125  */
1126 function upgrade_260() {
1127         global $wp_current_db_version;
1128
1129         if ( $wp_current_db_version < 8000 )
1130                 populate_roles_260();
1131 }
1132
1133 /**
1134  * Execute changes made in WordPress 2.7.
1135  *
1136  * @since 2.7.0
1137  */
1138 function upgrade_270() {
1139         global $wpdb, $wp_current_db_version;
1140
1141         if ( $wp_current_db_version < 8980 )
1142                 populate_roles_270();
1143
1144         // Update post_date for unpublished posts with empty timestamp
1145         if ( $wp_current_db_version < 8921 )
1146                 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" );
1147 }
1148
1149 /**
1150  * Execute changes made in WordPress 2.8.
1151  *
1152  * @since 2.8.0
1153  */
1154 function upgrade_280() {
1155         global $wp_current_db_version, $wpdb;
1156
1157         if ( $wp_current_db_version < 10360 )
1158                 populate_roles_280();
1159         if ( is_multisite() ) {
1160                 $start = 0;
1161                 while( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) {
1162                         foreach( $rows as $row ) {
1163                                 $value = $row->option_value;
1164                                 if ( !@unserialize( $value ) )
1165                                         $value = stripslashes( $value );
1166                                 if ( $value !== $row->option_value ) {
1167                                         update_option( $row->option_name, $value );
1168                                 }
1169                         }
1170                         $start += 20;
1171                 }
1172                 refresh_blog_details( $wpdb->blogid );
1173         }
1174 }
1175
1176 /**
1177  * Execute changes made in WordPress 2.9.
1178  *
1179  * @since 2.9.0
1180  */
1181 function upgrade_290() {
1182         global $wp_current_db_version;
1183
1184         if ( $wp_current_db_version < 11958 ) {
1185                 // Previously, setting depth to 1 would redundantly disable threading, but now 2 is the minimum depth to avoid confusion
1186                 if ( get_option( 'thread_comments_depth' ) == '1' ) {
1187                         update_option( 'thread_comments_depth', 2 );
1188                         update_option( 'thread_comments', 0 );
1189                 }
1190         }
1191 }
1192
1193 /**
1194  * Execute changes made in WordPress 3.0.
1195  *
1196  * @since 3.0.0
1197  */
1198 function upgrade_300() {
1199         global $wp_current_db_version, $wpdb;
1200
1201         if ( $wp_current_db_version < 15093 )
1202                 populate_roles_300();
1203
1204         if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false )
1205                 add_site_option( 'siteurl', '' );
1206
1207         // 3.0 screen options key name changes.
1208         if ( is_main_site() && !defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
1209                 $sql = "DELETE FROM $wpdb->usermeta
1210                         WHERE meta_key LIKE %s
1211                         OR meta_key LIKE %s
1212                         OR meta_key LIKE %s
1213                         OR meta_key LIKE %s
1214                         OR meta_key LIKE %s
1215                         OR meta_key LIKE %s
1216                         OR meta_key = 'manageedittagscolumnshidden'
1217                         OR meta_key = 'managecategoriescolumnshidden'
1218                         OR meta_key = 'manageedit-tagscolumnshidden'
1219                         OR meta_key = 'manageeditcolumnshidden'
1220                         OR meta_key = 'categories_per_page'
1221                         OR meta_key = 'edit_tags_per_page'";
1222                 $prefix = $wpdb->esc_like( $wpdb->base_prefix );
1223                 $wpdb->query( $wpdb->prepare( $sql,
1224                         $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%',
1225                         $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%',
1226                         $prefix . '%' . $wpdb->esc_like( 'manage-'         ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%',
1227                         $prefix . '%' . $wpdb->esc_like( 'meta-box-order'  ) . '%',
1228                         $prefix . '%' . $wpdb->esc_like( 'metaboxorder'    ) . '%',
1229                         $prefix . '%' . $wpdb->esc_like( 'screen_layout'   ) . '%'
1230                 ) );
1231         }
1232
1233 }
1234
1235 /**
1236  * Execute changes made in WordPress 3.3.
1237  *
1238  * @since 3.3.0
1239  */
1240 function upgrade_330() {
1241         global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets;
1242
1243         if ( $wp_current_db_version < 19061 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1244                 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" );
1245         }
1246
1247         if ( $wp_current_db_version >= 11548 )
1248                 return;
1249
1250         $sidebars_widgets = get_option( 'sidebars_widgets', array() );
1251         $_sidebars_widgets = array();
1252
1253         if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) )
1254                 $sidebars_widgets['array_version'] = 3;
1255         elseif ( !isset($sidebars_widgets['array_version']) )
1256                 $sidebars_widgets['array_version'] = 1;
1257
1258         switch ( $sidebars_widgets['array_version'] ) {
1259                 case 1 :
1260                         foreach ( (array) $sidebars_widgets as $index => $sidebar )
1261                         if ( is_array($sidebar) )
1262                         foreach ( (array) $sidebar as $i => $name ) {
1263                                 $id = strtolower($name);
1264                                 if ( isset($wp_registered_widgets[$id]) ) {
1265                                         $_sidebars_widgets[$index][$i] = $id;
1266                                         continue;
1267                                 }
1268                                 $id = sanitize_title($name);
1269                                 if ( isset($wp_registered_widgets[$id]) ) {
1270                                         $_sidebars_widgets[$index][$i] = $id;
1271                                         continue;
1272                                 }
1273
1274                                 $found = false;
1275
1276                                 foreach ( $wp_registered_widgets as $widget_id => $widget ) {
1277                                         if ( strtolower($widget['name']) == strtolower($name) ) {
1278                                                 $_sidebars_widgets[$index][$i] = $widget['id'];
1279                                                 $found = true;
1280                                                 break;
1281                                         } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) {
1282                                                 $_sidebars_widgets[$index][$i] = $widget['id'];
1283                                                 $found = true;
1284                                                 break;
1285                                         }
1286                                 }
1287
1288                                 if ( $found )
1289                                         continue;
1290
1291                                 unset($_sidebars_widgets[$index][$i]);
1292                         }
1293                         $_sidebars_widgets['array_version'] = 2;
1294                         $sidebars_widgets = $_sidebars_widgets;
1295                         unset($_sidebars_widgets);
1296
1297                 case 2 :
1298                         $sidebars_widgets = retrieve_widgets();
1299                         $sidebars_widgets['array_version'] = 3;
1300                         update_option( 'sidebars_widgets', $sidebars_widgets );
1301         }
1302 }
1303
1304 /**
1305  * Execute changes made in WordPress 3.4.
1306  *
1307  * @since 3.4.0
1308  */
1309 function upgrade_340() {
1310         global $wp_current_db_version, $wpdb;
1311
1312         if ( $wp_current_db_version < 19798 ) {
1313                 $wpdb->hide_errors();
1314                 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" );
1315                 $wpdb->show_errors();
1316         }
1317
1318         if ( $wp_current_db_version < 19799 ) {
1319                 $wpdb->hide_errors();
1320                 $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved");
1321                 $wpdb->show_errors();
1322         }
1323
1324         if ( $wp_current_db_version < 20022 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1325                 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" );
1326         }
1327
1328         if ( $wp_current_db_version < 20080 ) {
1329                 if ( 'yes' == $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) {
1330                         $uninstall_plugins = get_option( 'uninstall_plugins' );
1331                         delete_option( 'uninstall_plugins' );
1332                         add_option( 'uninstall_plugins', $uninstall_plugins, null, 'no' );
1333                 }
1334         }
1335 }
1336
1337 /**
1338  * Execute changes made in WordPress 3.5.
1339  *
1340  * @since 3.5.0
1341  */
1342 function upgrade_350() {
1343         global $wp_current_db_version, $wpdb;
1344
1345         if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
1346                 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options()
1347
1348         if ( $wp_current_db_version < 21811 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1349                 $meta_keys = array();
1350                 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) {
1351                         if ( false !== strpos( $name, '-' ) )
1352                         $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page';
1353                 }
1354                 if ( $meta_keys ) {
1355                         $meta_keys = implode( "', '", $meta_keys );
1356                         $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" );
1357                 }
1358         }
1359
1360         if ( $wp_current_db_version < 22422 && $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ) )
1361                 wp_delete_term( $term->term_id, 'post_format' );
1362 }
1363
1364 /**
1365  * Execute changes made in WordPress 3.7.
1366  *
1367  * @since 3.7.0
1368  */
1369 function upgrade_370() {
1370         global $wp_current_db_version;
1371         if ( $wp_current_db_version < 25824 )
1372                 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' );
1373 }
1374
1375 /**
1376  * Execute changes made in WordPress 3.7.2.
1377  *
1378  * @since 3.7.2
1379  * @since 3.8.0
1380  */
1381 function upgrade_372() {
1382         global $wp_current_db_version;
1383         if ( $wp_current_db_version < 26148 )
1384                 wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
1385 }
1386
1387 /**
1388  * Execute changes made in WordPress 3.8.0.
1389  *
1390  * @since 3.8.0
1391  */
1392 function upgrade_380() {
1393         global $wp_current_db_version;
1394         if ( $wp_current_db_version < 26691 ) {
1395                 deactivate_plugins( array( 'mp6/mp6.php' ), true );
1396         }
1397 }
1398
1399 /**
1400  * Execute changes made in WordPress 4.0.0.
1401  *
1402  * @since 4.0.0
1403  */
1404 function upgrade_400() {
1405         global $wp_current_db_version;
1406         if ( $wp_current_db_version < 29630 ) {
1407                 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) {
1408                         if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages() ) ) {
1409                                 update_option( 'WPLANG', WPLANG );
1410                         } else {
1411                                 update_option( 'WPLANG', '' );
1412                         }
1413                 }
1414         }
1415 }
1416
1417 /**
1418  * Execute changes made in WordPress 4.2.0.
1419  *
1420  * @since 4.2.0
1421  */
1422 function upgrade_420() {
1423         global $wp_current_db_version, $wpdb;
1424
1425         if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1426                 if ( is_multisite() ) {
1427                         $tables = $wpdb->tables( 'blog' );
1428                 } else {
1429                         $tables = $wpdb->tables( 'all' );
1430                 }
1431
1432                 foreach ( $tables as $table ) {
1433                         maybe_convert_table_to_utf8mb4( $table );
1434                 }
1435         }
1436 }
1437
1438 /**
1439  * Executes network-level upgrade routines.
1440  *
1441  * @since 3.0.0
1442  */
1443 function upgrade_network() {
1444         global $wp_current_db_version, $wpdb;
1445
1446         // Always.
1447         if ( is_main_network() ) {
1448                 /*
1449                  * Deletes all expired transients. The multi-table delete syntax is used
1450                  * to delete the transient record from table a, and the corresponding
1451                  * transient_timeout record from table b.
1452                  */
1453                 $time = time();
1454                 $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
1455                         WHERE a.meta_key LIKE %s
1456                         AND a.meta_key NOT LIKE %s
1457                         AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1458                         AND b.meta_value < %d";
1459                 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
1460         }
1461
1462         // 2.8.
1463         if ( $wp_current_db_version < 11549 ) {
1464                 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' );
1465                 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' );
1466                 if ( $wpmu_sitewide_plugins ) {
1467                         if ( !$active_sitewide_plugins )
1468                                 $sitewide_plugins = (array) $wpmu_sitewide_plugins;
1469                         else
1470                                 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins );
1471
1472                         update_site_option( 'active_sitewide_plugins', $sitewide_plugins );
1473                 }
1474                 delete_site_option( 'wpmu_sitewide_plugins' );
1475                 delete_site_option( 'deactivated_sitewide_plugins' );
1476
1477                 $start = 0;
1478                 while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) {
1479                         foreach( $rows as $row ) {
1480                                 $value = $row->meta_value;
1481                                 if ( !@unserialize( $value ) )
1482                                         $value = stripslashes( $value );
1483                                 if ( $value !== $row->meta_value ) {
1484                                         update_site_option( $row->meta_key, $value );
1485                                 }
1486                         }
1487                         $start += 20;
1488                 }
1489         }
1490
1491         // 3.0
1492         if ( $wp_current_db_version < 13576 )
1493                 update_site_option( 'global_terms_enabled', '1' );
1494
1495         // 3.3
1496         if ( $wp_current_db_version < 19390 )
1497                 update_site_option( 'initial_db_version', $wp_current_db_version );
1498
1499         if ( $wp_current_db_version < 19470 ) {
1500                 if ( false === get_site_option( 'active_sitewide_plugins' ) )
1501                         update_site_option( 'active_sitewide_plugins', array() );
1502         }
1503
1504         // 3.4
1505         if ( $wp_current_db_version < 20148 ) {
1506                 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name.
1507                 $allowedthemes  = get_site_option( 'allowedthemes'  );
1508                 $allowed_themes = get_site_option( 'allowed_themes' );
1509                 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) {
1510                         $converted = array();
1511                         $themes = wp_get_themes();
1512                         foreach ( $themes as $stylesheet => $theme_data ) {
1513                                 if ( isset( $allowed_themes[ $theme_data->get('Name') ] ) )
1514                                         $converted[ $stylesheet ] = true;
1515                         }
1516                         update_site_option( 'allowedthemes', $converted );
1517                         delete_site_option( 'allowed_themes' );
1518                 }
1519         }
1520
1521         // 3.5
1522         if ( $wp_current_db_version < 21823 )
1523                 update_site_option( 'ms_files_rewriting', '1' );
1524
1525         // 3.5.2
1526         if ( $wp_current_db_version < 24448 ) {
1527                 $illegal_names = get_site_option( 'illegal_names' );
1528                 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) {
1529                         $illegal_name = reset( $illegal_names );
1530                         $illegal_names = explode( ' ', $illegal_name );
1531                         update_site_option( 'illegal_names', $illegal_names );
1532                 }
1533         }
1534
1535         // 4.2
1536         if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1537                 if ( ! ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && DO_NOT_UPGRADE_GLOBAL_TABLES ) ) {
1538                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1539                         $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1540                         $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1541                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1542
1543                         $tables = $wpdb->tables( 'global' );
1544
1545                         foreach ( $tables as $table ) {
1546                                 maybe_convert_table_to_utf8mb4( $table );
1547                         }
1548                 }
1549         }
1550 }
1551
1552 //
1553 // General functions we use to actually do stuff
1554 //
1555
1556 /**
1557  * Creates a table in the database if it doesn't already exist.
1558  *
1559  * This method checks for an existing database and creates a new one if it's not
1560  * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses
1561  * to query all tables first and then run the SQL statement creating the table.
1562  *
1563  * @since 1.0.0
1564  *
1565  * @param string $table_name Database table name to create.
1566  * @param string $create_ddl SQL statement to create table.
1567  * @return bool If table already exists or was created by function.
1568  */
1569 function maybe_create_table($table_name, $create_ddl) {
1570         global $wpdb;
1571
1572         $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
1573
1574         if ( $wpdb->get_var( $query ) == $table_name ) {
1575                 return true;
1576         }
1577
1578         // Didn't find it try to create it..
1579         $wpdb->query($create_ddl);
1580
1581         // We cannot directly tell that whether this succeeded!
1582         if ( $wpdb->get_var( $query ) == $table_name ) {
1583                 return true;
1584         }
1585         return false;
1586 }
1587
1588 /**
1589  * Drops a specified index from a table.
1590  *
1591  * @since 1.0.1
1592  *
1593  * @param string $table Database table name.
1594  * @param string $index Index name to drop.
1595  * @return bool True, when finished.
1596  */
1597 function drop_index($table, $index) {
1598         global $wpdb;
1599         $wpdb->hide_errors();
1600         $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
1601         // Now we need to take out all the extra ones we may have created
1602         for ($i = 0; $i < 25; $i++) {
1603                 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
1604         }
1605         $wpdb->show_errors();
1606         return true;
1607 }
1608
1609 /**
1610  * Adds an index to a specified table.
1611  *
1612  * @since 1.0.1
1613  *
1614  * @param string $table Database table name.
1615  * @param string $index Database table index column.
1616  * @return bool True, when done with execution.
1617  */
1618 function add_clean_index($table, $index) {
1619         global $wpdb;
1620         drop_index($table, $index);
1621         $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
1622         return true;
1623 }
1624
1625 /**
1626  * Adds column to a database table if it doesn't already exist.
1627  *
1628  * @since 1.3.0
1629  *
1630  * @param string $table_name  The table name to modify.
1631  * @param string $column_name The column name to add to the table.
1632  * @param string $create_ddl  The SQL statement used to add the column.
1633  * @return True if already exists or on successful completion, false on error.
1634  */
1635 function maybe_add_column($table_name, $column_name, $create_ddl) {
1636         global $wpdb;
1637         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1638                 if ($column == $column_name) {
1639                         return true;
1640                 }
1641         }
1642
1643         // Didn't find it try to create it.
1644         $wpdb->query($create_ddl);
1645
1646         // We cannot directly tell that whether this succeeded!
1647         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1648                 if ($column == $column_name) {
1649                         return true;
1650                 }
1651         }
1652         return false;
1653 }
1654
1655 /**
1656  * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4.
1657  *
1658  * @since 4.2.0
1659  *
1660  * @param string $table The table to convert.
1661  * @return bool true if the table was converted, false if it wasn't.
1662  */
1663 function maybe_convert_table_to_utf8mb4( $table ) {
1664         global $wpdb;
1665
1666         $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" );
1667         if ( ! $results ) {
1668                 return false;
1669         }
1670
1671         foreach ( $results as $column ) {
1672                 if ( $column->Collation ) {
1673                         list( $charset ) = explode( '_', $column->Collation );
1674                         $charset = strtolower( $charset );
1675                         if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) {
1676                                 // Don't upgrade tables that have non-utf8 columns.
1677                                 return false;
1678                         }
1679                 }
1680         }
1681
1682         return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
1683 }
1684
1685 /**
1686  * Retrieve all options as it was for 1.2.
1687  *
1688  * @since 1.2.0
1689  *
1690  * @return stdClass List of options.
1691  */
1692 function get_alloptions_110() {
1693         global $wpdb;
1694         $all_options = new stdClass;
1695         if ( $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ) ) {
1696                 foreach ( $options as $option ) {
1697                         if ( 'siteurl' == $option->option_name || 'home' == $option->option_name || 'category_base' == $option->option_name )
1698                                 $option->option_value = untrailingslashit( $option->option_value );
1699                         $all_options->{$option->option_name} = stripslashes( $option->option_value );
1700                 }
1701         }
1702         return $all_options;
1703 }
1704
1705 /**
1706  * Utility version of get_option that is private to install/upgrade.
1707  *
1708  * @ignore
1709  * @since 1.5.1
1710  * @access private
1711  *
1712  * @param string $setting Option name.
1713  * @return mixed
1714  */
1715 function __get_option($setting) {
1716         global $wpdb;
1717
1718         if ( $setting == 'home' && defined( 'WP_HOME' ) )
1719                 return untrailingslashit( WP_HOME );
1720
1721         if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) )
1722                 return untrailingslashit( WP_SITEURL );
1723
1724         $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) );
1725
1726         if ( 'home' == $setting && '' == $option )
1727                 return __get_option( 'siteurl' );
1728
1729         if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting || 'tag_base' == $setting )
1730                 $option = untrailingslashit( $option );
1731
1732         return maybe_unserialize( $option );
1733 }
1734
1735 /**
1736  * Filters for content to remove unnecessary slashes.
1737  *
1738  * @since 1.5.0
1739  *
1740  * @param string $content The content to modify.
1741  * @return string The de-slashed content.
1742  */
1743 function deslash($content) {
1744         // Note: \\\ inside a regex denotes a single backslash.
1745
1746         /*
1747          * Replace one or more backslashes followed by a single quote with
1748          * a single quote.
1749          */
1750         $content = preg_replace("/\\\+'/", "'", $content);
1751
1752         /*
1753          * Replace one or more backslashes followed by a double quote with
1754          * a double quote.
1755          */
1756         $content = preg_replace('/\\\+"/', '"', $content);
1757
1758         // Replace one or more backslashes with one backslash.
1759         $content = preg_replace("/\\\+/", "\\", $content);
1760
1761         return $content;
1762 }
1763
1764 /**
1765  * Modifies the database based on specified SQL statements.
1766  *
1767  * Useful for creating new tables and updating existing tables to a new structure.
1768  *
1769  * @since 1.5.0
1770  *
1771  * @param string|array $queries Optional. The query to run. Can be multiple queries
1772  *                              in an array, or a string of queries separated by
1773  *                              semicolons. Default empty.
1774  * @param bool         $execute Optional. Whether or not to execute the query right away.
1775  *                              Default true.
1776  * @return array Strings containing the results of the various update queries.
1777  */
1778 function dbDelta( $queries = '', $execute = true ) {
1779         global $wpdb;
1780
1781         if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) )
1782             $queries = wp_get_db_schema( $queries );
1783
1784         // Separate individual queries into an array
1785         if ( !is_array($queries) ) {
1786                 $queries = explode( ';', $queries );
1787                 $queries = array_filter( $queries );
1788         }
1789
1790         /**
1791          * Filter the dbDelta SQL queries.
1792          *
1793          * @since 3.3.0
1794          *
1795          * @param array $queries An array of dbDelta SQL queries.
1796          */
1797         $queries = apply_filters( 'dbdelta_queries', $queries );
1798
1799         $cqueries = array(); // Creation Queries
1800         $iqueries = array(); // Insertion Queries
1801         $for_update = array();
1802
1803         // Create a tablename index for an array ($cqueries) of queries
1804         foreach($queries as $qry) {
1805                 if ( preg_match( "|CREATE TABLE ([^ ]*)|", $qry, $matches ) ) {
1806                         $cqueries[ trim( $matches[1], '`' ) ] = $qry;
1807                         $for_update[$matches[1]] = 'Created table '.$matches[1];
1808                 } elseif ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
1809                         array_unshift( $cqueries, $qry );
1810                 } elseif ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
1811                         $iqueries[] = $qry;
1812                 } elseif ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
1813                         $iqueries[] = $qry;
1814                 } else {
1815                         // Unrecognized query type
1816                 }
1817         }
1818
1819         /**
1820          * Filter the dbDelta SQL queries for creating tables and/or databases.
1821          *
1822          * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE".
1823          *
1824          * @since 3.3.0
1825          *
1826          * @param array $cqueries An array of dbDelta create SQL queries.
1827          */
1828         $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries );
1829
1830         /**
1831          * Filter the dbDelta SQL queries for inserting or updating.
1832          *
1833          * Queries filterable via this hook contain "INSERT INTO" or "UPDATE".
1834          *
1835          * @since 3.3.0
1836          *
1837          * @param array $iqueries An array of dbDelta insert or update SQL queries.
1838          */
1839         $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries );
1840
1841         $global_tables = $wpdb->tables( 'global' );
1842         foreach ( $cqueries as $table => $qry ) {
1843                 // Upgrade global tables only for the main site. Don't upgrade at all if DO_NOT_UPGRADE_GLOBAL_TABLES is defined.
1844                 if ( in_array( $table, $global_tables ) && ( !is_main_site() || defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) ) {
1845                         unset( $cqueries[ $table ], $for_update[ $table ] );
1846                         continue;
1847                 }
1848
1849                 // Fetch the table column structure from the database
1850                 $suppress = $wpdb->suppress_errors();
1851                 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
1852                 $wpdb->suppress_errors( $suppress );
1853
1854                 if ( ! $tablefields )
1855                         continue;
1856
1857                 // Clear the field and index arrays.
1858                 $cfields = $indices = array();
1859
1860                 // Get all of the field names in the query from between the parentheses.
1861                 preg_match("|\((.*)\)|ms", $qry, $match2);
1862                 $qryline = trim($match2[1]);
1863
1864                 // Separate field lines into an array.
1865                 $flds = explode("\n", $qryline);
1866
1867                 // todo: Remove this?
1868                 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
1869
1870                 // For every field line specified in the query.
1871                 foreach ($flds as $fld) {
1872
1873                         // Extract the field name.
1874                         preg_match("|^([^ ]*)|", trim($fld), $fvals);
1875                         $fieldname = trim( $fvals[1], '`' );
1876
1877                         // Verify the found field name.
1878                         $validfield = true;
1879                         switch (strtolower($fieldname)) {
1880                         case '':
1881                         case 'primary':
1882                         case 'index':
1883                         case 'fulltext':
1884                         case 'unique':
1885                         case 'key':
1886                                 $validfield = false;
1887                                 $indices[] = trim(trim($fld), ", \n");
1888                                 break;
1889                         }
1890                         $fld = trim($fld);
1891
1892                         // If it's a valid field, add it to the field array.
1893                         if ($validfield) {
1894                                 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
1895                         }
1896                 }
1897
1898                 // For every field in the table.
1899                 foreach ($tablefields as $tablefield) {
1900
1901                         // If the table field exists in the field array ...
1902                         if (array_key_exists(strtolower($tablefield->Field), $cfields)) {
1903
1904                                 // Get the field type from the query.
1905                                 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
1906                                 $fieldtype = $matches[1];
1907
1908                                 // Is actual field type different from the field type in query?
1909                                 if ($tablefield->Type != $fieldtype) {
1910                                         // Add a query to change the column type
1911                                         $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
1912                                         $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
1913                                 }
1914
1915                                 // Get the default value from the array
1916                                         // todo: Remove this?
1917                                         //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
1918                                 if (preg_match("| DEFAULT '(.*?)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
1919                                         $default_value = $matches[1];
1920                                         if ($tablefield->Default != $default_value) {
1921                                                 // Add a query to change the column's default value
1922                                                 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
1923                                                 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
1924                                         }
1925                                 }
1926
1927                                 // Remove the field from the array (so it's not added).
1928                                 unset($cfields[strtolower($tablefield->Field)]);
1929                         } else {
1930                                 // This field exists in the table, but not in the creation queries?
1931                         }
1932                 }
1933
1934                 // For every remaining field specified for the table.
1935                 foreach ($cfields as $fieldname => $fielddef) {
1936                         // Push a query line into $cqueries that adds the field to that table.
1937                         $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
1938                         $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
1939                 }
1940
1941                 // Index stuff goes here. Fetch the table index structure from the database.
1942                 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
1943
1944                 if ($tableindices) {
1945                         // Clear the index array.
1946                         $index_ary = array();
1947
1948                         // For every index in the table.
1949                         foreach ($tableindices as $tableindex) {
1950
1951                                 // Add the index to the index data array.
1952                                 $keyname = $tableindex->Key_name;
1953                                 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
1954                                 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
1955                         }
1956
1957                         // For each actual index in the index array.
1958                         foreach ($index_ary as $index_name => $index_data) {
1959
1960                                 // Build a create string to compare to the query.
1961                                 $index_string = '';
1962                                 if ($index_name == 'PRIMARY') {
1963                                         $index_string .= 'PRIMARY ';
1964                                 } elseif ( $index_data['unique'] ) {
1965                                         $index_string .= 'UNIQUE ';
1966                                 }
1967                                 $index_string .= 'KEY ';
1968                                 if ($index_name != 'PRIMARY') {
1969                                         $index_string .= $index_name;
1970                                 }
1971                                 $index_columns = '';
1972
1973                                 // For each column in the index.
1974                                 foreach ($index_data['columns'] as $column_data) {
1975                                         if ($index_columns != '') $index_columns .= ',';
1976
1977                                         // Add the field to the column list string.
1978                                         $index_columns .= $column_data['fieldname'];
1979                                         if ($column_data['subpart'] != '') {
1980                                                 $index_columns .= '('.$column_data['subpart'].')';
1981                                         }
1982                                 }
1983
1984                                 // The alternative index string doesn't care about subparts
1985                                 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
1986
1987                                 // Add the column list to the index create string.
1988                                 $index_strings = array(
1989                                         "$index_string ($index_columns)",
1990                                         "$index_string ($alt_index_columns)",
1991                                 );
1992
1993                                 foreach( $index_strings as $index_string ) {
1994                                         if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
1995                                                 unset( $indices[ $aindex ] );
1996                                                 break;
1997                                                 // todo: Remove this?
1998                                                 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
1999                                         }
2000                                 }
2001                                 // todo: Remove this?
2002                                 //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";
2003                         }
2004                 }
2005
2006                 // For every remaining index specified for the table.
2007                 foreach ( (array) $indices as $index ) {
2008                         // Push a query line into $cqueries that adds the index to that table.
2009                         $cqueries[] = "ALTER TABLE {$table} ADD $index";
2010                         $for_update[] = 'Added index ' . $table . ' ' . $index;
2011                 }
2012
2013                 // Remove the original table creation query from processing.
2014                 unset( $cqueries[ $table ], $for_update[ $table ] );
2015         }
2016
2017         $allqueries = array_merge($cqueries, $iqueries);
2018         if ($execute) {
2019                 foreach ($allqueries as $query) {
2020                         // todo: Remove this?
2021                         //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
2022                         $wpdb->query($query);
2023                 }
2024         }
2025
2026         return $for_update;
2027 }
2028
2029 /**
2030  * Updates the database tables to a new schema.
2031  *
2032  * By default, updates all the tables to use the latest defined schema, but can also
2033  * be used to update a specific set of tables in wp_get_db_schema().
2034  *
2035  * @since 1.5.0
2036  *
2037  * @uses dbDelta
2038  *
2039  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2040  */
2041 function make_db_current( $tables = 'all' ) {
2042         $alterations = dbDelta( $tables );
2043         echo "<ol>\n";
2044         foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
2045         echo "</ol>\n";
2046 }
2047
2048 /**
2049  * Updates the database tables to a new schema, but without displaying results.
2050  *
2051  * By default, updates all the tables to use the latest defined schema, but can
2052  * also be used to update a specific set of tables in wp_get_db_schema().
2053  *
2054  * @since 1.5.0
2055  *
2056  * @see make_db_current()
2057  *
2058  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2059  */
2060 function make_db_current_silent( $tables = 'all' ) {
2061         dbDelta( $tables );
2062 }
2063
2064 /**
2065  * Creates a site theme from an existing theme.
2066  *
2067  * {@internal Missing Long Description}}
2068  *
2069  * @since 1.5.0
2070  *
2071  * @param string $theme_name The name of the theme.
2072  * @param string $template   The directory name of the theme.
2073  * @return bool
2074  */
2075 function make_site_theme_from_oldschool($theme_name, $template) {
2076         $home_path = get_home_path();
2077         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2078
2079         if (! file_exists("$home_path/index.php"))
2080                 return false;
2081
2082         /*
2083          * Copy files from the old locations to the site theme.
2084          * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
2085          */
2086         $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
2087
2088         foreach ($files as $oldfile => $newfile) {
2089                 if ($oldfile == 'index.php')
2090                         $oldpath = $home_path;
2091                 else
2092                         $oldpath = ABSPATH;
2093
2094                 // Check to make sure it's not a new index.
2095                 if ($oldfile == 'index.php') {
2096                         $index = implode('', file("$oldpath/$oldfile"));
2097                         if (strpos($index, 'WP_USE_THEMES') !== false) {
2098                                 if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile"))
2099                                         return false;
2100
2101                                 // Don't copy anything.
2102                                 continue;
2103                                 }
2104                 }
2105
2106                 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
2107                         return false;
2108
2109                 chmod("$site_dir/$newfile", 0777);
2110
2111                 // Update the blog header include in each file.
2112                 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
2113                 if ($lines) {
2114                         $f = fopen("$site_dir/$newfile", 'w');
2115
2116                         foreach ($lines as $line) {
2117                                 if (preg_match('/require.*wp-blog-header/', $line))
2118                                         $line = '//' . $line;
2119
2120                                 // Update stylesheet references.
2121                                 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
2122
2123                                 // Update comments template inclusion.
2124                                 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
2125
2126                                 fwrite($f, "{$line}\n");
2127                         }
2128                         fclose($f);
2129                 }
2130         }
2131
2132         // Add a theme header.
2133         $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";
2134
2135         $stylelines = file_get_contents("$site_dir/style.css");
2136         if ($stylelines) {
2137                 $f = fopen("$site_dir/style.css", 'w');
2138
2139                 fwrite($f, $header);
2140                 fwrite($f, $stylelines);
2141                 fclose($f);
2142         }
2143
2144         return true;
2145 }
2146
2147 /**
2148  * Creates a site theme from the default theme.
2149  *
2150  * {@internal Missing Long Description}}
2151  *
2152  * @since 1.5.0
2153  *
2154  * @param string $theme_name The name of the theme.
2155  * @param string $template   The directory name of the theme.
2156  * @return null|false
2157  */
2158 function make_site_theme_from_default($theme_name, $template) {
2159         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2160         $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
2161
2162         // Copy files from the default theme to the site theme.
2163         //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
2164
2165         $theme_dir = @ opendir($default_dir);
2166         if ($theme_dir) {
2167                 while(($theme_file = readdir( $theme_dir )) !== false) {
2168                         if (is_dir("$default_dir/$theme_file"))
2169                                 continue;
2170                         if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
2171                                 return;
2172                         chmod("$site_dir/$theme_file", 0777);
2173                 }
2174         }
2175         @closedir($theme_dir);
2176
2177         // Rewrite the theme header.
2178         $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
2179         if ($stylelines) {
2180                 $f = fopen("$site_dir/style.css", 'w');
2181
2182                 foreach ($stylelines as $line) {
2183                         if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
2184                         elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
2185                         elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
2186                         elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
2187                         elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
2188                         fwrite($f, $line . "\n");
2189                 }
2190                 fclose($f);
2191         }
2192
2193         // Copy the images.
2194         umask(0);
2195         if (! mkdir("$site_dir/images", 0777)) {
2196                 return false;
2197         }
2198
2199         $images_dir = @ opendir("$default_dir/images");
2200         if ($images_dir) {
2201                 while(($image = readdir($images_dir)) !== false) {
2202                         if (is_dir("$default_dir/images/$image"))
2203                                 continue;
2204                         if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
2205                                 return;
2206                         chmod("$site_dir/images/$image", 0777);
2207                 }
2208         }
2209         @closedir($images_dir);
2210 }
2211
2212 /**
2213  * Creates a site theme.
2214  *
2215  * {@internal Missing Long Description}}
2216  *
2217  * @since 1.5.0
2218  *
2219  * @return false|string
2220  */
2221 function make_site_theme() {
2222         // Name the theme after the blog.
2223         $theme_name = __get_option('blogname');
2224         $template = sanitize_title($theme_name);
2225         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2226
2227         // If the theme already exists, nothing to do.
2228         if ( is_dir($site_dir)) {
2229                 return false;
2230         }
2231
2232         // We must be able to write to the themes dir.
2233         if (! is_writable(WP_CONTENT_DIR . "/themes")) {
2234                 return false;
2235         }
2236
2237         umask(0);
2238         if (! mkdir($site_dir, 0777)) {
2239                 return false;
2240         }
2241
2242         if (file_exists(ABSPATH . 'wp-layout.css')) {
2243                 if (! make_site_theme_from_oldschool($theme_name, $template)) {
2244                         // TODO: rm -rf the site theme directory.
2245                         return false;
2246                 }
2247         } else {
2248                 if (! make_site_theme_from_default($theme_name, $template))
2249                         // TODO: rm -rf the site theme directory.
2250                         return false;
2251         }
2252
2253         // Make the new site theme active.
2254         $current_template = __get_option('template');
2255         if ($current_template == WP_DEFAULT_THEME) {
2256                 update_option('template', $template);
2257                 update_option('stylesheet', $template);
2258         }
2259         return $template;
2260 }
2261
2262 /**
2263  * Translate user level to user role name.
2264  *
2265  * @since 2.0.0
2266  *
2267  * @param int $level User level.
2268  * @return string User role name.
2269  */
2270 function translate_level_to_role($level) {
2271         switch ($level) {
2272         case 10:
2273         case 9:
2274         case 8:
2275                 return 'administrator';
2276         case 7:
2277         case 6:
2278         case 5:
2279                 return 'editor';
2280         case 4:
2281         case 3:
2282         case 2:
2283                 return 'author';
2284         case 1:
2285                 return 'contributor';
2286         case 0:
2287                 return 'subscriber';
2288         }
2289 }
2290
2291 /**
2292  * Checks the version of the installed MySQL binary.
2293  *
2294  * @since 2.1.0
2295  */
2296 function wp_check_mysql_version() {
2297         global $wpdb;
2298         $result = $wpdb->check_database_version();
2299         if ( is_wp_error( $result ) )
2300                 die( $result->get_error_message() );
2301 }
2302
2303 /**
2304  * Disables the Automattic widgets plugin, which was merged into core.
2305  *
2306  * @since 2.2.0
2307  */
2308 function maybe_disable_automattic_widgets() {
2309         $plugins = __get_option( 'active_plugins' );
2310
2311         foreach ( (array) $plugins as $plugin ) {
2312                 if ( basename( $plugin ) == 'widgets.php' ) {
2313                         array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
2314                         update_option( 'active_plugins', $plugins );
2315                         break;
2316                 }
2317         }
2318 }
2319
2320 /**
2321  * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
2322  *
2323  * @since 3.5.0
2324  */
2325 function maybe_disable_link_manager() {
2326         global $wp_current_db_version, $wpdb;
2327
2328         if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
2329                 update_option( 'link_manager_enabled', 0 );
2330 }
2331
2332 /**
2333  * Runs before the schema is upgraded.
2334  *
2335  * @since 2.9.0
2336  */
2337 function pre_schema_upgrade() {
2338         global $wp_current_db_version, $wpdb;
2339
2340         // Upgrade versions prior to 2.9
2341         if ( $wp_current_db_version < 11557 ) {
2342                 // Delete duplicate options. Keep the option with the highest option_id.
2343                 $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id");
2344
2345                 // Drop the old primary key and add the new.
2346                 $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)");
2347
2348                 // Drop the old option_name index. dbDelta() doesn't do the drop.
2349                 $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name");
2350         }
2351
2352         // Multisite schema upgrades.
2353         if ( $wp_current_db_version < 25448 && is_multisite() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && is_main_network() ) {
2354
2355                 // Upgrade verions prior to 3.7
2356                 if ( $wp_current_db_version < 25179 ) {
2357                         // New primary key for signups.
2358                         $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
2359                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
2360                 }
2361
2362                 if ( $wp_current_db_version < 25448 ) {
2363                         // Convert archived from enum to tinyint.
2364                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
2365                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
2366                 }
2367         }
2368
2369         if ( $wp_current_db_version < 30133 ) {
2370                 // dbDelta() can recreate but can't drop the index.
2371                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug" );
2372         }
2373
2374         // Upgrade versions prior to 4.2.
2375         if ( $wp_current_db_version < 31351 ) {
2376                 if ( ! is_multisite() ) {
2377                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2378                 }
2379                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
2380                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
2381                 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2382                 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2383                 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
2384         }
2385 }
2386
2387 /**
2388  * Install global terms.
2389  *
2390  * @since 3.0.0
2391  *
2392  */
2393 if ( !function_exists( 'install_global_terms' ) ) :
2394 function install_global_terms() {
2395         global $wpdb, $charset_collate;
2396         $ms_queries = "
2397 CREATE TABLE $wpdb->sitecategories (
2398   cat_ID bigint(20) NOT NULL auto_increment,
2399   cat_name varchar(55) NOT NULL default '',
2400   category_nicename varchar(200) NOT NULL default '',
2401   last_updated timestamp NOT NULL,
2402   PRIMARY KEY  (cat_ID),
2403   KEY category_nicename (category_nicename),
2404   KEY last_updated (last_updated)
2405 ) $charset_collate;
2406 ";
2407 // now create tables
2408         dbDelta( $ms_queries );
2409 }
2410 endif;