]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/includes/upgrade.php
WordPress 4.2.5-scripts
[autoinstalls/wordpress.git] / wp-admin / includes / upgrade.php
1 <?php
2 /**
3  * WordPress Upgrade API
4  *
5  * Most of the functions are pluggable and can be overwritten.
6  *
7  * @package WordPress
8  * @subpackage Administration
9  */
10
11 /** Include user install customize script. */
12 if ( file_exists(WP_CONTENT_DIR . '/install.php') )
13         require (WP_CONTENT_DIR . '/install.php');
14
15 /** WordPress Administration API */
16 require_once(ABSPATH . 'wp-admin/includes/admin.php');
17
18 /** WordPress Schema API */
19 require_once(ABSPATH . 'wp-admin/includes/schema.php');
20
21 if ( !function_exists('wp_install') ) :
22 /**
23  * Installs the site.
24  *
25  * Runs the required functions to set up and populate the database,
26  * including primary admin user and initial options.
27  *
28  * @since 2.1.0
29  *
30  * @param string $blog_title    Blog title.
31  * @param string $user_name     User's username.
32  * @param string $user_email    User's email.
33  * @param bool   $public        Whether blog is public.
34  * @param string $deprecated    Optional. Not used.
35  * @param string $user_password Optional. User's chosen password. Default empty (random password).
36  * @param string $language      Optional. Language chosen. Default empty.
37  * @return array Array keys 'url', 'user_id', 'password', and 'password_message'.
38  */
39 function wp_install( $blog_title, $user_name, $user_email, $public, $deprecated = '', $user_password = '', $language = '' ) {
40         if ( !empty( $deprecated ) )
41                 _deprecated_argument( __FUNCTION__, '2.6' );
42
43         wp_check_mysql_version();
44         wp_cache_flush();
45         make_db_current_silent();
46         populate_options();
47         populate_roles();
48
49         update_option('blogname', $blog_title);
50         update_option('admin_email', $user_email);
51         update_option('blog_public', $public);
52
53         if ( $language ) {
54                 update_option( 'WPLANG', $language );
55         }
56
57         $guessurl = wp_guess_url();
58
59         update_option('siteurl', $guessurl);
60
61         // If not a public blog, don't ping.
62         if ( ! $public )
63                 update_option('default_pingback_flag', 0);
64
65         /*
66          * Create default user. If the user already exists, the user tables are
67          * being shared among blogs. Just set the role in that case.
68          */
69         $user_id = username_exists($user_name);
70         $user_password = trim($user_password);
71         $email_password = false;
72         if ( !$user_id && empty($user_password) ) {
73                 $user_password = wp_generate_password( 12, false );
74                 $message = __('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you.');
75                 $user_id = wp_create_user($user_name, $user_password, $user_email);
76                 update_user_option($user_id, 'default_password_nag', true, true);
77                 $email_password = true;
78         } elseif ( ! $user_id ) {
79                 // Password has been provided
80                 $message = '<em>'.__('Your chosen password.').'</em>';
81                 $user_id = wp_create_user($user_name, $user_password, $user_email);
82         } else {
83                 $message = __('User already exists. Password inherited.');
84         }
85
86         $user = new WP_User($user_id);
87         $user->set_role('administrator');
88
89         wp_install_defaults($user_id);
90
91         wp_install_maybe_enable_pretty_permalinks();
92
93         flush_rewrite_rules();
94
95         wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.') ) );
96
97         wp_cache_flush();
98
99         /**
100          * Fires after a site is fully installed.
101          *
102          * @since 3.9.0
103          *
104          * @param WP_User $user The site owner.
105          */
106         do_action( 'wp_install', $user );
107
108         return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message);
109 }
110 endif;
111
112 if ( !function_exists('wp_install_defaults') ) :
113 /**
114  * Creates the initial content for a newly-installed site.
115  *
116  * Adds the default "Uncategorized" category, the first post (with comment),
117  * first page, and default widgets for default theme for the current version.
118  *
119  * @since 2.1.0
120  *
121  * @param int $user_id User ID.
122  */
123 function wp_install_defaults( $user_id ) {
124         global $wpdb, $wp_rewrite, $table_prefix;
125
126         // Default category
127         $cat_name = __('Uncategorized');
128         /* translators: Default category slug */
129         $cat_slug = sanitize_title(_x('Uncategorized', 'Default category slug'));
130
131         if ( global_terms_enabled() ) {
132                 $cat_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) );
133                 if ( $cat_id == null ) {
134                         $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) );
135                         $cat_id = $wpdb->insert_id;
136                 }
137                 update_option('default_category', $cat_id);
138         } else {
139                 $cat_id = 1;
140         }
141
142         $wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) );
143         $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1));
144         $cat_tt_id = $wpdb->insert_id;
145
146         // First post
147         $now = current_time( 'mysql' );
148         $now_gmt = current_time( 'mysql', 1 );
149         $first_post_guid = get_option( 'home' ) . '/?p=1';
150
151         if ( is_multisite() ) {
152                 $first_post = get_site_option( 'first_post' );
153
154                 if ( empty($first_post) )
155                         $first_post = __( 'Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start blogging!' );
156
157                 $first_post = str_replace( "SITE_URL", esc_url( network_home_url() ), $first_post );
158                 $first_post = str_replace( "SITE_NAME", get_current_site()->site_name, $first_post );
159         } else {
160                 $first_post = __('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!');
161         }
162
163         $wpdb->insert( $wpdb->posts, array(
164                                                                 'post_author' => $user_id,
165                                                                 'post_date' => $now,
166                                                                 'post_date_gmt' => $now_gmt,
167                                                                 'post_content' => $first_post,
168                                                                 'post_excerpt' => '',
169                                                                 'post_title' => __('Hello world!'),
170                                                                 /* translators: Default post slug */
171                                                                 'post_name' => sanitize_title( _x('hello-world', 'Default post slug') ),
172                                                                 'post_modified' => $now,
173                                                                 'post_modified_gmt' => $now_gmt,
174                                                                 'guid' => $first_post_guid,
175                                                                 'comment_count' => 1,
176                                                                 'to_ping' => '',
177                                                                 'pinged' => '',
178                                                                 'post_content_filtered' => ''
179                                                                 ));
180         $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) );
181
182         // Default comment
183         $first_comment_author = __('Mr WordPress');
184         $first_comment_url = 'https://wordpress.org/';
185         $first_comment = __('Hi, this is a comment.
186 To delete a comment, just log in and view the post&#039;s comments. There you will have the option to edit or delete them.');
187         if ( is_multisite() ) {
188                 $first_comment_author = get_site_option( 'first_comment_author', $first_comment_author );
189                 $first_comment_url = get_site_option( 'first_comment_url', network_home_url() );
190                 $first_comment = get_site_option( 'first_comment', $first_comment );
191         }
192         $wpdb->insert( $wpdb->comments, array(
193                                                                 'comment_post_ID' => 1,
194                                                                 'comment_author' => $first_comment_author,
195                                                                 'comment_author_email' => '',
196                                                                 'comment_author_url' => $first_comment_url,
197                                                                 'comment_date' => $now,
198                                                                 'comment_date_gmt' => $now_gmt,
199                                                                 'comment_content' => $first_comment
200                                                                 ));
201
202         // First Page
203         $first_page = sprintf( __( "This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:
204
205 <blockquote>Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my blog. I live in Los Angeles, have a great dog named Jack, and I like pi&#241;a coladas. (And gettin' caught in the rain.)</blockquote>
206
207 ...or something like this:
208
209 <blockquote>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</blockquote>
210
211 As a new WordPress user, you should go to <a href=\"%s\">your dashboard</a> to delete this page and create new pages for your content. Have fun!" ), admin_url() );
212         if ( is_multisite() )
213                 $first_page = get_site_option( 'first_page', $first_page );
214         $first_post_guid = get_option('home') . '/?page_id=2';
215         $wpdb->insert( $wpdb->posts, array(
216                                                                 'post_author' => $user_id,
217                                                                 'post_date' => $now,
218                                                                 'post_date_gmt' => $now_gmt,
219                                                                 'post_content' => $first_page,
220                                                                 'post_excerpt' => '',
221                                                                 'post_title' => __( 'Sample Page' ),
222                                                                 /* translators: Default page slug */
223                                                                 'post_name' => __( 'sample-page' ),
224                                                                 'post_modified' => $now,
225                                                                 'post_modified_gmt' => $now_gmt,
226                                                                 'guid' => $first_post_guid,
227                                                                 'post_type' => 'page',
228                                                                 'to_ping' => '',
229                                                                 'pinged' => '',
230                                                                 'post_content_filtered' => ''
231                                                                 ));
232         $wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) );
233
234         // Set up default widgets for default theme.
235         update_option( 'widget_search', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
236         update_option( 'widget_recent-posts', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
237         update_option( 'widget_recent-comments', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
238         update_option( 'widget_archives', array ( 2 => array ( 'title' => '', 'count' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
239         update_option( 'widget_categories', array ( 2 => array ( 'title' => '', 'count' => 0, 'hierarchical' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
240         update_option( 'widget_meta', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
241         update_option( 'sidebars_widgets', array ( 'wp_inactive_widgets' => array (), 'sidebar-1' => array ( 0 => 'search-2', 1 => 'recent-posts-2', 2 => 'recent-comments-2', 3 => 'archives-2', 4 => 'categories-2', 5 => 'meta-2', ), 'array_version' => 3 ) );
242
243         if ( ! is_multisite() )
244                 update_user_meta( $user_id, 'show_welcome_panel', 1 );
245         elseif ( ! is_super_admin( $user_id ) && ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) )
246                 update_user_meta( $user_id, 'show_welcome_panel', 2 );
247
248         if ( is_multisite() ) {
249                 // Flush rules to pick up the new page.
250                 $wp_rewrite->init();
251                 $wp_rewrite->flush_rules();
252
253                 $user = new WP_User($user_id);
254                 $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') );
255
256                 // Remove all perms except for the login user.
257                 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') );
258                 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') );
259
260                 // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
261                 if ( !is_super_admin( $user_id ) && $user_id != 1 )
262                         $wpdb->delete( $wpdb->usermeta, array( 'user_id' => $user_id , 'meta_key' => $wpdb->base_prefix.'1_capabilities' ) );
263         }
264 }
265 endif;
266
267 /**
268  * Maybe enable pretty permalinks on install.
269  *
270  * If after enabling pretty permalinks don't work, fallback to query-string permalinks.
271  *
272  * @since 4.2.0
273  *
274  * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
275  *
276  * @return bool Whether pretty permalinks are enabled. False otherwise.
277  */
278 function wp_install_maybe_enable_pretty_permalinks() {
279         global $wp_rewrite;
280
281         // Bail if a permalink structure is already enabled.
282         if ( get_option( 'permalink_structure' ) ) {
283                 return true;
284         }
285
286         /*
287          * The Permalink structures to attempt.
288          *
289          * The first is designed for mod_rewrite or nginx rewriting.
290          *
291          * The second is PATHINFO-based permalinks for web server configurations
292          * without a true rewrite module enabled.
293          */
294         $permalink_structures = array(
295                 '/%year%/%monthnum%/%day%/%postname%/',
296                 '/index.php/%year%/%monthnum%/%day%/%postname%/'
297         );
298
299         foreach ( (array) $permalink_structures as $permalink_structure ) {
300                 $wp_rewrite->set_permalink_structure( $permalink_structure );
301
302                 /*
303                  * Flush rules with the hard option to force refresh of the web-server's
304                  * rewrite config file (e.g. .htaccess or web.config).
305                  */
306                 $wp_rewrite->flush_rules( true );
307
308                 // Test against a real WordPress Post, or if none were created, a random 404 page.
309                 $test_url = get_permalink( 1 );
310
311                 if ( ! $test_url ) {
312                         $test_url = home_url( '/wordpress-check-for-rewrites/' );
313                 }
314
315                 /*
316                  * Send a request to the site, and check whether
317                  * the 'x-pingback' header is returned as expected.
318                  *
319                  * Uses wp_remote_get() instead of wp_remote_head() because web servers
320                  * can block head requests.
321                  */
322                 $response          = wp_remote_get( $test_url, array( 'timeout' => 5 ) );
323                 $x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );
324                 $pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );
325
326                 if ( $pretty_permalinks ) {
327                         return true;
328                 }
329         }
330
331         /*
332          * If it makes it this far, pretty permalinks failed.
333          * Fallback to query-string permalinks.
334          */
335         $wp_rewrite->set_permalink_structure( '' );
336         $wp_rewrite->flush_rules( true );
337
338         return false;
339 }
340
341 if ( !function_exists('wp_new_blog_notification') ) :
342 /**
343  * Notifies the site admin that the setup is complete.
344  *
345  * Sends an email with wp_mail to the new administrator that the site setup is complete,
346  * and provides them with a record of their login credentials.
347  *
348  * @since 2.1.0
349  *
350  * @param string $blog_title Blog title.
351  * @param string $blog_url   Blog url.
352  * @param int    $user_id    User ID.
353  * @param string $password   User's Password.
354  */
355 function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) {
356         $user = new WP_User( $user_id );
357         $email = $user->user_email;
358         $name = $user->user_login;
359         $login_url = wp_login_url();
360         $message = sprintf( __( "Your new WordPress site has been successfully set up at:
361
362 %1\$s
363
364 You can log in to the administrator account with the following information:
365
366 Username: %2\$s
367 Password: %3\$s
368 Log in here: %4\$s
369
370 We hope you enjoy your new site. Thanks!
371
372 --The WordPress Team
373 https://wordpress.org/
374 "), $blog_url, $name, $password, $login_url );
375
376         @wp_mail($email, __('New WordPress Site'), $message);
377 }
378 endif;
379
380 if ( !function_exists('wp_upgrade') ) :
381 /**
382  * Runs WordPress Upgrade functions.
383  *
384  * Upgrades the database if needed during a site update.
385  *
386  * @since 2.1.0
387  *
388  * @return null If no update is necessary or site isn't completely installed, null.
389  */
390 function wp_upgrade() {
391         global $wp_current_db_version, $wp_db_version, $wpdb;
392
393         $wp_current_db_version = __get_option('db_version');
394
395         // We are up-to-date. Nothing to do.
396         if ( $wp_db_version == $wp_current_db_version )
397                 return;
398
399         if ( ! is_blog_installed() )
400                 return;
401
402         wp_check_mysql_version();
403         wp_cache_flush();
404         pre_schema_upgrade();
405         make_db_current_silent();
406         upgrade_all();
407         if ( is_multisite() && is_main_site() )
408                 upgrade_network();
409         wp_cache_flush();
410
411         if ( is_multisite() ) {
412                 if ( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) )
413                         $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" );
414                 else
415                         $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" );
416         }
417
418         /**
419          * Fires after a site is fully upgraded.
420          *
421          * @since 3.9.0
422          *
423          * @param int $wp_db_version         The new $wp_db_version.
424          * @param int $wp_current_db_version The old (current) $wp_db_version.
425          */
426         do_action( 'wp_upgrade', $wp_db_version, $wp_current_db_version );
427 }
428 endif;
429
430 /**
431  * Functions to be called in install and upgrade scripts.
432  *
433  * Contains conditional checks to determine which upgrade scripts to run,
434  * based on database version and WP version being updated-to.
435  *
436  * @since 1.0.1
437  *
438  * @return null If no update is necessary, null.
439  */
440 function upgrade_all() {
441         global $wp_current_db_version, $wp_db_version;
442         $wp_current_db_version = __get_option('db_version');
443
444         // We are up-to-date. Nothing to do.
445         if ( $wp_db_version == $wp_current_db_version )
446                 return;
447
448         // If the version is not set in the DB, try to guess the version.
449         if ( empty($wp_current_db_version) ) {
450                 $wp_current_db_version = 0;
451
452                 // If the template option exists, we have 1.5.
453                 $template = __get_option('template');
454                 if ( !empty($template) )
455                         $wp_current_db_version = 2541;
456         }
457
458         if ( $wp_current_db_version < 6039 )
459                 upgrade_230_options_table();
460
461         populate_options();
462
463         if ( $wp_current_db_version < 2541 ) {
464                 upgrade_100();
465                 upgrade_101();
466                 upgrade_110();
467                 upgrade_130();
468         }
469
470         if ( $wp_current_db_version < 3308 )
471                 upgrade_160();
472
473         if ( $wp_current_db_version < 4772 )
474                 upgrade_210();
475
476         if ( $wp_current_db_version < 4351 )
477                 upgrade_old_slugs();
478
479         if ( $wp_current_db_version < 5539 )
480                 upgrade_230();
481
482         if ( $wp_current_db_version < 6124 )
483                 upgrade_230_old_tables();
484
485         if ( $wp_current_db_version < 7499 )
486                 upgrade_250();
487
488         if ( $wp_current_db_version < 7935 )
489                 upgrade_252();
490
491         if ( $wp_current_db_version < 8201 )
492                 upgrade_260();
493
494         if ( $wp_current_db_version < 8989 )
495                 upgrade_270();
496
497         if ( $wp_current_db_version < 10360 )
498                 upgrade_280();
499
500         if ( $wp_current_db_version < 11958 )
501                 upgrade_290();
502
503         if ( $wp_current_db_version < 15260 )
504                 upgrade_300();
505
506         if ( $wp_current_db_version < 19389 )
507                 upgrade_330();
508
509         if ( $wp_current_db_version < 20080 )
510                 upgrade_340();
511
512         if ( $wp_current_db_version < 22422 )
513                 upgrade_350();
514
515         if ( $wp_current_db_version < 25824 )
516                 upgrade_370();
517
518         if ( $wp_current_db_version < 26148 )
519                 upgrade_372();
520
521         if ( $wp_current_db_version < 26691 )
522                 upgrade_380();
523
524         if ( $wp_current_db_version < 29630 )
525                 upgrade_400();
526
527         if ( $wp_current_db_version < 31534 )
528                 upgrade_422();
529
530         if ( $wp_current_db_version < 31536 )
531                 upgrade_423();
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 }
1427
1428 /**
1429  * Execute changes made in WordPress 4.2.1.
1430  *
1431  * @since 4.2.1
1432  */
1433 function upgrade_421() {
1434 }
1435
1436 /**
1437  * Execute changes made in WordPress 4.2.2.
1438  *
1439  * @since 4.2.2
1440  */
1441 function upgrade_422() {
1442         global $wp_current_db_version, $wpdb;
1443
1444         if ( $wp_current_db_version < 31534 ) {
1445                 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' );
1446
1447                 if ( is_wp_error( $content_length ) ) {
1448                         return;
1449                 }
1450
1451                 if ( false === $content_length ) {
1452                         $content_length = array(
1453                                 'type'   => 'byte',
1454                                 'length' => 65535,
1455                         );
1456                 } elseif ( ! is_array( $content_length ) ) {
1457                         $length = (int) $content_length > 0 ? (int) $content_length : 65535;
1458                         $content_length = array(
1459                                 'type'   => 'byte',
1460                                 'length' => $length
1461                         );
1462                 }
1463
1464                 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) {
1465                         // Sites with malformed DB schemas are on their own.
1466                         return;
1467                 }
1468
1469                 $allowed_length = intval( $content_length['length'] ) - 10;
1470
1471                 $comments = $wpdb->get_results(
1472                         "SELECT `comment_ID` FROM `{$wpdb->comments}`
1473                                 WHERE `comment_date_gmt` > '2015-04-26'
1474                                 AND LENGTH( `comment_content` ) >= {$allowed_length}
1475                                 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )"
1476                 );
1477
1478                 foreach ( $comments as $comment ) {
1479                         wp_delete_comment( $comment->comment_ID, true );
1480                 }
1481         }
1482 }
1483
1484 /**
1485  * Execute changes made in WordPress 4.2.0.
1486  *
1487  * @since 4.2.3
1488  */
1489 function upgrade_423() {
1490         global $wp_current_db_version, $wpdb;
1491
1492         if ( $wp_current_db_version < 31536 && $wpdb->charset === 'utf8mb4' ) {
1493                 if ( is_multisite() ) {
1494                         $tables = $wpdb->tables( 'blog' );
1495                 } else {
1496                         $tables = $wpdb->tables( 'all' );
1497                         if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1498                                 $global_tables = $wpdb->tables( 'global' );
1499                                 $tables = array_diff_assoc( $tables, $global_tables );
1500                         }
1501                 }
1502
1503                 foreach ( $tables as $table ) {
1504                         maybe_convert_table_to_utf8mb4( $table );
1505                 }
1506         }
1507 }
1508
1509 /**
1510  * Executes network-level upgrade routines.
1511  *
1512  * @since 3.0.0
1513  */
1514 function upgrade_network() {
1515         global $wp_current_db_version, $wpdb;
1516
1517         // Always.
1518         if ( is_main_network() ) {
1519                 /*
1520                  * Deletes all expired transients. The multi-table delete syntax is used
1521                  * to delete the transient record from table a, and the corresponding
1522                  * transient_timeout record from table b.
1523                  */
1524                 $time = time();
1525                 $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
1526                         WHERE a.meta_key LIKE %s
1527                         AND a.meta_key NOT LIKE %s
1528                         AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1529                         AND b.meta_value < %d";
1530                 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
1531         }
1532
1533         // 2.8.
1534         if ( $wp_current_db_version < 11549 ) {
1535                 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' );
1536                 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' );
1537                 if ( $wpmu_sitewide_plugins ) {
1538                         if ( !$active_sitewide_plugins )
1539                                 $sitewide_plugins = (array) $wpmu_sitewide_plugins;
1540                         else
1541                                 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins );
1542
1543                         update_site_option( 'active_sitewide_plugins', $sitewide_plugins );
1544                 }
1545                 delete_site_option( 'wpmu_sitewide_plugins' );
1546                 delete_site_option( 'deactivated_sitewide_plugins' );
1547
1548                 $start = 0;
1549                 while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) {
1550                         foreach( $rows as $row ) {
1551                                 $value = $row->meta_value;
1552                                 if ( !@unserialize( $value ) )
1553                                         $value = stripslashes( $value );
1554                                 if ( $value !== $row->meta_value ) {
1555                                         update_site_option( $row->meta_key, $value );
1556                                 }
1557                         }
1558                         $start += 20;
1559                 }
1560         }
1561
1562         // 3.0
1563         if ( $wp_current_db_version < 13576 )
1564                 update_site_option( 'global_terms_enabled', '1' );
1565
1566         // 3.3
1567         if ( $wp_current_db_version < 19390 )
1568                 update_site_option( 'initial_db_version', $wp_current_db_version );
1569
1570         if ( $wp_current_db_version < 19470 ) {
1571                 if ( false === get_site_option( 'active_sitewide_plugins' ) )
1572                         update_site_option( 'active_sitewide_plugins', array() );
1573         }
1574
1575         // 3.4
1576         if ( $wp_current_db_version < 20148 ) {
1577                 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name.
1578                 $allowedthemes  = get_site_option( 'allowedthemes'  );
1579                 $allowed_themes = get_site_option( 'allowed_themes' );
1580                 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) {
1581                         $converted = array();
1582                         $themes = wp_get_themes();
1583                         foreach ( $themes as $stylesheet => $theme_data ) {
1584                                 if ( isset( $allowed_themes[ $theme_data->get('Name') ] ) )
1585                                         $converted[ $stylesheet ] = true;
1586                         }
1587                         update_site_option( 'allowedthemes', $converted );
1588                         delete_site_option( 'allowed_themes' );
1589                 }
1590         }
1591
1592         // 3.5
1593         if ( $wp_current_db_version < 21823 )
1594                 update_site_option( 'ms_files_rewriting', '1' );
1595
1596         // 3.5.2
1597         if ( $wp_current_db_version < 24448 ) {
1598                 $illegal_names = get_site_option( 'illegal_names' );
1599                 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) {
1600                         $illegal_name = reset( $illegal_names );
1601                         $illegal_names = explode( ' ', $illegal_name );
1602                         update_site_option( 'illegal_names', $illegal_names );
1603                 }
1604         }
1605
1606         // 4.2
1607         if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1608                 if ( ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1609                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1610                         $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1611                         $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1612                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1613
1614                         $tables = $wpdb->tables( 'global' );
1615
1616                         foreach ( $tables as $table ) {
1617                                 maybe_convert_table_to_utf8mb4( $table );
1618                         }
1619                 }
1620         }
1621
1622         // 4.2.2
1623         if ( $wp_current_db_version < 31535 && 'utf8mb4' === $wpdb->charset ) {
1624                 if ( ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1625                         $upgrade = false;
1626                         $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" );
1627                         foreach( $indexes as $index ) {
1628                                 if ( 'domain_path' == $index->Key_name && 'domain' == $index->Column_name && 140 != $index->Sub_part ) {
1629                                         $upgrade = true;
1630                                         break;
1631                                 }
1632                         }
1633
1634                         if ( $upgrade ) {
1635                                 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1636                         }
1637                 }
1638         }
1639
1640         // 4.2.3
1641         if ( $wp_current_db_version < 31536 && $wpdb->charset === 'utf8mb4' ) {
1642                 if ( ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
1643                         $tables = $wpdb->tables( 'global' );
1644
1645                         foreach ( $tables as $table ) {
1646                                 maybe_convert_table_to_utf8mb4( $table );
1647                         }
1648                 }
1649         }
1650 }
1651
1652 //
1653 // General functions we use to actually do stuff
1654 //
1655
1656 /**
1657  * Creates a table in the database if it doesn't already exist.
1658  *
1659  * This method checks for an existing database and creates a new one if it's not
1660  * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses
1661  * to query all tables first and then run the SQL statement creating the table.
1662  *
1663  * @since 1.0.0
1664  *
1665  * @param string $table_name Database table name to create.
1666  * @param string $create_ddl SQL statement to create table.
1667  * @return bool If table already exists or was created by function.
1668  */
1669 function maybe_create_table($table_name, $create_ddl) {
1670         global $wpdb;
1671
1672         $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
1673
1674         if ( $wpdb->get_var( $query ) == $table_name ) {
1675                 return true;
1676         }
1677
1678         // Didn't find it try to create it..
1679         $wpdb->query($create_ddl);
1680
1681         // We cannot directly tell that whether this succeeded!
1682         if ( $wpdb->get_var( $query ) == $table_name ) {
1683                 return true;
1684         }
1685         return false;
1686 }
1687
1688 /**
1689  * Drops a specified index from a table.
1690  *
1691  * @since 1.0.1
1692  *
1693  * @param string $table Database table name.
1694  * @param string $index Index name to drop.
1695  * @return bool True, when finished.
1696  */
1697 function drop_index($table, $index) {
1698         global $wpdb;
1699         $wpdb->hide_errors();
1700         $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
1701         // Now we need to take out all the extra ones we may have created
1702         for ($i = 0; $i < 25; $i++) {
1703                 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
1704         }
1705         $wpdb->show_errors();
1706         return true;
1707 }
1708
1709 /**
1710  * Adds an index to a specified table.
1711  *
1712  * @since 1.0.1
1713  *
1714  * @param string $table Database table name.
1715  * @param string $index Database table index column.
1716  * @return bool True, when done with execution.
1717  */
1718 function add_clean_index($table, $index) {
1719         global $wpdb;
1720         drop_index($table, $index);
1721         $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
1722         return true;
1723 }
1724
1725 /**
1726  * Adds column to a database table if it doesn't already exist.
1727  *
1728  * @since 1.3.0
1729  *
1730  * @param string $table_name  The table name to modify.
1731  * @param string $column_name The column name to add to the table.
1732  * @param string $create_ddl  The SQL statement used to add the column.
1733  * @return True if already exists or on successful completion, false on error.
1734  */
1735 function maybe_add_column($table_name, $column_name, $create_ddl) {
1736         global $wpdb;
1737         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1738                 if ($column == $column_name) {
1739                         return true;
1740                 }
1741         }
1742
1743         // Didn't find it try to create it.
1744         $wpdb->query($create_ddl);
1745
1746         // We cannot directly tell that whether this succeeded!
1747         foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1748                 if ($column == $column_name) {
1749                         return true;
1750                 }
1751         }
1752         return false;
1753 }
1754
1755 /**
1756  * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4.
1757  *
1758  * @since 4.2.0
1759  *
1760  * @param string $table The table to convert.
1761  * @return bool true if the table was converted, false if it wasn't.
1762  */
1763 function maybe_convert_table_to_utf8mb4( $table ) {
1764         global $wpdb;
1765
1766         $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" );
1767         if ( ! $results ) {
1768                 return false;
1769         }
1770
1771         foreach ( $results as $column ) {
1772                 if ( $column->Collation ) {
1773                         list( $charset ) = explode( '_', $column->Collation );
1774                         $charset = strtolower( $charset );
1775                         if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) {
1776                                 // Don't upgrade tables that have non-utf8 columns.
1777                                 return false;
1778                         }
1779                 }
1780         }
1781
1782         $table_details = $wpdb->get_row( "SHOW TABLE STATUS LIKE '$table'" );
1783         if ( ! $table_details ) {
1784                 return false;
1785         }
1786
1787         list( $table_charset ) = explode( '_', $table_details->Collation );
1788         $table_charset = strtolower( $table_charset );
1789         if ( 'utf8mb4' === $table_charset ) {
1790                 return true;
1791         }
1792
1793         return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
1794 }
1795
1796 /**
1797  * Retrieve all options as it was for 1.2.
1798  *
1799  * @since 1.2.0
1800  *
1801  * @return stdClass List of options.
1802  */
1803 function get_alloptions_110() {
1804         global $wpdb;
1805         $all_options = new stdClass;
1806         if ( $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ) ) {
1807                 foreach ( $options as $option ) {
1808                         if ( 'siteurl' == $option->option_name || 'home' == $option->option_name || 'category_base' == $option->option_name )
1809                                 $option->option_value = untrailingslashit( $option->option_value );
1810                         $all_options->{$option->option_name} = stripslashes( $option->option_value );
1811                 }
1812         }
1813         return $all_options;
1814 }
1815
1816 /**
1817  * Utility version of get_option that is private to install/upgrade.
1818  *
1819  * @ignore
1820  * @since 1.5.1
1821  * @access private
1822  *
1823  * @param string $setting Option name.
1824  * @return mixed
1825  */
1826 function __get_option($setting) {
1827         global $wpdb;
1828
1829         if ( $setting == 'home' && defined( 'WP_HOME' ) )
1830                 return untrailingslashit( WP_HOME );
1831
1832         if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) )
1833                 return untrailingslashit( WP_SITEURL );
1834
1835         $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) );
1836
1837         if ( 'home' == $setting && '' == $option )
1838                 return __get_option( 'siteurl' );
1839
1840         if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting || 'tag_base' == $setting )
1841                 $option = untrailingslashit( $option );
1842
1843         return maybe_unserialize( $option );
1844 }
1845
1846 /**
1847  * Filters for content to remove unnecessary slashes.
1848  *
1849  * @since 1.5.0
1850  *
1851  * @param string $content The content to modify.
1852  * @return string The de-slashed content.
1853  */
1854 function deslash($content) {
1855         // Note: \\\ inside a regex denotes a single backslash.
1856
1857         /*
1858          * Replace one or more backslashes followed by a single quote with
1859          * a single quote.
1860          */
1861         $content = preg_replace("/\\\+'/", "'", $content);
1862
1863         /*
1864          * Replace one or more backslashes followed by a double quote with
1865          * a double quote.
1866          */
1867         $content = preg_replace('/\\\+"/', '"', $content);
1868
1869         // Replace one or more backslashes with one backslash.
1870         $content = preg_replace("/\\\+/", "\\", $content);
1871
1872         return $content;
1873 }
1874
1875 /**
1876  * Modifies the database based on specified SQL statements.
1877  *
1878  * Useful for creating new tables and updating existing tables to a new structure.
1879  *
1880  * @since 1.5.0
1881  *
1882  * @param string|array $queries Optional. The query to run. Can be multiple queries
1883  *                              in an array, or a string of queries separated by
1884  *                              semicolons. Default empty.
1885  * @param bool         $execute Optional. Whether or not to execute the query right away.
1886  *                              Default true.
1887  * @return array Strings containing the results of the various update queries.
1888  */
1889 function dbDelta( $queries = '', $execute = true ) {
1890         global $wpdb;
1891
1892         if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) )
1893             $queries = wp_get_db_schema( $queries );
1894
1895         // Separate individual queries into an array
1896         if ( !is_array($queries) ) {
1897                 $queries = explode( ';', $queries );
1898                 $queries = array_filter( $queries );
1899         }
1900
1901         /**
1902          * Filter the dbDelta SQL queries.
1903          *
1904          * @since 3.3.0
1905          *
1906          * @param array $queries An array of dbDelta SQL queries.
1907          */
1908         $queries = apply_filters( 'dbdelta_queries', $queries );
1909
1910         $cqueries = array(); // Creation Queries
1911         $iqueries = array(); // Insertion Queries
1912         $for_update = array();
1913
1914         // Create a tablename index for an array ($cqueries) of queries
1915         foreach($queries as $qry) {
1916                 if ( preg_match( "|CREATE TABLE ([^ ]*)|", $qry, $matches ) ) {
1917                         $cqueries[ trim( $matches[1], '`' ) ] = $qry;
1918                         $for_update[$matches[1]] = 'Created table '.$matches[1];
1919                 } elseif ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
1920                         array_unshift( $cqueries, $qry );
1921                 } elseif ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
1922                         $iqueries[] = $qry;
1923                 } elseif ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
1924                         $iqueries[] = $qry;
1925                 } else {
1926                         // Unrecognized query type
1927                 }
1928         }
1929
1930         /**
1931          * Filter the dbDelta SQL queries for creating tables and/or databases.
1932          *
1933          * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE".
1934          *
1935          * @since 3.3.0
1936          *
1937          * @param array $cqueries An array of dbDelta create SQL queries.
1938          */
1939         $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries );
1940
1941         /**
1942          * Filter the dbDelta SQL queries for inserting or updating.
1943          *
1944          * Queries filterable via this hook contain "INSERT INTO" or "UPDATE".
1945          *
1946          * @since 3.3.0
1947          *
1948          * @param array $iqueries An array of dbDelta insert or update SQL queries.
1949          */
1950         $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries );
1951
1952         $global_tables = $wpdb->tables( 'global' );
1953         foreach ( $cqueries as $table => $qry ) {
1954                 // Upgrade global tables only for the main site. Don't upgrade at all if DO_NOT_UPGRADE_GLOBAL_TABLES is defined.
1955                 if ( in_array( $table, $global_tables ) && ( !is_main_site() || defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) ) {
1956                         unset( $cqueries[ $table ], $for_update[ $table ] );
1957                         continue;
1958                 }
1959
1960                 // Fetch the table column structure from the database
1961                 $suppress = $wpdb->suppress_errors();
1962                 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
1963                 $wpdb->suppress_errors( $suppress );
1964
1965                 if ( ! $tablefields )
1966                         continue;
1967
1968                 // Clear the field and index arrays.
1969                 $cfields = $indices = array();
1970
1971                 // Get all of the field names in the query from between the parentheses.
1972                 preg_match("|\((.*)\)|ms", $qry, $match2);
1973                 $qryline = trim($match2[1]);
1974
1975                 // Separate field lines into an array.
1976                 $flds = explode("\n", $qryline);
1977
1978                 // todo: Remove this?
1979                 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
1980
1981                 // For every field line specified in the query.
1982                 foreach ($flds as $fld) {
1983
1984                         // Extract the field name.
1985                         preg_match("|^([^ ]*)|", trim($fld), $fvals);
1986                         $fieldname = trim( $fvals[1], '`' );
1987
1988                         // Verify the found field name.
1989                         $validfield = true;
1990                         switch (strtolower($fieldname)) {
1991                         case '':
1992                         case 'primary':
1993                         case 'index':
1994                         case 'fulltext':
1995                         case 'unique':
1996                         case 'key':
1997                                 $validfield = false;
1998                                 $indices[] = trim(trim($fld), ", \n");
1999                                 break;
2000                         }
2001                         $fld = trim($fld);
2002
2003                         // If it's a valid field, add it to the field array.
2004                         if ($validfield) {
2005                                 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
2006                         }
2007                 }
2008
2009                 // For every field in the table.
2010                 foreach ($tablefields as $tablefield) {
2011
2012                         // If the table field exists in the field array ...
2013                         if (array_key_exists(strtolower($tablefield->Field), $cfields)) {
2014
2015                                 // Get the field type from the query.
2016                                 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
2017                                 $fieldtype = $matches[1];
2018
2019                                 // Is actual field type different from the field type in query?
2020                                 if ($tablefield->Type != $fieldtype) {
2021                                         // Add a query to change the column type
2022                                         $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
2023                                         $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
2024                                 }
2025
2026                                 // Get the default value from the array
2027                                         // todo: Remove this?
2028                                         //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
2029                                 if (preg_match("| DEFAULT '(.*?)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
2030                                         $default_value = $matches[1];
2031                                         if ($tablefield->Default != $default_value) {
2032                                                 // Add a query to change the column's default value
2033                                                 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
2034                                                 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
2035                                         }
2036                                 }
2037
2038                                 // Remove the field from the array (so it's not added).
2039                                 unset($cfields[strtolower($tablefield->Field)]);
2040                         } else {
2041                                 // This field exists in the table, but not in the creation queries?
2042                         }
2043                 }
2044
2045                 // For every remaining field specified for the table.
2046                 foreach ($cfields as $fieldname => $fielddef) {
2047                         // Push a query line into $cqueries that adds the field to that table.
2048                         $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
2049                         $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
2050                 }
2051
2052                 // Index stuff goes here. Fetch the table index structure from the database.
2053                 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
2054
2055                 if ($tableindices) {
2056                         // Clear the index array.
2057                         $index_ary = array();
2058
2059                         // For every index in the table.
2060                         foreach ($tableindices as $tableindex) {
2061
2062                                 // Add the index to the index data array.
2063                                 $keyname = $tableindex->Key_name;
2064                                 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
2065                                 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
2066                         }
2067
2068                         // For each actual index in the index array.
2069                         foreach ($index_ary as $index_name => $index_data) {
2070
2071                                 // Build a create string to compare to the query.
2072                                 $index_string = '';
2073                                 if ($index_name == 'PRIMARY') {
2074                                         $index_string .= 'PRIMARY ';
2075                                 } elseif ( $index_data['unique'] ) {
2076                                         $index_string .= 'UNIQUE ';
2077                                 }
2078                                 $index_string .= 'KEY ';
2079                                 if ($index_name != 'PRIMARY') {
2080                                         $index_string .= $index_name;
2081                                 }
2082                                 $index_columns = '';
2083
2084                                 // For each column in the index.
2085                                 foreach ($index_data['columns'] as $column_data) {
2086                                         if ($index_columns != '') $index_columns .= ',';
2087
2088                                         // Add the field to the column list string.
2089                                         $index_columns .= $column_data['fieldname'];
2090                                         if ($column_data['subpart'] != '') {
2091                                                 $index_columns .= '('.$column_data['subpart'].')';
2092                                         }
2093                                 }
2094
2095                                 // The alternative index string doesn't care about subparts
2096                                 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
2097
2098                                 // Add the column list to the index create string.
2099                                 $index_strings = array(
2100                                         "$index_string ($index_columns)",
2101                                         "$index_string ($alt_index_columns)",
2102                                 );
2103
2104                                 foreach( $index_strings as $index_string ) {
2105                                         if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
2106                                                 unset( $indices[ $aindex ] );
2107                                                 break;
2108                                                 // todo: Remove this?
2109                                                 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
2110                                         }
2111                                 }
2112                                 // todo: Remove this?
2113                                 //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";
2114                         }
2115                 }
2116
2117                 // For every remaining index specified for the table.
2118                 foreach ( (array) $indices as $index ) {
2119                         // Push a query line into $cqueries that adds the index to that table.
2120                         $cqueries[] = "ALTER TABLE {$table} ADD $index";
2121                         $for_update[] = 'Added index ' . $table . ' ' . $index;
2122                 }
2123
2124                 // Remove the original table creation query from processing.
2125                 unset( $cqueries[ $table ], $for_update[ $table ] );
2126         }
2127
2128         $allqueries = array_merge($cqueries, $iqueries);
2129         if ($execute) {
2130                 foreach ($allqueries as $query) {
2131                         // todo: Remove this?
2132                         //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
2133                         $wpdb->query($query);
2134                 }
2135         }
2136
2137         return $for_update;
2138 }
2139
2140 /**
2141  * Updates the database tables to a new schema.
2142  *
2143  * By default, updates all the tables to use the latest defined schema, but can also
2144  * be used to update a specific set of tables in wp_get_db_schema().
2145  *
2146  * @since 1.5.0
2147  *
2148  * @uses dbDelta
2149  *
2150  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2151  */
2152 function make_db_current( $tables = 'all' ) {
2153         $alterations = dbDelta( $tables );
2154         echo "<ol>\n";
2155         foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
2156         echo "</ol>\n";
2157 }
2158
2159 /**
2160  * Updates the database tables to a new schema, but without displaying results.
2161  *
2162  * By default, updates all the tables to use the latest defined schema, but can
2163  * also be used to update a specific set of tables in wp_get_db_schema().
2164  *
2165  * @since 1.5.0
2166  *
2167  * @see make_db_current()
2168  *
2169  * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2170  */
2171 function make_db_current_silent( $tables = 'all' ) {
2172         dbDelta( $tables );
2173 }
2174
2175 /**
2176  * Creates a site theme from an existing theme.
2177  *
2178  * {@internal Missing Long Description}}
2179  *
2180  * @since 1.5.0
2181  *
2182  * @param string $theme_name The name of the theme.
2183  * @param string $template   The directory name of the theme.
2184  * @return bool
2185  */
2186 function make_site_theme_from_oldschool($theme_name, $template) {
2187         $home_path = get_home_path();
2188         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2189
2190         if (! file_exists("$home_path/index.php"))
2191                 return false;
2192
2193         /*
2194          * Copy files from the old locations to the site theme.
2195          * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
2196          */
2197         $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
2198
2199         foreach ($files as $oldfile => $newfile) {
2200                 if ($oldfile == 'index.php')
2201                         $oldpath = $home_path;
2202                 else
2203                         $oldpath = ABSPATH;
2204
2205                 // Check to make sure it's not a new index.
2206                 if ($oldfile == 'index.php') {
2207                         $index = implode('', file("$oldpath/$oldfile"));
2208                         if (strpos($index, 'WP_USE_THEMES') !== false) {
2209                                 if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile"))
2210                                         return false;
2211
2212                                 // Don't copy anything.
2213                                 continue;
2214                                 }
2215                 }
2216
2217                 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
2218                         return false;
2219
2220                 chmod("$site_dir/$newfile", 0777);
2221
2222                 // Update the blog header include in each file.
2223                 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
2224                 if ($lines) {
2225                         $f = fopen("$site_dir/$newfile", 'w');
2226
2227                         foreach ($lines as $line) {
2228                                 if (preg_match('/require.*wp-blog-header/', $line))
2229                                         $line = '//' . $line;
2230
2231                                 // Update stylesheet references.
2232                                 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
2233
2234                                 // Update comments template inclusion.
2235                                 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
2236
2237                                 fwrite($f, "{$line}\n");
2238                         }
2239                         fclose($f);
2240                 }
2241         }
2242
2243         // Add a theme header.
2244         $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";
2245
2246         $stylelines = file_get_contents("$site_dir/style.css");
2247         if ($stylelines) {
2248                 $f = fopen("$site_dir/style.css", 'w');
2249
2250                 fwrite($f, $header);
2251                 fwrite($f, $stylelines);
2252                 fclose($f);
2253         }
2254
2255         return true;
2256 }
2257
2258 /**
2259  * Creates a site theme from the default theme.
2260  *
2261  * {@internal Missing Long Description}}
2262  *
2263  * @since 1.5.0
2264  *
2265  * @param string $theme_name The name of the theme.
2266  * @param string $template   The directory name of the theme.
2267  * @return null|false
2268  */
2269 function make_site_theme_from_default($theme_name, $template) {
2270         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2271         $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
2272
2273         // Copy files from the default theme to the site theme.
2274         //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
2275
2276         $theme_dir = @ opendir($default_dir);
2277         if ($theme_dir) {
2278                 while(($theme_file = readdir( $theme_dir )) !== false) {
2279                         if (is_dir("$default_dir/$theme_file"))
2280                                 continue;
2281                         if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
2282                                 return;
2283                         chmod("$site_dir/$theme_file", 0777);
2284                 }
2285         }
2286         @closedir($theme_dir);
2287
2288         // Rewrite the theme header.
2289         $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
2290         if ($stylelines) {
2291                 $f = fopen("$site_dir/style.css", 'w');
2292
2293                 foreach ($stylelines as $line) {
2294                         if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
2295                         elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
2296                         elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
2297                         elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
2298                         elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
2299                         fwrite($f, $line . "\n");
2300                 }
2301                 fclose($f);
2302         }
2303
2304         // Copy the images.
2305         umask(0);
2306         if (! mkdir("$site_dir/images", 0777)) {
2307                 return false;
2308         }
2309
2310         $images_dir = @ opendir("$default_dir/images");
2311         if ($images_dir) {
2312                 while(($image = readdir($images_dir)) !== false) {
2313                         if (is_dir("$default_dir/images/$image"))
2314                                 continue;
2315                         if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
2316                                 return;
2317                         chmod("$site_dir/images/$image", 0777);
2318                 }
2319         }
2320         @closedir($images_dir);
2321 }
2322
2323 /**
2324  * Creates a site theme.
2325  *
2326  * {@internal Missing Long Description}}
2327  *
2328  * @since 1.5.0
2329  *
2330  * @return false|string
2331  */
2332 function make_site_theme() {
2333         // Name the theme after the blog.
2334         $theme_name = __get_option('blogname');
2335         $template = sanitize_title($theme_name);
2336         $site_dir = WP_CONTENT_DIR . "/themes/$template";
2337
2338         // If the theme already exists, nothing to do.
2339         if ( is_dir($site_dir)) {
2340                 return false;
2341         }
2342
2343         // We must be able to write to the themes dir.
2344         if (! is_writable(WP_CONTENT_DIR . "/themes")) {
2345                 return false;
2346         }
2347
2348         umask(0);
2349         if (! mkdir($site_dir, 0777)) {
2350                 return false;
2351         }
2352
2353         if (file_exists(ABSPATH . 'wp-layout.css')) {
2354                 if (! make_site_theme_from_oldschool($theme_name, $template)) {
2355                         // TODO: rm -rf the site theme directory.
2356                         return false;
2357                 }
2358         } else {
2359                 if (! make_site_theme_from_default($theme_name, $template))
2360                         // TODO: rm -rf the site theme directory.
2361                         return false;
2362         }
2363
2364         // Make the new site theme active.
2365         $current_template = __get_option('template');
2366         if ($current_template == WP_DEFAULT_THEME) {
2367                 update_option('template', $template);
2368                 update_option('stylesheet', $template);
2369         }
2370         return $template;
2371 }
2372
2373 /**
2374  * Translate user level to user role name.
2375  *
2376  * @since 2.0.0
2377  *
2378  * @param int $level User level.
2379  * @return string User role name.
2380  */
2381 function translate_level_to_role($level) {
2382         switch ($level) {
2383         case 10:
2384         case 9:
2385         case 8:
2386                 return 'administrator';
2387         case 7:
2388         case 6:
2389         case 5:
2390                 return 'editor';
2391         case 4:
2392         case 3:
2393         case 2:
2394                 return 'author';
2395         case 1:
2396                 return 'contributor';
2397         case 0:
2398                 return 'subscriber';
2399         }
2400 }
2401
2402 /**
2403  * Checks the version of the installed MySQL binary.
2404  *
2405  * @since 2.1.0
2406  */
2407 function wp_check_mysql_version() {
2408         global $wpdb;
2409         $result = $wpdb->check_database_version();
2410         if ( is_wp_error( $result ) )
2411                 die( $result->get_error_message() );
2412 }
2413
2414 /**
2415  * Disables the Automattic widgets plugin, which was merged into core.
2416  *
2417  * @since 2.2.0
2418  */
2419 function maybe_disable_automattic_widgets() {
2420         $plugins = __get_option( 'active_plugins' );
2421
2422         foreach ( (array) $plugins as $plugin ) {
2423                 if ( basename( $plugin ) == 'widgets.php' ) {
2424                         array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
2425                         update_option( 'active_plugins', $plugins );
2426                         break;
2427                 }
2428         }
2429 }
2430
2431 /**
2432  * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
2433  *
2434  * @since 3.5.0
2435  */
2436 function maybe_disable_link_manager() {
2437         global $wp_current_db_version, $wpdb;
2438
2439         if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
2440                 update_option( 'link_manager_enabled', 0 );
2441 }
2442
2443 /**
2444  * Runs before the schema is upgraded.
2445  *
2446  * @since 2.9.0
2447  */
2448 function pre_schema_upgrade() {
2449         global $wp_current_db_version, $wpdb;
2450
2451         // Upgrade versions prior to 2.9
2452         if ( $wp_current_db_version < 11557 ) {
2453                 // Delete duplicate options. Keep the option with the highest option_id.
2454                 $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id");
2455
2456                 // Drop the old primary key and add the new.
2457                 $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)");
2458
2459                 // Drop the old option_name index. dbDelta() doesn't do the drop.
2460                 $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name");
2461         }
2462
2463         // Multisite schema upgrades.
2464         if ( $wp_current_db_version < 25448 && is_multisite() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) && is_main_network() ) {
2465
2466                 // Upgrade verions prior to 3.7
2467                 if ( $wp_current_db_version < 25179 ) {
2468                         // New primary key for signups.
2469                         $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
2470                         $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
2471                 }
2472
2473                 if ( $wp_current_db_version < 25448 ) {
2474                         // Convert archived from enum to tinyint.
2475                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
2476                         $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
2477                 }
2478         }
2479
2480         // Upgrade versions prior to 4.2.
2481         if ( $wp_current_db_version < 31351 ) {
2482                 if ( ! is_multisite() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
2483                         $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2484                 }
2485                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
2486                 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
2487                 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2488                 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2489                 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
2490         }
2491 }
2492
2493 /**
2494  * Install global terms.
2495  *
2496  * @since 3.0.0
2497  *
2498  */
2499 if ( !function_exists( 'install_global_terms' ) ) :
2500 function install_global_terms() {
2501         global $wpdb, $charset_collate;
2502         $ms_queries = "
2503 CREATE TABLE $wpdb->sitecategories (
2504   cat_ID bigint(20) NOT NULL auto_increment,
2505   cat_name varchar(55) NOT NULL default '',
2506   category_nicename varchar(200) NOT NULL default '',
2507   last_updated timestamp NOT NULL,
2508   PRIMARY KEY  (cat_ID),
2509   KEY category_nicename (category_nicename),
2510   KEY last_updated (last_updated)
2511 ) $charset_collate;
2512 ";
2513 // now create tables
2514         dbDelta( $ms_queries );
2515 }
2516 endif;