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