3 * WordPress Upgrade API
5 * Most of the functions are pluggable and can be overwritten.
8 * @subpackage Administration
11 /** Include user install customize script. */
12 if ( file_exists(WP_CONTENT_DIR . '/install.php') )
13 require (WP_CONTENT_DIR . '/install.php');
15 /** WordPress Administration API */
16 require_once(ABSPATH . 'wp-admin/includes/admin.php');
18 /** WordPress Schema API */
19 require_once(ABSPATH . 'wp-admin/includes/schema.php');
21 if ( !function_exists('wp_install') ) :
25 * Runs the required functions to set up and populate the database,
26 * including primary admin user and initial options.
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'.
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' );
43 wp_check_mysql_version();
45 make_db_current_silent();
49 update_option('blogname', $blog_title);
50 update_option('admin_email', $user_email);
51 update_option('blog_public', $public);
54 update_option( 'WPLANG', $language );
57 $guessurl = wp_guess_url();
59 update_option('siteurl', $guessurl);
61 // If not a public blog, don't ping.
63 update_option('default_pingback_flag', 0);
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.
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);
83 $message = __('User already exists. Password inherited.');
86 $user = new WP_User($user_id);
87 $user->set_role('administrator');
89 wp_install_defaults($user_id);
91 wp_install_maybe_enable_pretty_permalinks();
93 flush_rewrite_rules();
95 wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.') ) );
100 * Fires after a site is fully installed.
104 * @param WP_User $user The site owner.
106 do_action( 'wp_install', $user );
108 return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message);
112 if ( !function_exists('wp_install_defaults') ) :
114 * Creates the initial content for a newly-installed site.
116 * Adds the default "Uncategorized" category, the first post (with comment),
117 * first page, and default widgets for default theme for the current version.
122 * @global WP_Rewrite $wp_rewrite
123 * @global string $table_prefix
125 * @param int $user_id User ID.
127 function wp_install_defaults( $user_id ) {
128 global $wpdb, $wp_rewrite, $table_prefix;
131 $cat_name = __('Uncategorized');
132 /* translators: Default category slug */
133 $cat_slug = sanitize_title(_x('Uncategorized', 'Default category slug'));
135 if ( global_terms_enabled() ) {
136 $cat_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) );
137 if ( $cat_id == null ) {
138 $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) );
139 $cat_id = $wpdb->insert_id;
141 update_option('default_category', $cat_id);
146 $wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) );
147 $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1));
148 $cat_tt_id = $wpdb->insert_id;
151 $now = current_time( 'mysql' );
152 $now_gmt = current_time( 'mysql', 1 );
153 $first_post_guid = get_option( 'home' ) . '/?p=1';
155 if ( is_multisite() ) {
156 $first_post = get_site_option( 'first_post' );
158 if ( empty($first_post) )
159 $first_post = __( 'Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start writing!' );
161 $first_post = str_replace( "SITE_URL", esc_url( network_home_url() ), $first_post );
162 $first_post = str_replace( "SITE_NAME", get_current_site()->site_name, $first_post );
164 $first_post = __( 'Welcome to WordPress. This is your first post. Edit or delete it, then start writing!' );
167 $wpdb->insert( $wpdb->posts, array(
168 'post_author' => $user_id,
170 'post_date_gmt' => $now_gmt,
171 'post_content' => $first_post,
172 'post_excerpt' => '',
173 'post_title' => __('Hello world!'),
174 /* translators: Default post slug */
175 'post_name' => sanitize_title( _x('hello-world', 'Default post slug') ),
176 'post_modified' => $now,
177 'post_modified_gmt' => $now_gmt,
178 'guid' => $first_post_guid,
179 'comment_count' => 1,
182 'post_content_filtered' => ''
184 $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) );
187 $first_comment_author = __('Mr WordPress');
188 $first_comment_url = 'https://wordpress.org/';
189 $first_comment = __('Hi, this is a comment.
190 To delete a comment, just log in and view the post's comments. There you will have the option to edit or delete them.');
191 if ( is_multisite() ) {
192 $first_comment_author = get_site_option( 'first_comment_author', $first_comment_author );
193 $first_comment_url = get_site_option( 'first_comment_url', network_home_url() );
194 $first_comment = get_site_option( 'first_comment', $first_comment );
196 $wpdb->insert( $wpdb->comments, array(
197 'comment_post_ID' => 1,
198 'comment_author' => $first_comment_author,
199 'comment_author_email' => '',
200 'comment_author_url' => $first_comment_url,
201 'comment_date' => $now,
202 'comment_date_gmt' => $now_gmt,
203 'comment_content' => $first_comment
207 $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:
209 <blockquote>Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)</blockquote>
211 ...or something like this:
213 <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>
215 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() );
216 if ( is_multisite() )
217 $first_page = get_site_option( 'first_page', $first_page );
218 $first_post_guid = get_option('home') . '/?page_id=2';
219 $wpdb->insert( $wpdb->posts, array(
220 'post_author' => $user_id,
222 'post_date_gmt' => $now_gmt,
223 'post_content' => $first_page,
224 'post_excerpt' => '',
225 'post_title' => __( 'Sample Page' ),
226 /* translators: Default page slug */
227 'post_name' => __( 'sample-page' ),
228 'post_modified' => $now,
229 'post_modified_gmt' => $now_gmt,
230 'guid' => $first_post_guid,
231 'post_type' => 'page',
234 'post_content_filtered' => ''
236 $wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) );
238 // Set up default widgets for default theme.
239 update_option( 'widget_search', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
240 update_option( 'widget_recent-posts', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
241 update_option( 'widget_recent-comments', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
242 update_option( 'widget_archives', array ( 2 => array ( 'title' => '', 'count' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
243 update_option( 'widget_categories', array ( 2 => array ( 'title' => '', 'count' => 0, 'hierarchical' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
244 update_option( 'widget_meta', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
245 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 ) );
247 if ( ! is_multisite() )
248 update_user_meta( $user_id, 'show_welcome_panel', 1 );
249 elseif ( ! is_super_admin( $user_id ) && ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) )
250 update_user_meta( $user_id, 'show_welcome_panel', 2 );
252 if ( is_multisite() ) {
253 // Flush rules to pick up the new page.
255 $wp_rewrite->flush_rules();
257 $user = new WP_User($user_id);
258 $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') );
260 // Remove all perms except for the login user.
261 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') );
262 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') );
264 // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
265 if ( !is_super_admin( $user_id ) && $user_id != 1 )
266 $wpdb->delete( $wpdb->usermeta, array( 'user_id' => $user_id , 'meta_key' => $wpdb->base_prefix.'1_capabilities' ) );
272 * Maybe enable pretty permalinks on install.
274 * If after enabling pretty permalinks don't work, fallback to query-string permalinks.
278 * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
280 * @return bool Whether pretty permalinks are enabled. False otherwise.
282 function wp_install_maybe_enable_pretty_permalinks() {
285 // Bail if a permalink structure is already enabled.
286 if ( get_option( 'permalink_structure' ) ) {
291 * The Permalink structures to attempt.
293 * The first is designed for mod_rewrite or nginx rewriting.
295 * The second is PATHINFO-based permalinks for web server configurations
296 * without a true rewrite module enabled.
298 $permalink_structures = array(
299 '/%year%/%monthnum%/%day%/%postname%/',
300 '/index.php/%year%/%monthnum%/%day%/%postname%/'
303 foreach ( (array) $permalink_structures as $permalink_structure ) {
304 $wp_rewrite->set_permalink_structure( $permalink_structure );
307 * Flush rules with the hard option to force refresh of the web-server's
308 * rewrite config file (e.g. .htaccess or web.config).
310 $wp_rewrite->flush_rules( true );
312 // Test against a real WordPress Post, or if none were created, a random 404 page.
313 $test_url = get_permalink( 1 );
316 $test_url = home_url( '/wordpress-check-for-rewrites/' );
320 * Send a request to the site, and check whether
321 * the 'x-pingback' header is returned as expected.
323 * Uses wp_remote_get() instead of wp_remote_head() because web servers
324 * can block head requests.
326 $response = wp_remote_get( $test_url, array( 'timeout' => 5 ) );
327 $x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );
328 $pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );
330 if ( $pretty_permalinks ) {
336 * If it makes it this far, pretty permalinks failed.
337 * Fallback to query-string permalinks.
339 $wp_rewrite->set_permalink_structure( '' );
340 $wp_rewrite->flush_rules( true );
345 if ( !function_exists('wp_new_blog_notification') ) :
347 * Notifies the site admin that the setup is complete.
349 * Sends an email with wp_mail to the new administrator that the site setup is complete,
350 * and provides them with a record of their login credentials.
354 * @param string $blog_title Blog title.
355 * @param string $blog_url Blog url.
356 * @param int $user_id User ID.
357 * @param string $password User's Password.
359 function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) {
360 $user = new WP_User( $user_id );
361 $email = $user->user_email;
362 $name = $user->user_login;
363 $login_url = wp_login_url();
364 $message = sprintf( __( "Your new WordPress site has been successfully set up at:
368 You can log in to the administrator account with the following information:
374 We hope you enjoy your new site. Thanks!
377 https://wordpress.org/
378 "), $blog_url, $name, $password, $login_url );
380 @wp_mail($email, __('New WordPress Site'), $message);
384 if ( !function_exists('wp_upgrade') ) :
386 * Runs WordPress Upgrade functions.
388 * Upgrades the database if needed during a site update.
392 * @global int $wp_current_db_version
393 * @global int $wp_db_version
396 function wp_upgrade() {
397 global $wp_current_db_version, $wp_db_version, $wpdb;
399 $wp_current_db_version = __get_option('db_version');
401 // We are up-to-date. Nothing to do.
402 if ( $wp_db_version == $wp_current_db_version )
405 if ( ! is_blog_installed() )
408 wp_check_mysql_version();
410 pre_schema_upgrade();
411 make_db_current_silent();
413 if ( is_multisite() && is_main_site() )
417 if ( is_multisite() ) {
418 if ( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) )
419 $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" );
421 $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" );
425 * Fires after a site is fully upgraded.
429 * @param int $wp_db_version The new $wp_db_version.
430 * @param int $wp_current_db_version The old (current) $wp_db_version.
432 do_action( 'wp_upgrade', $wp_db_version, $wp_current_db_version );
437 * Functions to be called in install and upgrade scripts.
439 * Contains conditional checks to determine which upgrade scripts to run,
440 * based on database version and WP version being updated-to.
444 * @global int $wp_current_db_version
445 * @global int $wp_db_version
447 function upgrade_all() {
448 global $wp_current_db_version, $wp_db_version;
449 $wp_current_db_version = __get_option('db_version');
451 // We are up-to-date. Nothing to do.
452 if ( $wp_db_version == $wp_current_db_version )
455 // If the version is not set in the DB, try to guess the version.
456 if ( empty($wp_current_db_version) ) {
457 $wp_current_db_version = 0;
459 // If the template option exists, we have 1.5.
460 $template = __get_option('template');
461 if ( !empty($template) )
462 $wp_current_db_version = 2541;
465 if ( $wp_current_db_version < 6039 )
466 upgrade_230_options_table();
470 if ( $wp_current_db_version < 2541 ) {
477 if ( $wp_current_db_version < 3308 )
480 if ( $wp_current_db_version < 4772 )
483 if ( $wp_current_db_version < 4351 )
486 if ( $wp_current_db_version < 5539 )
489 if ( $wp_current_db_version < 6124 )
490 upgrade_230_old_tables();
492 if ( $wp_current_db_version < 7499 )
495 if ( $wp_current_db_version < 7935 )
498 if ( $wp_current_db_version < 8201 )
501 if ( $wp_current_db_version < 8989 )
504 if ( $wp_current_db_version < 10360 )
507 if ( $wp_current_db_version < 11958 )
510 if ( $wp_current_db_version < 15260 )
513 if ( $wp_current_db_version < 19389 )
516 if ( $wp_current_db_version < 20080 )
519 if ( $wp_current_db_version < 22422 )
522 if ( $wp_current_db_version < 25824 )
525 if ( $wp_current_db_version < 26148 )
528 if ( $wp_current_db_version < 26691 )
531 if ( $wp_current_db_version < 29630 )
534 if ( $wp_current_db_version < 33055 )
537 maybe_disable_link_manager();
539 maybe_disable_automattic_widgets();
541 update_option( 'db_version', $wp_db_version );
542 update_option( 'db_upgraded', true );
546 * Execute changes made in WordPress 1.0.
552 function upgrade_100() {
555 // Get the title and ID of every post, post_name to check if it already has a value
556 $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
558 foreach($posts as $post) {
559 if ('' == $post->post_name) {
560 $newtitle = sanitize_title($post->post_title);
561 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID) );
566 $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
567 foreach ($categories as $category) {
568 if ('' == $category->category_nicename) {
569 $newtitle = sanitize_title($category->cat_name);
570 $wpdb->update( $wpdb->categories, array('category_nicename' => $newtitle), array('cat_ID' => $category->cat_ID) );
574 $sql = "UPDATE $wpdb->options
575 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
576 WHERE option_name LIKE %s
577 AND option_value LIKE %s";
578 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) );
580 $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
582 $done_posts = array();
583 foreach ($done_ids as $done_id) :
584 $done_posts[] = $done_id->post_id;
586 $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
591 $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
593 foreach ($allposts as $post) {
594 // Check to see if it's already been imported
595 $cat = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category) );
596 if (!$cat && 0 != $post->post_category) { // If there's no result
597 $wpdb->insert( $wpdb->post2cat, array('post_id' => $post->ID, 'category_id' => $post->post_category) );
604 * Execute changes made in WordPress 1.0.1.
610 function upgrade_101() {
613 // Clean up indices, add a few
614 add_clean_index($wpdb->posts, 'post_name');
615 add_clean_index($wpdb->posts, 'post_status');
616 add_clean_index($wpdb->categories, 'category_nicename');
617 add_clean_index($wpdb->comments, 'comment_approved');
618 add_clean_index($wpdb->comments, 'comment_post_ID');
619 add_clean_index($wpdb->links , 'link_category');
620 add_clean_index($wpdb->links , 'link_visible');
624 * Execute changes made in WordPress 1.2.
630 function upgrade_110() {
633 // Set user_nicename.
634 $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
635 foreach ($users as $user) {
636 if ('' == $user->user_nicename) {
637 $newname = sanitize_title($user->user_nickname);
638 $wpdb->update( $wpdb->users, array('user_nicename' => $newname), array('ID' => $user->ID) );
642 $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
643 foreach ($users as $row) {
644 if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
645 $wpdb->update( $wpdb->users, array('user_pass' => md5($row->user_pass)), array('ID' => $row->ID) );
649 // Get the GMT offset, we'll use that later on
650 $all_options = get_alloptions_110();
652 $time_difference = $all_options->time_difference;
654 $server_time = time()+date('Z');
655 $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS;
658 $diff_gmt_server = ($gmt_time - $server_time) / HOUR_IN_SECONDS;
659 $diff_weblogger_server = ($weblogger_time - $server_time) / HOUR_IN_SECONDS;
660 $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
661 $gmt_offset = -$diff_gmt_weblogger;
663 // Add a gmt_offset option, with value $gmt_offset
664 add_option('gmt_offset', $gmt_offset);
666 // Check if we already set the GMT fields (if we did, then
667 // MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
668 // <michel_v> I just slapped myself silly for not thinking about it earlier
669 $got_gmt_fields = ! ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00');
671 if (!$got_gmt_fields) {
673 // Add or subtract time to all dates, to get GMT dates
674 $add_hours = intval($diff_gmt_weblogger);
675 $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
676 $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
677 $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
678 $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'");
679 $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
680 $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
686 * Execute changes made in WordPress 1.5.
692 function upgrade_130() {
695 // Remove extraneous backslashes.
696 $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
698 foreach($posts as $post) {
699 $post_content = addslashes(deslash($post->post_content));
700 $post_title = addslashes(deslash($post->post_title));
701 $post_excerpt = addslashes(deslash($post->post_excerpt));
702 if ( empty($post->guid) )
703 $guid = get_permalink($post->ID);
707 $wpdb->update( $wpdb->posts, compact('post_title', 'post_content', 'post_excerpt', 'guid'), array('ID' => $post->ID) );
712 // Remove extraneous backslashes.
713 $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
715 foreach($comments as $comment) {
716 $comment_content = deslash($comment->comment_content);
717 $comment_author = deslash($comment->comment_author);
719 $wpdb->update($wpdb->comments, compact('comment_content', 'comment_author'), array('comment_ID' => $comment->comment_ID) );
723 // Remove extraneous backslashes.
724 $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
726 foreach($links as $link) {
727 $link_name = deslash($link->link_name);
728 $link_description = deslash($link->link_description);
730 $wpdb->update( $wpdb->links, compact('link_name', 'link_description'), array('link_id' => $link->link_id) );
734 $active_plugins = __get_option('active_plugins');
737 * If plugins are not stored in an array, they're stored in the old
738 * newline separated format. Convert to new format.
740 if ( !is_array( $active_plugins ) ) {
741 $active_plugins = explode("\n", trim($active_plugins));
742 update_option('active_plugins', $active_plugins);
746 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues');
747 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes');
748 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups');
749 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options');
751 // Update comments table to use comment_type
752 $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
753 $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
755 // Some versions have multiple duplicate option_name rows with the same values
756 $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
757 foreach ( $options as $option ) {
758 if ( 1 != $option->dupes ) { // Could this be done in the query?
759 $limit = $option->dupes - 1;
760 $dupe_ids = $wpdb->get_col( $wpdb->prepare("SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit) );
762 $dupe_ids = join($dupe_ids, ',');
763 $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
772 * Execute changes made in WordPress 2.0.
777 * @global int $wp_current_db_version
779 function upgrade_160() {
780 global $wpdb, $wp_current_db_version;
782 populate_roles_160();
784 $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
785 foreach ( $users as $user ) :
786 if ( !empty( $user->user_firstname ) )
787 update_user_meta( $user->ID, 'first_name', wp_slash($user->user_firstname) );
788 if ( !empty( $user->user_lastname ) )
789 update_user_meta( $user->ID, 'last_name', wp_slash($user->user_lastname) );
790 if ( !empty( $user->user_nickname ) )
791 update_user_meta( $user->ID, 'nickname', wp_slash($user->user_nickname) );
792 if ( !empty( $user->user_level ) )
793 update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level );
794 if ( !empty( $user->user_icq ) )
795 update_user_meta( $user->ID, 'icq', wp_slash($user->user_icq) );
796 if ( !empty( $user->user_aim ) )
797 update_user_meta( $user->ID, 'aim', wp_slash($user->user_aim) );
798 if ( !empty( $user->user_msn ) )
799 update_user_meta( $user->ID, 'msn', wp_slash($user->user_msn) );
800 if ( !empty( $user->user_yim ) )
801 update_user_meta( $user->ID, 'yim', wp_slash($user->user_icq) );
802 if ( !empty( $user->user_description ) )
803 update_user_meta( $user->ID, 'description', wp_slash($user->user_description) );
805 if ( isset( $user->user_idmode ) ):
806 $idmode = $user->user_idmode;
807 if ($idmode == 'nickname') $id = $user->user_nickname;
808 if ($idmode == 'login') $id = $user->user_login;
809 if ($idmode == 'firstname') $id = $user->user_firstname;
810 if ($idmode == 'lastname') $id = $user->user_lastname;
811 if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
812 if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
813 if (!$idmode) $id = $user->user_nickname;
814 $wpdb->update( $wpdb->users, array('display_name' => $id), array('ID' => $user->ID) );
817 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
818 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities');
819 if ( empty($caps) || defined('RESET_CAPS') ) {
820 $level = get_user_meta($user->ID, $wpdb->prefix . 'user_level', true);
821 $role = translate_level_to_role($level);
822 update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) );
826 $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' );
827 $wpdb->hide_errors();
828 foreach ( $old_user_fields as $old )
829 $wpdb->query("ALTER TABLE $wpdb->users DROP $old");
830 $wpdb->show_errors();
832 // Populate comment_count field of posts table.
833 $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
834 if ( is_array( $comments ) )
835 foreach ($comments as $comment)
836 $wpdb->update( $wpdb->posts, array('comment_count' => $comment->c), array('ID' => $comment->comment_post_ID) );
839 * Some alpha versions used a post status of object instead of attachment
840 * and put the mime type in post_type instead of post_mime_type.
842 if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
843 $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
844 foreach ($objects as $object) {
845 $wpdb->update( $wpdb->posts, array( 'post_status' => 'attachment',
846 'post_mime_type' => $object->post_type,
848 array( 'ID' => $object->ID ) );
850 $meta = get_post_meta($object->ID, 'imagedata', true);
851 if ( ! empty($meta['file']) )
852 update_attached_file( $object->ID, $meta['file'] );
858 * Execute changes made in WordPress 2.1.
863 * @global int $wp_current_db_version
865 function upgrade_210() {
866 global $wpdb, $wp_current_db_version;
868 if ( $wp_current_db_version < 3506 ) {
869 // Update status and type.
870 $posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts");
872 if ( ! empty($posts) ) foreach ($posts as $post) {
873 $status = $post->post_status;
876 if ( 'static' == $status ) {
879 } elseif ( 'attachment' == $status ) {
881 $type = 'attachment';
884 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID) );
888 if ( $wp_current_db_version < 3845 ) {
889 populate_roles_210();
892 if ( $wp_current_db_version < 3531 ) {
893 // Give future posts a post_status of future.
894 $now = gmdate('Y-m-d H:i:59');
895 $wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'");
897 $posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'");
898 if ( !empty($posts) )
899 foreach ( $posts as $post )
900 wp_schedule_single_event(mysql2date('U', $post->post_date, false), 'publish_future_post', array($post->ID));
905 * Execute changes made in WordPress 2.3.
910 * @global int $wp_current_db_version
912 function upgrade_230() {
913 global $wp_current_db_version, $wpdb;
915 if ( $wp_current_db_version < 5200 ) {
916 populate_roles_230();
919 // Convert categories to terms.
922 $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID");
923 foreach ($categories as $category) {
924 $term_id = (int) $category->cat_ID;
925 $name = $category->cat_name;
926 $description = $category->category_description;
927 $slug = $category->category_nicename;
928 $parent = $category->category_parent;
931 // Associate terms with the same slug in a term group and make slugs unique.
932 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
933 $term_group = $exists[0]->term_group;
934 $id = $exists[0]->term_id;
937 $alt_slug = $slug . "-$num";
939 $slug_check = $wpdb->get_var( $wpdb->prepare("SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug) );
940 } while ( $slug_check );
944 if ( empty( $term_group ) ) {
945 $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
946 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id) );
950 $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES
951 (%d, %s, %s, %d)", $term_id, $name, $slug, $term_group) );
954 if ( !empty($category->category_count) ) {
955 $count = (int) $category->category_count;
956 $taxonomy = 'category';
957 $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) );
958 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
961 if ( !empty($category->link_count) ) {
962 $count = (int) $category->link_count;
963 $taxonomy = 'link_category';
964 $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) );
965 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
968 if ( !empty($category->tag_count) ) {
970 $count = (int) $category->tag_count;
971 $taxonomy = 'post_tag';
972 $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
973 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
976 if ( empty($count) ) {
978 $taxonomy = 'category';
979 $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
980 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
984 $select = 'post_id, category_id';
986 $select .= ', rel_type';
988 $posts = $wpdb->get_results("SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id");
989 foreach ( $posts as $post ) {
990 $post_id = (int) $post->post_id;
991 $term_id = (int) $post->category_id;
992 $taxonomy = 'category';
993 if ( !empty($post->rel_type) && 'tag' == $post->rel_type)
995 $tt_id = $tt_ids[$term_id][$taxonomy];
999 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $post_id, 'term_taxonomy_id' => $tt_id) );
1002 // < 3570 we used linkcategories. >= 3570 we used categories and link2cat.
1003 if ( $wp_current_db_version < 3570 ) {
1005 * Create link_category terms for link categories. Create a map of link
1006 * cat IDs to link_category terms.
1008 $link_cat_id_map = array();
1009 $default_link_cat = 0;
1011 $link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories');
1012 foreach ( $link_cats as $category) {
1013 $cat_id = (int) $category->cat_id;
1015 $name = wp_slash($category->cat_name);
1016 $slug = sanitize_title($name);
1019 // Associate terms with the same slug in a term group and make slugs unique.
1020 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
1021 $term_group = $exists[0]->term_group;
1022 $term_id = $exists[0]->term_id;
1025 if ( empty($term_id) ) {
1026 $wpdb->insert( $wpdb->terms, compact('name', 'slug', 'term_group') );
1027 $term_id = (int) $wpdb->insert_id;
1030 $link_cat_id_map[$cat_id] = $term_id;
1031 $default_link_cat = $term_id;
1033 $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $term_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 0) );
1034 $tt_ids[$term_id] = (int) $wpdb->insert_id;
1037 // Associate links to cats.
1038 $links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links");
1039 if ( !empty($links) ) foreach ( $links as $link ) {
1040 if ( 0 == $link->link_category )
1042 if ( ! isset($link_cat_id_map[$link->link_category]) )
1044 $term_id = $link_cat_id_map[$link->link_category];
1045 $tt_id = $tt_ids[$term_id];
1046 if ( empty($tt_id) )
1049 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link->link_id, 'term_taxonomy_id' => $tt_id) );
1052 // Set default to the last category we grabbed during the upgrade loop.
1053 update_option('default_link_category', $default_link_cat);
1055 $links = $wpdb->get_results("SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id");
1056 foreach ( $links as $link ) {
1057 $link_id = (int) $link->link_id;
1058 $term_id = (int) $link->category_id;
1059 $taxonomy = 'link_category';
1060 $tt_id = $tt_ids[$term_id][$taxonomy];
1061 if ( empty($tt_id) )
1063 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link_id, 'term_taxonomy_id' => $tt_id) );
1067 if ( $wp_current_db_version < 4772 ) {
1068 // Obsolete linkcategories table
1069 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories');
1072 // Recalculate all counts
1073 $terms = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy");
1074 foreach ( (array) $terms as $term ) {
1075 if ( ('post_tag' == $term->taxonomy) || ('category' == $term->taxonomy) )
1076 $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) );
1078 $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id) );
1079 $wpdb->update( $wpdb->term_taxonomy, array('count' => $count), array('term_taxonomy_id' => $term->term_taxonomy_id) );
1084 * Remove old options from the database.
1088 * @global wpdb $wpdb
1090 function upgrade_230_options_table() {
1092 $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' );
1093 $wpdb->hide_errors();
1094 foreach ( $old_options_fields as $old )
1095 $wpdb->query("ALTER TABLE $wpdb->options DROP $old");
1096 $wpdb->show_errors();
1100 * Remove old categories, link2cat, and post2cat database tables.
1104 * @global wpdb $wpdb
1106 function upgrade_230_old_tables() {
1108 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories');
1109 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat');
1110 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat');
1114 * Upgrade old slugs made in version 2.2.
1118 * @global wpdb $wpdb
1120 function upgrade_old_slugs() {
1121 // Upgrade people who were using the Redirect Old Slugs plugin.
1123 $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'");
1127 * Execute changes made in WordPress 2.5.0.
1131 * @global int $wp_current_db_version
1133 function upgrade_250() {
1134 global $wp_current_db_version;
1136 if ( $wp_current_db_version < 6689 ) {
1137 populate_roles_250();
1143 * Execute changes made in WordPress 2.5.2.
1147 * @global wpdb $wpdb
1149 function upgrade_252() {
1152 $wpdb->query("UPDATE $wpdb->users SET user_activation_key = ''");
1156 * Execute changes made in WordPress 2.6.
1160 * @global int $wp_current_db_version
1162 function upgrade_260() {
1163 global $wp_current_db_version;
1165 if ( $wp_current_db_version < 8000 )
1166 populate_roles_260();
1170 * Execute changes made in WordPress 2.7.
1174 * @global wpdb $wpdb
1175 * @global int $wp_current_db_version
1177 function upgrade_270() {
1178 global $wpdb, $wp_current_db_version;
1180 if ( $wp_current_db_version < 8980 )
1181 populate_roles_270();
1183 // Update post_date for unpublished posts with empty timestamp
1184 if ( $wp_current_db_version < 8921 )
1185 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" );
1189 * Execute changes made in WordPress 2.8.
1193 * @global int $wp_current_db_version
1194 * @global wpdb $wpdb
1196 function upgrade_280() {
1197 global $wp_current_db_version, $wpdb;
1199 if ( $wp_current_db_version < 10360 )
1200 populate_roles_280();
1201 if ( is_multisite() ) {
1203 while( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) {
1204 foreach( $rows as $row ) {
1205 $value = $row->option_value;
1206 if ( !@unserialize( $value ) )
1207 $value = stripslashes( $value );
1208 if ( $value !== $row->option_value ) {
1209 update_option( $row->option_name, $value );
1214 refresh_blog_details( $wpdb->blogid );
1219 * Execute changes made in WordPress 2.9.
1223 * @global int $wp_current_db_version
1225 function upgrade_290() {
1226 global $wp_current_db_version;
1228 if ( $wp_current_db_version < 11958 ) {
1229 // Previously, setting depth to 1 would redundantly disable threading, but now 2 is the minimum depth to avoid confusion
1230 if ( get_option( 'thread_comments_depth' ) == '1' ) {
1231 update_option( 'thread_comments_depth', 2 );
1232 update_option( 'thread_comments', 0 );
1238 * Execute changes made in WordPress 3.0.
1242 * @global int $wp_current_db_version
1243 * @global wpdb $wpdb
1245 function upgrade_300() {
1246 global $wp_current_db_version, $wpdb;
1248 if ( $wp_current_db_version < 15093 )
1249 populate_roles_300();
1251 if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false )
1252 add_site_option( 'siteurl', '' );
1254 // 3.0 screen options key name changes.
1255 if ( wp_should_upgrade_global_tables() ) {
1256 $sql = "DELETE FROM $wpdb->usermeta
1257 WHERE meta_key LIKE %s
1263 OR meta_key = 'manageedittagscolumnshidden'
1264 OR meta_key = 'managecategoriescolumnshidden'
1265 OR meta_key = 'manageedit-tagscolumnshidden'
1266 OR meta_key = 'manageeditcolumnshidden'
1267 OR meta_key = 'categories_per_page'
1268 OR meta_key = 'edit_tags_per_page'";
1269 $prefix = $wpdb->esc_like( $wpdb->base_prefix );
1270 $wpdb->query( $wpdb->prepare( $sql,
1271 $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%',
1272 $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%',
1273 $prefix . '%' . $wpdb->esc_like( 'manage-' ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%',
1274 $prefix . '%' . $wpdb->esc_like( 'meta-box-order' ) . '%',
1275 $prefix . '%' . $wpdb->esc_like( 'metaboxorder' ) . '%',
1276 $prefix . '%' . $wpdb->esc_like( 'screen_layout' ) . '%'
1283 * Execute changes made in WordPress 3.3.
1287 * @global int $wp_current_db_version
1288 * @global wpdb $wpdb
1289 * @global array $wp_registered_widgets
1290 * @global array $sidebars_widgets
1292 function upgrade_330() {
1293 global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets;
1295 if ( $wp_current_db_version < 19061 && wp_should_upgrade_global_tables() ) {
1296 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" );
1299 if ( $wp_current_db_version >= 11548 )
1302 $sidebars_widgets = get_option( 'sidebars_widgets', array() );
1303 $_sidebars_widgets = array();
1305 if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) )
1306 $sidebars_widgets['array_version'] = 3;
1307 elseif ( !isset($sidebars_widgets['array_version']) )
1308 $sidebars_widgets['array_version'] = 1;
1310 switch ( $sidebars_widgets['array_version'] ) {
1312 foreach ( (array) $sidebars_widgets as $index => $sidebar )
1313 if ( is_array($sidebar) )
1314 foreach ( (array) $sidebar as $i => $name ) {
1315 $id = strtolower($name);
1316 if ( isset($wp_registered_widgets[$id]) ) {
1317 $_sidebars_widgets[$index][$i] = $id;
1320 $id = sanitize_title($name);
1321 if ( isset($wp_registered_widgets[$id]) ) {
1322 $_sidebars_widgets[$index][$i] = $id;
1328 foreach ( $wp_registered_widgets as $widget_id => $widget ) {
1329 if ( strtolower($widget['name']) == strtolower($name) ) {
1330 $_sidebars_widgets[$index][$i] = $widget['id'];
1333 } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) {
1334 $_sidebars_widgets[$index][$i] = $widget['id'];
1343 unset($_sidebars_widgets[$index][$i]);
1345 $_sidebars_widgets['array_version'] = 2;
1346 $sidebars_widgets = $_sidebars_widgets;
1347 unset($_sidebars_widgets);
1350 $sidebars_widgets = retrieve_widgets();
1351 $sidebars_widgets['array_version'] = 3;
1352 update_option( 'sidebars_widgets', $sidebars_widgets );
1357 * Execute changes made in WordPress 3.4.
1361 * @global int $wp_current_db_version
1362 * @global wpdb $wpdb
1364 function upgrade_340() {
1365 global $wp_current_db_version, $wpdb;
1367 if ( $wp_current_db_version < 19798 ) {
1368 $wpdb->hide_errors();
1369 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" );
1370 $wpdb->show_errors();
1373 if ( $wp_current_db_version < 19799 ) {
1374 $wpdb->hide_errors();
1375 $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved");
1376 $wpdb->show_errors();
1379 if ( $wp_current_db_version < 20022 && wp_should_upgrade_global_tables() ) {
1380 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" );
1383 if ( $wp_current_db_version < 20080 ) {
1384 if ( 'yes' == $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) {
1385 $uninstall_plugins = get_option( 'uninstall_plugins' );
1386 delete_option( 'uninstall_plugins' );
1387 add_option( 'uninstall_plugins', $uninstall_plugins, null, 'no' );
1393 * Execute changes made in WordPress 3.5.
1397 * @global int $wp_current_db_version
1398 * @global wpdb $wpdb
1400 function upgrade_350() {
1401 global $wp_current_db_version, $wpdb;
1403 if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
1404 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options()
1406 if ( $wp_current_db_version < 21811 && wp_should_upgrade_global_tables() ) {
1407 $meta_keys = array();
1408 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) {
1409 if ( false !== strpos( $name, '-' ) )
1410 $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page';
1413 $meta_keys = implode( "', '", $meta_keys );
1414 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" );
1418 if ( $wp_current_db_version < 22422 && $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ) )
1419 wp_delete_term( $term->term_id, 'post_format' );
1423 * Execute changes made in WordPress 3.7.
1427 * @global int $wp_current_db_version
1429 function upgrade_370() {
1430 global $wp_current_db_version;
1431 if ( $wp_current_db_version < 25824 )
1432 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' );
1436 * Execute changes made in WordPress 3.7.2.
1441 * @global int $wp_current_db_version
1443 function upgrade_372() {
1444 global $wp_current_db_version;
1445 if ( $wp_current_db_version < 26148 )
1446 wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
1450 * Execute changes made in WordPress 3.8.0.
1454 * @global int $wp_current_db_version
1456 function upgrade_380() {
1457 global $wp_current_db_version;
1458 if ( $wp_current_db_version < 26691 ) {
1459 deactivate_plugins( array( 'mp6/mp6.php' ), true );
1464 * Execute changes made in WordPress 4.0.0.
1468 * @global int $wp_current_db_version
1470 function upgrade_400() {
1471 global $wp_current_db_version;
1472 if ( $wp_current_db_version < 29630 ) {
1473 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) {
1474 if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages() ) ) {
1475 update_option( 'WPLANG', WPLANG );
1477 update_option( 'WPLANG', '' );
1484 * Execute changes made in WordPress 4.2.0.
1488 * @global int $wp_current_db_version
1489 * @global wpdb $wpdb
1491 function upgrade_420() {}
1494 * Executes changes made in WordPress 4.3.0.
1498 * @global int $wp_current_db_version Current version.
1499 * @global wpdb $wpdb WordPress database abstraction object.
1501 function upgrade_430() {
1502 global $wp_current_db_version, $wpdb;
1504 if ( $wp_current_db_version < 32364 ) {
1505 upgrade_430_fix_comments();
1508 // Shared terms are split in a separate process.
1509 if ( $wp_current_db_version < 32814 ) {
1510 update_option( 'finished_splitting_shared_terms', 0 );
1511 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
1514 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) {
1515 if ( is_multisite() ) {
1516 $tables = $wpdb->tables( 'blog' );
1518 $tables = $wpdb->tables( 'all' );
1519 if ( ! wp_should_upgrade_global_tables() ) {
1520 $global_tables = $wpdb->tables( 'global' );
1521 $tables = array_diff_assoc( $tables, $global_tables );
1525 foreach ( $tables as $table ) {
1526 maybe_convert_table_to_utf8mb4( $table );
1532 * Executes comments changes made in WordPress 4.3.0.
1536 * @global int $wp_current_db_version Current version.
1537 * @global wpdb $wpdb WordPress database abstraction object.
1539 function upgrade_430_fix_comments() {
1540 global $wp_current_db_version, $wpdb;
1542 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' );
1544 if ( is_wp_error( $content_length ) ) {
1548 if ( false === $content_length ) {
1549 $content_length = array(
1553 } elseif ( ! is_array( $content_length ) ) {
1554 $length = (int) $content_length > 0 ? (int) $content_length : 65535;
1555 $content_length = array(
1561 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) {
1562 // Sites with malformed DB schemas are on their own.
1566 $allowed_length = intval( $content_length['length'] ) - 10;
1568 $comments = $wpdb->get_results(
1569 "SELECT `comment_ID` FROM `{$wpdb->comments}`
1570 WHERE `comment_date_gmt` > '2015-04-26'
1571 AND LENGTH( `comment_content` ) >= {$allowed_length}
1572 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )"
1575 foreach ( $comments as $comment ) {
1576 wp_delete_comment( $comment->comment_ID, true );
1581 * Executes network-level upgrade routines.
1585 * @global int $wp_current_db_version
1586 * @global wpdb $wpdb
1588 function upgrade_network() {
1589 global $wp_current_db_version, $wpdb;
1592 if ( is_main_network() ) {
1594 * Deletes all expired transients. The multi-table delete syntax is used
1595 * to delete the transient record from table a, and the corresponding
1596 * transient_timeout record from table b.
1599 $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
1600 WHERE a.meta_key LIKE %s
1601 AND a.meta_key NOT LIKE %s
1602 AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1603 AND b.meta_value < %d";
1604 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
1608 if ( $wp_current_db_version < 11549 ) {
1609 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' );
1610 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' );
1611 if ( $wpmu_sitewide_plugins ) {
1612 if ( !$active_sitewide_plugins )
1613 $sitewide_plugins = (array) $wpmu_sitewide_plugins;
1615 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins );
1617 update_site_option( 'active_sitewide_plugins', $sitewide_plugins );
1619 delete_site_option( 'wpmu_sitewide_plugins' );
1620 delete_site_option( 'deactivated_sitewide_plugins' );
1623 while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) {
1624 foreach( $rows as $row ) {
1625 $value = $row->meta_value;
1626 if ( !@unserialize( $value ) )
1627 $value = stripslashes( $value );
1628 if ( $value !== $row->meta_value ) {
1629 update_site_option( $row->meta_key, $value );
1637 if ( $wp_current_db_version < 13576 )
1638 update_site_option( 'global_terms_enabled', '1' );
1641 if ( $wp_current_db_version < 19390 )
1642 update_site_option( 'initial_db_version', $wp_current_db_version );
1644 if ( $wp_current_db_version < 19470 ) {
1645 if ( false === get_site_option( 'active_sitewide_plugins' ) )
1646 update_site_option( 'active_sitewide_plugins', array() );
1650 if ( $wp_current_db_version < 20148 ) {
1651 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name.
1652 $allowedthemes = get_site_option( 'allowedthemes' );
1653 $allowed_themes = get_site_option( 'allowed_themes' );
1654 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) {
1655 $converted = array();
1656 $themes = wp_get_themes();
1657 foreach ( $themes as $stylesheet => $theme_data ) {
1658 if ( isset( $allowed_themes[ $theme_data->get('Name') ] ) )
1659 $converted[ $stylesheet ] = true;
1661 update_site_option( 'allowedthemes', $converted );
1662 delete_site_option( 'allowed_themes' );
1667 if ( $wp_current_db_version < 21823 )
1668 update_site_option( 'ms_files_rewriting', '1' );
1671 if ( $wp_current_db_version < 24448 ) {
1672 $illegal_names = get_site_option( 'illegal_names' );
1673 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) {
1674 $illegal_name = reset( $illegal_names );
1675 $illegal_names = explode( ' ', $illegal_name );
1676 update_site_option( 'illegal_names', $illegal_names );
1681 if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1682 if ( wp_should_upgrade_global_tables() ) {
1683 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1684 $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1685 $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1686 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1688 $tables = $wpdb->tables( 'global' );
1690 // sitecategories may not exist.
1691 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) {
1692 unset( $tables['sitecategories'] );
1695 foreach ( $tables as $table ) {
1696 maybe_convert_table_to_utf8mb4( $table );
1702 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) {
1703 if ( wp_should_upgrade_global_tables() ) {
1705 $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" );
1706 foreach( $indexes as $index ) {
1707 if ( 'domain_path' == $index->Key_name && 'domain' == $index->Column_name && 140 != $index->Sub_part ) {
1714 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1717 $tables = $wpdb->tables( 'global' );
1719 // sitecategories may not exist.
1720 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) {
1721 unset( $tables['sitecategories'] );
1724 foreach ( $tables as $table ) {
1725 maybe_convert_table_to_utf8mb4( $table );
1732 // General functions we use to actually do stuff
1736 * Creates a table in the database if it doesn't already exist.
1738 * This method checks for an existing database and creates a new one if it's not
1739 * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses
1740 * to query all tables first and then run the SQL statement creating the table.
1744 * @global wpdb $wpdb
1746 * @param string $table_name Database table name to create.
1747 * @param string $create_ddl SQL statement to create table.
1748 * @return bool If table already exists or was created by function.
1750 function maybe_create_table($table_name, $create_ddl) {
1753 $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
1755 if ( $wpdb->get_var( $query ) == $table_name ) {
1759 // Didn't find it try to create it..
1760 $wpdb->query($create_ddl);
1762 // We cannot directly tell that whether this succeeded!
1763 if ( $wpdb->get_var( $query ) == $table_name ) {
1770 * Drops a specified index from a table.
1774 * @global wpdb $wpdb
1776 * @param string $table Database table name.
1777 * @param string $index Index name to drop.
1778 * @return true True, when finished.
1780 function drop_index($table, $index) {
1782 $wpdb->hide_errors();
1783 $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
1784 // Now we need to take out all the extra ones we may have created
1785 for ($i = 0; $i < 25; $i++) {
1786 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
1788 $wpdb->show_errors();
1793 * Adds an index to a specified table.
1797 * @global wpdb $wpdb
1799 * @param string $table Database table name.
1800 * @param string $index Database table index column.
1801 * @return true True, when done with execution.
1803 function add_clean_index($table, $index) {
1805 drop_index($table, $index);
1806 $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
1811 * Adds column to a database table if it doesn't already exist.
1815 * @global wpdb $wpdb
1817 * @param string $table_name The table name to modify.
1818 * @param string $column_name The column name to add to the table.
1819 * @param string $create_ddl The SQL statement used to add the column.
1820 * @return bool True if already exists or on successful completion, false on error.
1822 function maybe_add_column($table_name, $column_name, $create_ddl) {
1824 foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1825 if ($column == $column_name) {
1830 // Didn't find it try to create it.
1831 $wpdb->query($create_ddl);
1833 // We cannot directly tell that whether this succeeded!
1834 foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1835 if ($column == $column_name) {
1843 * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4.
1847 * @global wpdb $wpdb
1849 * @param string $table The table to convert.
1850 * @return bool true if the table was converted, false if it wasn't.
1852 function maybe_convert_table_to_utf8mb4( $table ) {
1855 $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" );
1860 foreach ( $results as $column ) {
1861 if ( $column->Collation ) {
1862 list( $charset ) = explode( '_', $column->Collation );
1863 $charset = strtolower( $charset );
1864 if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) {
1865 // Don't upgrade tables that have non-utf8 columns.
1871 $table_details = $wpdb->get_row( "SHOW TABLE STATUS LIKE '$table'" );
1872 if ( ! $table_details ) {
1876 list( $table_charset ) = explode( '_', $table_details->Collation );
1877 $table_charset = strtolower( $table_charset );
1878 if ( 'utf8mb4' === $table_charset ) {
1882 return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
1886 * Retrieve all options as it was for 1.2.
1890 * @global wpdb $wpdb
1892 * @return stdClass List of options.
1894 function get_alloptions_110() {
1896 $all_options = new stdClass;
1897 if ( $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ) ) {
1898 foreach ( $options as $option ) {
1899 if ( 'siteurl' == $option->option_name || 'home' == $option->option_name || 'category_base' == $option->option_name )
1900 $option->option_value = untrailingslashit( $option->option_value );
1901 $all_options->{$option->option_name} = stripslashes( $option->option_value );
1904 return $all_options;
1908 * Utility version of get_option that is private to install/upgrade.
1914 * @global wpdb $wpdb
1916 * @param string $setting Option name.
1919 function __get_option($setting) {
1922 if ( $setting == 'home' && defined( 'WP_HOME' ) )
1923 return untrailingslashit( WP_HOME );
1925 if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) )
1926 return untrailingslashit( WP_SITEURL );
1928 $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) );
1930 if ( 'home' == $setting && '' == $option )
1931 return __get_option( 'siteurl' );
1933 if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting || 'tag_base' == $setting )
1934 $option = untrailingslashit( $option );
1936 return maybe_unserialize( $option );
1940 * Filters for content to remove unnecessary slashes.
1944 * @param string $content The content to modify.
1945 * @return string The de-slashed content.
1947 function deslash($content) {
1948 // Note: \\\ inside a regex denotes a single backslash.
1951 * Replace one or more backslashes followed by a single quote with
1954 $content = preg_replace("/\\\+'/", "'", $content);
1957 * Replace one or more backslashes followed by a double quote with
1960 $content = preg_replace('/\\\+"/', '"', $content);
1962 // Replace one or more backslashes with one backslash.
1963 $content = preg_replace("/\\\+/", "\\", $content);
1969 * Modifies the database based on specified SQL statements.
1971 * Useful for creating new tables and updating existing tables to a new structure.
1975 * @global wpdb $wpdb
1977 * @param string|array $queries Optional. The query to run. Can be multiple queries
1978 * in an array, or a string of queries separated by
1979 * semicolons. Default empty.
1980 * @param bool $execute Optional. Whether or not to execute the query right away.
1982 * @return array Strings containing the results of the various update queries.
1984 function dbDelta( $queries = '', $execute = true ) {
1987 if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) )
1988 $queries = wp_get_db_schema( $queries );
1990 // Separate individual queries into an array
1991 if ( !is_array($queries) ) {
1992 $queries = explode( ';', $queries );
1993 $queries = array_filter( $queries );
1997 * Filter the dbDelta SQL queries.
2001 * @param array $queries An array of dbDelta SQL queries.
2003 $queries = apply_filters( 'dbdelta_queries', $queries );
2005 $cqueries = array(); // Creation Queries
2006 $iqueries = array(); // Insertion Queries
2007 $for_update = array();
2009 // Create a tablename index for an array ($cqueries) of queries
2010 foreach($queries as $qry) {
2011 if ( preg_match( "|CREATE TABLE ([^ ]*)|", $qry, $matches ) ) {
2012 $cqueries[ trim( $matches[1], '`' ) ] = $qry;
2013 $for_update[$matches[1]] = 'Created table '.$matches[1];
2014 } elseif ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
2015 array_unshift( $cqueries, $qry );
2016 } elseif ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
2018 } elseif ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
2021 // Unrecognized query type
2026 * Filter the dbDelta SQL queries for creating tables and/or databases.
2028 * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE".
2032 * @param array $cqueries An array of dbDelta create SQL queries.
2034 $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries );
2037 * Filter the dbDelta SQL queries for inserting or updating.
2039 * Queries filterable via this hook contain "INSERT INTO" or "UPDATE".
2043 * @param array $iqueries An array of dbDelta insert or update SQL queries.
2045 $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries );
2047 $global_tables = $wpdb->tables( 'global' );
2048 foreach ( $cqueries as $table => $qry ) {
2049 // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal.
2050 if ( in_array( $table, $global_tables ) && ! wp_should_upgrade_global_tables() ) {
2051 unset( $cqueries[ $table ], $for_update[ $table ] );
2055 // Fetch the table column structure from the database
2056 $suppress = $wpdb->suppress_errors();
2057 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
2058 $wpdb->suppress_errors( $suppress );
2060 if ( ! $tablefields )
2063 // Clear the field and index arrays.
2064 $cfields = $indices = array();
2066 // Get all of the field names in the query from between the parentheses.
2067 preg_match("|\((.*)\)|ms", $qry, $match2);
2068 $qryline = trim($match2[1]);
2070 // Separate field lines into an array.
2071 $flds = explode("\n", $qryline);
2073 // todo: Remove this?
2074 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
2076 // For every field line specified in the query.
2077 foreach ($flds as $fld) {
2079 // Extract the field name.
2080 preg_match("|^([^ ]*)|", trim($fld), $fvals);
2081 $fieldname = trim( $fvals[1], '`' );
2083 // Verify the found field name.
2085 switch (strtolower($fieldname)) {
2092 $validfield = false;
2093 $indices[] = trim(trim($fld), ", \n");
2098 // If it's a valid field, add it to the field array.
2100 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
2104 // For every field in the table.
2105 foreach ($tablefields as $tablefield) {
2107 // If the table field exists in the field array ...
2108 if (array_key_exists(strtolower($tablefield->Field), $cfields)) {
2110 // Get the field type from the query.
2111 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
2112 $fieldtype = $matches[1];
2114 // Is actual field type different from the field type in query?
2115 if ($tablefield->Type != $fieldtype) {
2116 // Add a query to change the column type
2117 $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
2118 $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
2121 // Get the default value from the array
2122 // todo: Remove this?
2123 //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
2124 if (preg_match("| DEFAULT '(.*?)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
2125 $default_value = $matches[1];
2126 if ($tablefield->Default != $default_value) {
2127 // Add a query to change the column's default value
2128 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
2129 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
2133 // Remove the field from the array (so it's not added).
2134 unset($cfields[strtolower($tablefield->Field)]);
2136 // This field exists in the table, but not in the creation queries?
2140 // For every remaining field specified for the table.
2141 foreach ($cfields as $fieldname => $fielddef) {
2142 // Push a query line into $cqueries that adds the field to that table.
2143 $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
2144 $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
2147 // Index stuff goes here. Fetch the table index structure from the database.
2148 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
2150 if ($tableindices) {
2151 // Clear the index array.
2152 $index_ary = array();
2154 // For every index in the table.
2155 foreach ($tableindices as $tableindex) {
2157 // Add the index to the index data array.
2158 $keyname = $tableindex->Key_name;
2159 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
2160 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
2163 // For each actual index in the index array.
2164 foreach ($index_ary as $index_name => $index_data) {
2166 // Build a create string to compare to the query.
2168 if ($index_name == 'PRIMARY') {
2169 $index_string .= 'PRIMARY ';
2170 } elseif ( $index_data['unique'] ) {
2171 $index_string .= 'UNIQUE ';
2173 $index_string .= 'KEY ';
2174 if ($index_name != 'PRIMARY') {
2175 $index_string .= $index_name;
2177 $index_columns = '';
2179 // For each column in the index.
2180 foreach ($index_data['columns'] as $column_data) {
2181 if ($index_columns != '') $index_columns .= ',';
2183 // Add the field to the column list string.
2184 $index_columns .= $column_data['fieldname'];
2185 if ($column_data['subpart'] != '') {
2186 $index_columns .= '('.$column_data['subpart'].')';
2190 // The alternative index string doesn't care about subparts
2191 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
2193 // Add the column list to the index create string.
2194 $index_strings = array(
2195 "$index_string ($index_columns)",
2196 "$index_string ($alt_index_columns)",
2199 foreach( $index_strings as $index_string ) {
2200 if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
2201 unset( $indices[ $aindex ] );
2203 // todo: Remove this?
2204 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
2207 // todo: Remove this?
2208 //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";
2212 // For every remaining index specified for the table.
2213 foreach ( (array) $indices as $index ) {
2214 // Push a query line into $cqueries that adds the index to that table.
2215 $cqueries[] = "ALTER TABLE {$table} ADD $index";
2216 $for_update[] = 'Added index ' . $table . ' ' . $index;
2219 // Remove the original table creation query from processing.
2220 unset( $cqueries[ $table ], $for_update[ $table ] );
2223 $allqueries = array_merge($cqueries, $iqueries);
2225 foreach ($allqueries as $query) {
2226 // todo: Remove this?
2227 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
2228 $wpdb->query($query);
2236 * Updates the database tables to a new schema.
2238 * By default, updates all the tables to use the latest defined schema, but can also
2239 * be used to update a specific set of tables in wp_get_db_schema().
2245 * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2247 function make_db_current( $tables = 'all' ) {
2248 $alterations = dbDelta( $tables );
2250 foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
2255 * Updates the database tables to a new schema, but without displaying results.
2257 * By default, updates all the tables to use the latest defined schema, but can
2258 * also be used to update a specific set of tables in wp_get_db_schema().
2262 * @see make_db_current()
2264 * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2266 function make_db_current_silent( $tables = 'all' ) {
2271 * Creates a site theme from an existing theme.
2273 * {@internal Missing Long Description}}
2277 * @param string $theme_name The name of the theme.
2278 * @param string $template The directory name of the theme.
2281 function make_site_theme_from_oldschool($theme_name, $template) {
2282 $home_path = get_home_path();
2283 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2285 if (! file_exists("$home_path/index.php"))
2289 * Copy files from the old locations to the site theme.
2290 * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
2292 $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
2294 foreach ($files as $oldfile => $newfile) {
2295 if ($oldfile == 'index.php')
2296 $oldpath = $home_path;
2300 // Check to make sure it's not a new index.
2301 if ($oldfile == 'index.php') {
2302 $index = implode('', file("$oldpath/$oldfile"));
2303 if (strpos($index, 'WP_USE_THEMES') !== false) {
2304 if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile"))
2307 // Don't copy anything.
2312 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
2315 chmod("$site_dir/$newfile", 0777);
2317 // Update the blog header include in each file.
2318 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
2320 $f = fopen("$site_dir/$newfile", 'w');
2322 foreach ($lines as $line) {
2323 if (preg_match('/require.*wp-blog-header/', $line))
2324 $line = '//' . $line;
2326 // Update stylesheet references.
2327 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
2329 // Update comments template inclusion.
2330 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
2332 fwrite($f, "{$line}\n");
2338 // Add a theme header.
2339 $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";
2341 $stylelines = file_get_contents("$site_dir/style.css");
2343 $f = fopen("$site_dir/style.css", 'w');
2345 fwrite($f, $header);
2346 fwrite($f, $stylelines);
2354 * Creates a site theme from the default theme.
2356 * {@internal Missing Long Description}}
2360 * @param string $theme_name The name of the theme.
2361 * @param string $template The directory name of the theme.
2362 * @return false|void
2364 function make_site_theme_from_default($theme_name, $template) {
2365 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2366 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
2368 // Copy files from the default theme to the site theme.
2369 //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
2371 $theme_dir = @ opendir($default_dir);
2373 while(($theme_file = readdir( $theme_dir )) !== false) {
2374 if (is_dir("$default_dir/$theme_file"))
2376 if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
2378 chmod("$site_dir/$theme_file", 0777);
2381 @closedir($theme_dir);
2383 // Rewrite the theme header.
2384 $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
2386 $f = fopen("$site_dir/style.css", 'w');
2388 foreach ($stylelines as $line) {
2389 if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
2390 elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
2391 elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
2392 elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
2393 elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
2394 fwrite($f, $line . "\n");
2401 if (! mkdir("$site_dir/images", 0777)) {
2405 $images_dir = @ opendir("$default_dir/images");
2407 while(($image = readdir($images_dir)) !== false) {
2408 if (is_dir("$default_dir/images/$image"))
2410 if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
2412 chmod("$site_dir/images/$image", 0777);
2415 @closedir($images_dir);
2419 * Creates a site theme.
2421 * {@internal Missing Long Description}}
2425 * @return false|string
2427 function make_site_theme() {
2428 // Name the theme after the blog.
2429 $theme_name = __get_option('blogname');
2430 $template = sanitize_title($theme_name);
2431 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2433 // If the theme already exists, nothing to do.
2434 if ( is_dir($site_dir)) {
2438 // We must be able to write to the themes dir.
2439 if (! is_writable(WP_CONTENT_DIR . "/themes")) {
2444 if (! mkdir($site_dir, 0777)) {
2448 if (file_exists(ABSPATH . 'wp-layout.css')) {
2449 if (! make_site_theme_from_oldschool($theme_name, $template)) {
2450 // TODO: rm -rf the site theme directory.
2454 if (! make_site_theme_from_default($theme_name, $template))
2455 // TODO: rm -rf the site theme directory.
2459 // Make the new site theme active.
2460 $current_template = __get_option('template');
2461 if ($current_template == WP_DEFAULT_THEME) {
2462 update_option('template', $template);
2463 update_option('stylesheet', $template);
2469 * Translate user level to user role name.
2473 * @param int $level User level.
2474 * @return string User role name.
2476 function translate_level_to_role($level) {
2481 return 'administrator';
2491 return 'contributor';
2493 return 'subscriber';
2498 * Checks the version of the installed MySQL binary.
2502 * @global wpdb $wpdb
2504 function wp_check_mysql_version() {
2506 $result = $wpdb->check_database_version();
2507 if ( is_wp_error( $result ) )
2508 die( $result->get_error_message() );
2512 * Disables the Automattic widgets plugin, which was merged into core.
2516 function maybe_disable_automattic_widgets() {
2517 $plugins = __get_option( 'active_plugins' );
2519 foreach ( (array) $plugins as $plugin ) {
2520 if ( basename( $plugin ) == 'widgets.php' ) {
2521 array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
2522 update_option( 'active_plugins', $plugins );
2529 * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
2533 * @global int $wp_current_db_version
2534 * @global wpdb $wpdb
2536 function maybe_disable_link_manager() {
2537 global $wp_current_db_version, $wpdb;
2539 if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
2540 update_option( 'link_manager_enabled', 0 );
2544 * Runs before the schema is upgraded.
2548 * @global int $wp_current_db_version
2549 * @global wpdb $wpdb
2551 function pre_schema_upgrade() {
2552 global $wp_current_db_version, $wpdb;
2554 // Upgrade versions prior to 2.9
2555 if ( $wp_current_db_version < 11557 ) {
2556 // Delete duplicate options. Keep the option with the highest option_id.
2557 $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id");
2559 // Drop the old primary key and add the new.
2560 $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)");
2562 // Drop the old option_name index. dbDelta() doesn't do the drop.
2563 $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name");
2566 // Multisite schema upgrades.
2567 if ( $wp_current_db_version < 25448 && is_multisite() && wp_should_upgrade_global_tables() ) {
2569 // Upgrade verions prior to 3.7
2570 if ( $wp_current_db_version < 25179 ) {
2571 // New primary key for signups.
2572 $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
2573 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
2576 if ( $wp_current_db_version < 25448 ) {
2577 // Convert archived from enum to tinyint.
2578 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
2579 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
2583 // Upgrade versions prior to 4.2.
2584 if ( $wp_current_db_version < 31351 ) {
2585 if ( ! is_multisite() && wp_should_upgrade_global_tables() ) {
2586 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2588 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
2589 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
2590 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2591 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2592 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
2597 * Install global terms.
2601 * @global wpdb $wpdb
2602 * @global string $charset_collate
2604 if ( !function_exists( 'install_global_terms' ) ) :
2605 function install_global_terms() {
2606 global $wpdb, $charset_collate;
2608 CREATE TABLE $wpdb->sitecategories (
2609 cat_ID bigint(20) NOT NULL auto_increment,
2610 cat_name varchar(55) NOT NULL default '',
2611 category_nicename varchar(200) NOT NULL default '',
2612 last_updated timestamp NOT NULL,
2613 PRIMARY KEY (cat_ID),
2614 KEY category_nicename (category_nicename),
2615 KEY last_updated (last_updated)
2618 // now create tables
2619 dbDelta( $ms_queries );
2624 * Determine if global tables should be upgraded.
2626 * This function performs a series of checks to ensure the environment allows
2627 * for the safe upgrading of global WordPress database tables. It is necessary
2628 * because global tables will commonly grow to millions of rows on large
2629 * installations, and the ability to control their upgrade routines can be
2630 * critical to the operation of large networks.
2632 * In a future iteration, this function may use `wp_is_large_network()` to more-
2633 * intelligently prevent global table upgrades. Until then, we make sure
2634 * WordPress is on the main site of the main network, to avoid running queries
2635 * more than once in multi-site or multi-network environments.
2639 * @return bool Whether to run the upgrade routines on global tables.
2641 function wp_should_upgrade_global_tables() {
2643 // Return false early if explicitly not upgrading
2644 if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
2648 // Assume global tables should be upgraded
2649 $should_upgrade = true;
2651 // Set to false if not on main network (does not matter if not multi-network)
2652 if ( ! is_main_network() ) {
2653 $should_upgrade = false;
2656 // Set to false if not on main site of current network (does not matter if not multi-site)
2657 if ( ! is_main_site() ) {
2658 $should_upgrade = false;
2662 * Filter if upgrade routines should be run on global tables.
2664 * @param bool $should_upgrade Whether to run the upgrade routines on global tables.
2666 return apply_filters( 'wp_should_upgrade_global_tables', $should_upgrade );