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 Site title.
31 * @param string $user_name User's username.
32 * @param string $user_email User's email.
33 * @param bool $public Whether site 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 sites. 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 ( ! $first_post ) {
159 /* translators: %s: site link */
160 $first_post = __( 'Welcome to %s. This is your first post. Edit or delete it, then start blogging!' );
163 $first_post = sprintf( $first_post,
164 sprintf( '<a href="%s">%s</a>', esc_url( network_home_url() ), get_current_site()->site_name )
167 // Back-compat for pre-4.4
168 $first_post = str_replace( 'SITE_URL', esc_url( network_home_url() ), $first_post );
169 $first_post = str_replace( 'SITE_NAME', get_current_site()->site_name, $first_post );
171 $first_post = __( 'Welcome to WordPress. This is your first post. Edit or delete it, then start writing!' );
174 $wpdb->insert( $wpdb->posts, array(
175 'post_author' => $user_id,
177 'post_date_gmt' => $now_gmt,
178 'post_content' => $first_post,
179 'post_excerpt' => '',
180 'post_title' => __('Hello world!'),
181 /* translators: Default post slug */
182 'post_name' => sanitize_title( _x('hello-world', 'Default post slug') ),
183 'post_modified' => $now,
184 'post_modified_gmt' => $now_gmt,
185 'guid' => $first_post_guid,
186 'comment_count' => 1,
189 'post_content_filtered' => ''
191 $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) );
194 $first_comment_author = __('Mr WordPress');
195 $first_comment_url = 'https://wordpress.org/';
196 $first_comment = __('Hi, this is a comment.
197 To delete a comment, just log in and view the post's comments. There you will have the option to edit or delete them.');
198 if ( is_multisite() ) {
199 $first_comment_author = get_site_option( 'first_comment_author', $first_comment_author );
200 $first_comment_url = get_site_option( 'first_comment_url', network_home_url() );
201 $first_comment = get_site_option( 'first_comment', $first_comment );
203 $wpdb->insert( $wpdb->comments, array(
204 'comment_post_ID' => 1,
205 'comment_author' => $first_comment_author,
206 'comment_author_email' => '',
207 'comment_author_url' => $first_comment_url,
208 'comment_date' => $now,
209 'comment_date_gmt' => $now_gmt,
210 'comment_content' => $first_comment
214 $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:
216 <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>
218 ...or something like this:
220 <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>
222 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() );
223 if ( is_multisite() )
224 $first_page = get_site_option( 'first_page', $first_page );
225 $first_post_guid = get_option('home') . '/?page_id=2';
226 $wpdb->insert( $wpdb->posts, array(
227 'post_author' => $user_id,
229 'post_date_gmt' => $now_gmt,
230 'post_content' => $first_page,
231 'post_excerpt' => '',
232 'comment_status' => 'closed',
233 'post_title' => __( 'Sample Page' ),
234 /* translators: Default page slug */
235 'post_name' => __( 'sample-page' ),
236 'post_modified' => $now,
237 'post_modified_gmt' => $now_gmt,
238 'guid' => $first_post_guid,
239 'post_type' => 'page',
242 'post_content_filtered' => ''
244 $wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) );
246 // Set up default widgets for default theme.
247 update_option( 'widget_search', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
248 update_option( 'widget_recent-posts', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
249 update_option( 'widget_recent-comments', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) );
250 update_option( 'widget_archives', array ( 2 => array ( 'title' => '', 'count' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
251 update_option( 'widget_categories', array ( 2 => array ( 'title' => '', 'count' => 0, 'hierarchical' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) );
252 update_option( 'widget_meta', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) );
253 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 ) );
255 if ( ! is_multisite() )
256 update_user_meta( $user_id, 'show_welcome_panel', 1 );
257 elseif ( ! is_super_admin( $user_id ) && ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) )
258 update_user_meta( $user_id, 'show_welcome_panel', 2 );
260 if ( is_multisite() ) {
261 // Flush rules to pick up the new page.
263 $wp_rewrite->flush_rules();
265 $user = new WP_User($user_id);
266 $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') );
268 // Remove all perms except for the login user.
269 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') );
270 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') );
272 // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
273 if ( !is_super_admin( $user_id ) && $user_id != 1 )
274 $wpdb->delete( $wpdb->usermeta, array( 'user_id' => $user_id , 'meta_key' => $wpdb->base_prefix.'1_capabilities' ) );
280 * Maybe enable pretty permalinks on install.
282 * If after enabling pretty permalinks don't work, fallback to query-string permalinks.
286 * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
288 * @return bool Whether pretty permalinks are enabled. False otherwise.
290 function wp_install_maybe_enable_pretty_permalinks() {
293 // Bail if a permalink structure is already enabled.
294 if ( get_option( 'permalink_structure' ) ) {
299 * The Permalink structures to attempt.
301 * The first is designed for mod_rewrite or nginx rewriting.
303 * The second is PATHINFO-based permalinks for web server configurations
304 * without a true rewrite module enabled.
306 $permalink_structures = array(
307 '/%year%/%monthnum%/%day%/%postname%/',
308 '/index.php/%year%/%monthnum%/%day%/%postname%/'
311 foreach ( (array) $permalink_structures as $permalink_structure ) {
312 $wp_rewrite->set_permalink_structure( $permalink_structure );
315 * Flush rules with the hard option to force refresh of the web-server's
316 * rewrite config file (e.g. .htaccess or web.config).
318 $wp_rewrite->flush_rules( true );
320 // Test against a real WordPress Post, or if none were created, a random 404 page.
321 $test_url = get_permalink( 1 );
324 $test_url = home_url( '/wordpress-check-for-rewrites/' );
328 * Send a request to the site, and check whether
329 * the 'x-pingback' header is returned as expected.
331 * Uses wp_remote_get() instead of wp_remote_head() because web servers
332 * can block head requests.
334 $response = wp_remote_get( $test_url, array( 'timeout' => 5 ) );
335 $x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );
336 $pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );
338 if ( $pretty_permalinks ) {
344 * If it makes it this far, pretty permalinks failed.
345 * Fallback to query-string permalinks.
347 $wp_rewrite->set_permalink_structure( '' );
348 $wp_rewrite->flush_rules( true );
353 if ( !function_exists('wp_new_blog_notification') ) :
355 * Notifies the site admin that the setup is complete.
357 * Sends an email with wp_mail to the new administrator that the site setup is complete,
358 * and provides them with a record of their login credentials.
362 * @param string $blog_title Site title.
363 * @param string $blog_url Site url.
364 * @param int $user_id User ID.
365 * @param string $password User's Password.
367 function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) {
368 $user = new WP_User( $user_id );
369 $email = $user->user_email;
370 $name = $user->user_login;
371 $login_url = wp_login_url();
372 $message = sprintf( __( "Your new WordPress site has been successfully set up at:
376 You can log in to the administrator account with the following information:
382 We hope you enjoy your new site. Thanks!
385 https://wordpress.org/
386 "), $blog_url, $name, $password, $login_url );
388 @wp_mail($email, __('New WordPress Site'), $message);
392 if ( !function_exists('wp_upgrade') ) :
394 * Runs WordPress Upgrade functions.
396 * Upgrades the database if needed during a site update.
400 * @global int $wp_current_db_version
401 * @global int $wp_db_version
402 * @global wpdb $wpdb WordPress database abstraction object.
404 function wp_upgrade() {
405 global $wp_current_db_version, $wp_db_version, $wpdb;
407 $wp_current_db_version = __get_option('db_version');
409 // We are up-to-date. Nothing to do.
410 if ( $wp_db_version == $wp_current_db_version )
413 if ( ! is_blog_installed() )
416 wp_check_mysql_version();
418 pre_schema_upgrade();
419 make_db_current_silent();
421 if ( is_multisite() && is_main_site() )
425 if ( is_multisite() ) {
426 if ( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) )
427 $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" );
429 $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" );
433 * Fires after a site is fully upgraded.
437 * @param int $wp_db_version The new $wp_db_version.
438 * @param int $wp_current_db_version The old (current) $wp_db_version.
440 do_action( 'wp_upgrade', $wp_db_version, $wp_current_db_version );
445 * Functions to be called in install and upgrade scripts.
447 * Contains conditional checks to determine which upgrade scripts to run,
448 * based on database version and WP version being updated-to.
453 * @global int $wp_current_db_version
454 * @global int $wp_db_version
456 function upgrade_all() {
457 global $wp_current_db_version, $wp_db_version;
458 $wp_current_db_version = __get_option('db_version');
460 // We are up-to-date. Nothing to do.
461 if ( $wp_db_version == $wp_current_db_version )
464 // If the version is not set in the DB, try to guess the version.
465 if ( empty($wp_current_db_version) ) {
466 $wp_current_db_version = 0;
468 // If the template option exists, we have 1.5.
469 $template = __get_option('template');
470 if ( !empty($template) )
471 $wp_current_db_version = 2541;
474 if ( $wp_current_db_version < 6039 )
475 upgrade_230_options_table();
479 if ( $wp_current_db_version < 2541 ) {
486 if ( $wp_current_db_version < 3308 )
489 if ( $wp_current_db_version < 4772 )
492 if ( $wp_current_db_version < 4351 )
495 if ( $wp_current_db_version < 5539 )
498 if ( $wp_current_db_version < 6124 )
499 upgrade_230_old_tables();
501 if ( $wp_current_db_version < 7499 )
504 if ( $wp_current_db_version < 7935 )
507 if ( $wp_current_db_version < 8201 )
510 if ( $wp_current_db_version < 8989 )
513 if ( $wp_current_db_version < 10360 )
516 if ( $wp_current_db_version < 11958 )
519 if ( $wp_current_db_version < 15260 )
522 if ( $wp_current_db_version < 19389 )
525 if ( $wp_current_db_version < 20080 )
528 if ( $wp_current_db_version < 22422 )
531 if ( $wp_current_db_version < 25824 )
534 if ( $wp_current_db_version < 26148 )
537 if ( $wp_current_db_version < 26691 )
540 if ( $wp_current_db_version < 29630 )
543 if ( $wp_current_db_version < 33055 )
546 if ( $wp_current_db_version < 33056 )
549 if ( $wp_current_db_version < 35700 )
552 if ( $wp_current_db_version < 36686 )
555 maybe_disable_link_manager();
557 maybe_disable_automattic_widgets();
559 update_option( 'db_version', $wp_db_version );
560 update_option( 'db_upgraded', true );
564 * Execute changes made in WordPress 1.0.
569 * @global wpdb $wpdb WordPress database abstraction object.
571 function upgrade_100() {
574 // Get the title and ID of every post, post_name to check if it already has a value
575 $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
577 foreach ($posts as $post) {
578 if ('' == $post->post_name) {
579 $newtitle = sanitize_title($post->post_title);
580 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID) );
585 $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
586 foreach ($categories as $category) {
587 if ('' == $category->category_nicename) {
588 $newtitle = sanitize_title($category->cat_name);
589 $wpdb->update( $wpdb->categories, array('category_nicename' => $newtitle), array('cat_ID' => $category->cat_ID) );
593 $sql = "UPDATE $wpdb->options
594 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
595 WHERE option_name LIKE %s
596 AND option_value LIKE %s";
597 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) );
599 $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
601 $done_posts = array();
602 foreach ($done_ids as $done_id) :
603 $done_posts[] = $done_id->post_id;
605 $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
610 $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
612 foreach ($allposts as $post) {
613 // Check to see if it's already been imported
614 $cat = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category) );
615 if (!$cat && 0 != $post->post_category) { // If there's no result
616 $wpdb->insert( $wpdb->post2cat, array('post_id' => $post->ID, 'category_id' => $post->post_category) );
623 * Execute changes made in WordPress 1.0.1.
628 * @global wpdb $wpdb WordPress database abstraction object.
630 function upgrade_101() {
633 // Clean up indices, add a few
634 add_clean_index($wpdb->posts, 'post_name');
635 add_clean_index($wpdb->posts, 'post_status');
636 add_clean_index($wpdb->categories, 'category_nicename');
637 add_clean_index($wpdb->comments, 'comment_approved');
638 add_clean_index($wpdb->comments, 'comment_post_ID');
639 add_clean_index($wpdb->links , 'link_category');
640 add_clean_index($wpdb->links , 'link_visible');
644 * Execute changes made in WordPress 1.2.
649 * @global wpdb $wpdb WordPress database abstraction object.
651 function upgrade_110() {
654 // Set user_nicename.
655 $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
656 foreach ($users as $user) {
657 if ('' == $user->user_nicename) {
658 $newname = sanitize_title($user->user_nickname);
659 $wpdb->update( $wpdb->users, array('user_nicename' => $newname), array('ID' => $user->ID) );
663 $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
664 foreach ($users as $row) {
665 if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
666 $wpdb->update( $wpdb->users, array('user_pass' => md5($row->user_pass)), array('ID' => $row->ID) );
670 // Get the GMT offset, we'll use that later on
671 $all_options = get_alloptions_110();
673 $time_difference = $all_options->time_difference;
675 $server_time = time()+date('Z');
676 $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS;
679 $diff_gmt_server = ($gmt_time - $server_time) / HOUR_IN_SECONDS;
680 $diff_weblogger_server = ($weblogger_time - $server_time) / HOUR_IN_SECONDS;
681 $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
682 $gmt_offset = -$diff_gmt_weblogger;
684 // Add a gmt_offset option, with value $gmt_offset
685 add_option('gmt_offset', $gmt_offset);
687 // Check if we already set the GMT fields (if we did, then
688 // MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
689 // <michel_v> I just slapped myself silly for not thinking about it earlier
690 $got_gmt_fields = ! ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00');
692 if (!$got_gmt_fields) {
694 // Add or subtract time to all dates, to get GMT dates
695 $add_hours = intval($diff_gmt_weblogger);
696 $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
697 $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
698 $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
699 $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'");
700 $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
701 $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
707 * Execute changes made in WordPress 1.5.
712 * @global wpdb $wpdb WordPress database abstraction object.
714 function upgrade_130() {
717 // Remove extraneous backslashes.
718 $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
720 foreach ($posts as $post) {
721 $post_content = addslashes(deslash($post->post_content));
722 $post_title = addslashes(deslash($post->post_title));
723 $post_excerpt = addslashes(deslash($post->post_excerpt));
724 if ( empty($post->guid) )
725 $guid = get_permalink($post->ID);
729 $wpdb->update( $wpdb->posts, compact('post_title', 'post_content', 'post_excerpt', 'guid'), array('ID' => $post->ID) );
734 // Remove extraneous backslashes.
735 $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
737 foreach ($comments as $comment) {
738 $comment_content = deslash($comment->comment_content);
739 $comment_author = deslash($comment->comment_author);
741 $wpdb->update($wpdb->comments, compact('comment_content', 'comment_author'), array('comment_ID' => $comment->comment_ID) );
745 // Remove extraneous backslashes.
746 $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
748 foreach ($links as $link) {
749 $link_name = deslash($link->link_name);
750 $link_description = deslash($link->link_description);
752 $wpdb->update( $wpdb->links, compact('link_name', 'link_description'), array('link_id' => $link->link_id) );
756 $active_plugins = __get_option('active_plugins');
759 * If plugins are not stored in an array, they're stored in the old
760 * newline separated format. Convert to new format.
762 if ( !is_array( $active_plugins ) ) {
763 $active_plugins = explode("\n", trim($active_plugins));
764 update_option('active_plugins', $active_plugins);
768 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues');
769 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes');
770 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups');
771 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options');
773 // Update comments table to use comment_type
774 $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
775 $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
777 // Some versions have multiple duplicate option_name rows with the same values
778 $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
779 foreach ( $options as $option ) {
780 if ( 1 != $option->dupes ) { // Could this be done in the query?
781 $limit = $option->dupes - 1;
782 $dupe_ids = $wpdb->get_col( $wpdb->prepare("SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit) );
784 $dupe_ids = join($dupe_ids, ',');
785 $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
794 * Execute changes made in WordPress 2.0.
799 * @global wpdb $wpdb WordPress database abstraction object.
800 * @global int $wp_current_db_version
802 function upgrade_160() {
803 global $wpdb, $wp_current_db_version;
805 populate_roles_160();
807 $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
808 foreach ( $users as $user ) :
809 if ( !empty( $user->user_firstname ) )
810 update_user_meta( $user->ID, 'first_name', wp_slash($user->user_firstname) );
811 if ( !empty( $user->user_lastname ) )
812 update_user_meta( $user->ID, 'last_name', wp_slash($user->user_lastname) );
813 if ( !empty( $user->user_nickname ) )
814 update_user_meta( $user->ID, 'nickname', wp_slash($user->user_nickname) );
815 if ( !empty( $user->user_level ) )
816 update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level );
817 if ( !empty( $user->user_icq ) )
818 update_user_meta( $user->ID, 'icq', wp_slash($user->user_icq) );
819 if ( !empty( $user->user_aim ) )
820 update_user_meta( $user->ID, 'aim', wp_slash($user->user_aim) );
821 if ( !empty( $user->user_msn ) )
822 update_user_meta( $user->ID, 'msn', wp_slash($user->user_msn) );
823 if ( !empty( $user->user_yim ) )
824 update_user_meta( $user->ID, 'yim', wp_slash($user->user_icq) );
825 if ( !empty( $user->user_description ) )
826 update_user_meta( $user->ID, 'description', wp_slash($user->user_description) );
828 if ( isset( $user->user_idmode ) ):
829 $idmode = $user->user_idmode;
830 if ($idmode == 'nickname') $id = $user->user_nickname;
831 if ($idmode == 'login') $id = $user->user_login;
832 if ($idmode == 'firstname') $id = $user->user_firstname;
833 if ($idmode == 'lastname') $id = $user->user_lastname;
834 if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
835 if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
836 if (!$idmode) $id = $user->user_nickname;
837 $wpdb->update( $wpdb->users, array('display_name' => $id), array('ID' => $user->ID) );
840 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
841 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities');
842 if ( empty($caps) || defined('RESET_CAPS') ) {
843 $level = get_user_meta($user->ID, $wpdb->prefix . 'user_level', true);
844 $role = translate_level_to_role($level);
845 update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) );
849 $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' );
850 $wpdb->hide_errors();
851 foreach ( $old_user_fields as $old )
852 $wpdb->query("ALTER TABLE $wpdb->users DROP $old");
853 $wpdb->show_errors();
855 // Populate comment_count field of posts table.
856 $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
857 if ( is_array( $comments ) )
858 foreach ($comments as $comment)
859 $wpdb->update( $wpdb->posts, array('comment_count' => $comment->c), array('ID' => $comment->comment_post_ID) );
862 * Some alpha versions used a post status of object instead of attachment
863 * and put the mime type in post_type instead of post_mime_type.
865 if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
866 $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
867 foreach ($objects as $object) {
868 $wpdb->update( $wpdb->posts, array( 'post_status' => 'attachment',
869 'post_mime_type' => $object->post_type,
871 array( 'ID' => $object->ID ) );
873 $meta = get_post_meta($object->ID, 'imagedata', true);
874 if ( ! empty($meta['file']) )
875 update_attached_file( $object->ID, $meta['file'] );
881 * Execute changes made in WordPress 2.1.
886 * @global wpdb $wpdb WordPress database abstraction object.
887 * @global int $wp_current_db_version
889 function upgrade_210() {
890 global $wpdb, $wp_current_db_version;
892 if ( $wp_current_db_version < 3506 ) {
893 // Update status and type.
894 $posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts");
896 if ( ! empty($posts) ) foreach ($posts as $post) {
897 $status = $post->post_status;
900 if ( 'static' == $status ) {
903 } elseif ( 'attachment' == $status ) {
905 $type = 'attachment';
908 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID) );
912 if ( $wp_current_db_version < 3845 ) {
913 populate_roles_210();
916 if ( $wp_current_db_version < 3531 ) {
917 // Give future posts a post_status of future.
918 $now = gmdate('Y-m-d H:i:59');
919 $wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'");
921 $posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'");
922 if ( !empty($posts) )
923 foreach ( $posts as $post )
924 wp_schedule_single_event(mysql2date('U', $post->post_date, false), 'publish_future_post', array($post->ID));
929 * Execute changes made in WordPress 2.3.
934 * @global wpdb $wpdb WordPress database abstraction object.
935 * @global int $wp_current_db_version
937 function upgrade_230() {
938 global $wp_current_db_version, $wpdb;
940 if ( $wp_current_db_version < 5200 ) {
941 populate_roles_230();
944 // Convert categories to terms.
947 $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID");
948 foreach ($categories as $category) {
949 $term_id = (int) $category->cat_ID;
950 $name = $category->cat_name;
951 $description = $category->category_description;
952 $slug = $category->category_nicename;
953 $parent = $category->category_parent;
956 // Associate terms with the same slug in a term group and make slugs unique.
957 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
958 $term_group = $exists[0]->term_group;
959 $id = $exists[0]->term_id;
962 $alt_slug = $slug . "-$num";
964 $slug_check = $wpdb->get_var( $wpdb->prepare("SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug) );
965 } while ( $slug_check );
969 if ( empty( $term_group ) ) {
970 $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
971 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id) );
975 $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES
976 (%d, %s, %s, %d)", $term_id, $name, $slug, $term_group) );
979 if ( !empty($category->category_count) ) {
980 $count = (int) $category->category_count;
981 $taxonomy = 'category';
982 $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) );
983 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
986 if ( !empty($category->link_count) ) {
987 $count = (int) $category->link_count;
988 $taxonomy = 'link_category';
989 $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) );
990 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
993 if ( !empty($category->tag_count) ) {
995 $count = (int) $category->tag_count;
996 $taxonomy = 'post_tag';
997 $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
998 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
1001 if ( empty($count) ) {
1003 $taxonomy = 'category';
1004 $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') );
1005 $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id;
1009 $select = 'post_id, category_id';
1011 $select .= ', rel_type';
1013 $posts = $wpdb->get_results("SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id");
1014 foreach ( $posts as $post ) {
1015 $post_id = (int) $post->post_id;
1016 $term_id = (int) $post->category_id;
1017 $taxonomy = 'category';
1018 if ( !empty($post->rel_type) && 'tag' == $post->rel_type)
1020 $tt_id = $tt_ids[$term_id][$taxonomy];
1021 if ( empty($tt_id) )
1024 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $post_id, 'term_taxonomy_id' => $tt_id) );
1027 // < 3570 we used linkcategories. >= 3570 we used categories and link2cat.
1028 if ( $wp_current_db_version < 3570 ) {
1030 * Create link_category terms for link categories. Create a map of link
1031 * cat IDs to link_category terms.
1033 $link_cat_id_map = array();
1034 $default_link_cat = 0;
1036 $link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories');
1037 foreach ( $link_cats as $category) {
1038 $cat_id = (int) $category->cat_id;
1040 $name = wp_slash($category->cat_name);
1041 $slug = sanitize_title($name);
1044 // Associate terms with the same slug in a term group and make slugs unique.
1045 if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) {
1046 $term_group = $exists[0]->term_group;
1047 $term_id = $exists[0]->term_id;
1050 if ( empty($term_id) ) {
1051 $wpdb->insert( $wpdb->terms, compact('name', 'slug', 'term_group') );
1052 $term_id = (int) $wpdb->insert_id;
1055 $link_cat_id_map[$cat_id] = $term_id;
1056 $default_link_cat = $term_id;
1058 $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $term_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 0) );
1059 $tt_ids[$term_id] = (int) $wpdb->insert_id;
1062 // Associate links to cats.
1063 $links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links");
1064 if ( !empty($links) ) foreach ( $links as $link ) {
1065 if ( 0 == $link->link_category )
1067 if ( ! isset($link_cat_id_map[$link->link_category]) )
1069 $term_id = $link_cat_id_map[$link->link_category];
1070 $tt_id = $tt_ids[$term_id];
1071 if ( empty($tt_id) )
1074 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link->link_id, 'term_taxonomy_id' => $tt_id) );
1077 // Set default to the last category we grabbed during the upgrade loop.
1078 update_option('default_link_category', $default_link_cat);
1080 $links = $wpdb->get_results("SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id");
1081 foreach ( $links as $link ) {
1082 $link_id = (int) $link->link_id;
1083 $term_id = (int) $link->category_id;
1084 $taxonomy = 'link_category';
1085 $tt_id = $tt_ids[$term_id][$taxonomy];
1086 if ( empty($tt_id) )
1088 $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link_id, 'term_taxonomy_id' => $tt_id) );
1092 if ( $wp_current_db_version < 4772 ) {
1093 // Obsolete linkcategories table
1094 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories');
1097 // Recalculate all counts
1098 $terms = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy");
1099 foreach ( (array) $terms as $term ) {
1100 if ( ('post_tag' == $term->taxonomy) || ('category' == $term->taxonomy) )
1101 $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) );
1103 $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id) );
1104 $wpdb->update( $wpdb->term_taxonomy, array('count' => $count), array('term_taxonomy_id' => $term->term_taxonomy_id) );
1109 * Remove old options from the database.
1114 * @global wpdb $wpdb WordPress database abstraction object.
1116 function upgrade_230_options_table() {
1118 $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' );
1119 $wpdb->hide_errors();
1120 foreach ( $old_options_fields as $old )
1121 $wpdb->query("ALTER TABLE $wpdb->options DROP $old");
1122 $wpdb->show_errors();
1126 * Remove old categories, link2cat, and post2cat database tables.
1131 * @global wpdb $wpdb WordPress database abstraction object.
1133 function upgrade_230_old_tables() {
1135 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories');
1136 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat');
1137 $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat');
1141 * Upgrade old slugs made in version 2.2.
1146 * @global wpdb $wpdb WordPress database abstraction object.
1148 function upgrade_old_slugs() {
1149 // Upgrade people who were using the Redirect Old Slugs plugin.
1151 $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'");
1155 * Execute changes made in WordPress 2.5.0.
1160 * @global int $wp_current_db_version
1162 function upgrade_250() {
1163 global $wp_current_db_version;
1165 if ( $wp_current_db_version < 6689 ) {
1166 populate_roles_250();
1172 * Execute changes made in WordPress 2.5.2.
1177 * @global wpdb $wpdb WordPress database abstraction object.
1179 function upgrade_252() {
1182 $wpdb->query("UPDATE $wpdb->users SET user_activation_key = ''");
1186 * Execute changes made in WordPress 2.6.
1191 * @global int $wp_current_db_version
1193 function upgrade_260() {
1194 global $wp_current_db_version;
1196 if ( $wp_current_db_version < 8000 )
1197 populate_roles_260();
1201 * Execute changes made in WordPress 2.7.
1206 * @global wpdb $wpdb WordPress database abstraction object.
1207 * @global int $wp_current_db_version
1209 function upgrade_270() {
1210 global $wpdb, $wp_current_db_version;
1212 if ( $wp_current_db_version < 8980 )
1213 populate_roles_270();
1215 // Update post_date for unpublished posts with empty timestamp
1216 if ( $wp_current_db_version < 8921 )
1217 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" );
1221 * Execute changes made in WordPress 2.8.
1226 * @global int $wp_current_db_version
1227 * @global wpdb $wpdb WordPress database abstraction object.
1229 function upgrade_280() {
1230 global $wp_current_db_version, $wpdb;
1232 if ( $wp_current_db_version < 10360 )
1233 populate_roles_280();
1234 if ( is_multisite() ) {
1236 while( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) {
1237 foreach ( $rows as $row ) {
1238 $value = $row->option_value;
1239 if ( !@unserialize( $value ) )
1240 $value = stripslashes( $value );
1241 if ( $value !== $row->option_value ) {
1242 update_option( $row->option_name, $value );
1247 refresh_blog_details( $wpdb->blogid );
1252 * Execute changes made in WordPress 2.9.
1257 * @global int $wp_current_db_version
1259 function upgrade_290() {
1260 global $wp_current_db_version;
1262 if ( $wp_current_db_version < 11958 ) {
1263 // Previously, setting depth to 1 would redundantly disable threading, but now 2 is the minimum depth to avoid confusion
1264 if ( get_option( 'thread_comments_depth' ) == '1' ) {
1265 update_option( 'thread_comments_depth', 2 );
1266 update_option( 'thread_comments', 0 );
1272 * Execute changes made in WordPress 3.0.
1277 * @global int $wp_current_db_version
1278 * @global wpdb $wpdb WordPress database abstraction object.
1280 function upgrade_300() {
1281 global $wp_current_db_version, $wpdb;
1283 if ( $wp_current_db_version < 15093 )
1284 populate_roles_300();
1286 if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false )
1287 add_site_option( 'siteurl', '' );
1289 // 3.0 screen options key name changes.
1290 if ( wp_should_upgrade_global_tables() ) {
1291 $sql = "DELETE FROM $wpdb->usermeta
1292 WHERE meta_key LIKE %s
1298 OR meta_key = 'manageedittagscolumnshidden'
1299 OR meta_key = 'managecategoriescolumnshidden'
1300 OR meta_key = 'manageedit-tagscolumnshidden'
1301 OR meta_key = 'manageeditcolumnshidden'
1302 OR meta_key = 'categories_per_page'
1303 OR meta_key = 'edit_tags_per_page'";
1304 $prefix = $wpdb->esc_like( $wpdb->base_prefix );
1305 $wpdb->query( $wpdb->prepare( $sql,
1306 $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%',
1307 $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%',
1308 $prefix . '%' . $wpdb->esc_like( 'manage-' ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%',
1309 $prefix . '%' . $wpdb->esc_like( 'meta-box-order' ) . '%',
1310 $prefix . '%' . $wpdb->esc_like( 'metaboxorder' ) . '%',
1311 $prefix . '%' . $wpdb->esc_like( 'screen_layout' ) . '%'
1318 * Execute changes made in WordPress 3.3.
1323 * @global int $wp_current_db_version
1324 * @global wpdb $wpdb
1325 * @global array $wp_registered_widgets
1326 * @global array $sidebars_widgets
1328 function upgrade_330() {
1329 global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets;
1331 if ( $wp_current_db_version < 19061 && wp_should_upgrade_global_tables() ) {
1332 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" );
1335 if ( $wp_current_db_version >= 11548 )
1338 $sidebars_widgets = get_option( 'sidebars_widgets', array() );
1339 $_sidebars_widgets = array();
1341 if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) )
1342 $sidebars_widgets['array_version'] = 3;
1343 elseif ( !isset($sidebars_widgets['array_version']) )
1344 $sidebars_widgets['array_version'] = 1;
1346 switch ( $sidebars_widgets['array_version'] ) {
1348 foreach ( (array) $sidebars_widgets as $index => $sidebar )
1349 if ( is_array($sidebar) )
1350 foreach ( (array) $sidebar as $i => $name ) {
1351 $id = strtolower($name);
1352 if ( isset($wp_registered_widgets[$id]) ) {
1353 $_sidebars_widgets[$index][$i] = $id;
1356 $id = sanitize_title($name);
1357 if ( isset($wp_registered_widgets[$id]) ) {
1358 $_sidebars_widgets[$index][$i] = $id;
1364 foreach ( $wp_registered_widgets as $widget_id => $widget ) {
1365 if ( strtolower($widget['name']) == strtolower($name) ) {
1366 $_sidebars_widgets[$index][$i] = $widget['id'];
1369 } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) {
1370 $_sidebars_widgets[$index][$i] = $widget['id'];
1379 unset($_sidebars_widgets[$index][$i]);
1381 $_sidebars_widgets['array_version'] = 2;
1382 $sidebars_widgets = $_sidebars_widgets;
1383 unset($_sidebars_widgets);
1386 $sidebars_widgets = retrieve_widgets();
1387 $sidebars_widgets['array_version'] = 3;
1388 update_option( 'sidebars_widgets', $sidebars_widgets );
1393 * Execute changes made in WordPress 3.4.
1398 * @global int $wp_current_db_version
1399 * @global wpdb $wpdb
1401 function upgrade_340() {
1402 global $wp_current_db_version, $wpdb;
1404 if ( $wp_current_db_version < 19798 ) {
1405 $wpdb->hide_errors();
1406 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" );
1407 $wpdb->show_errors();
1410 if ( $wp_current_db_version < 19799 ) {
1411 $wpdb->hide_errors();
1412 $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved");
1413 $wpdb->show_errors();
1416 if ( $wp_current_db_version < 20022 && wp_should_upgrade_global_tables() ) {
1417 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" );
1420 if ( $wp_current_db_version < 20080 ) {
1421 if ( 'yes' == $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) {
1422 $uninstall_plugins = get_option( 'uninstall_plugins' );
1423 delete_option( 'uninstall_plugins' );
1424 add_option( 'uninstall_plugins', $uninstall_plugins, null, 'no' );
1430 * Execute changes made in WordPress 3.5.
1435 * @global int $wp_current_db_version
1436 * @global wpdb $wpdb
1438 function upgrade_350() {
1439 global $wp_current_db_version, $wpdb;
1441 if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
1442 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options()
1444 if ( $wp_current_db_version < 21811 && wp_should_upgrade_global_tables() ) {
1445 $meta_keys = array();
1446 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) {
1447 if ( false !== strpos( $name, '-' ) )
1448 $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page';
1451 $meta_keys = implode( "', '", $meta_keys );
1452 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" );
1456 if ( $wp_current_db_version < 22422 && $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ) )
1457 wp_delete_term( $term->term_id, 'post_format' );
1461 * Execute changes made in WordPress 3.7.
1466 * @global int $wp_current_db_version
1468 function upgrade_370() {
1469 global $wp_current_db_version;
1470 if ( $wp_current_db_version < 25824 )
1471 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' );
1475 * Execute changes made in WordPress 3.7.2.
1481 * @global int $wp_current_db_version
1483 function upgrade_372() {
1484 global $wp_current_db_version;
1485 if ( $wp_current_db_version < 26148 )
1486 wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
1490 * Execute changes made in WordPress 3.8.0.
1495 * @global int $wp_current_db_version
1497 function upgrade_380() {
1498 global $wp_current_db_version;
1499 if ( $wp_current_db_version < 26691 ) {
1500 deactivate_plugins( array( 'mp6/mp6.php' ), true );
1505 * Execute changes made in WordPress 4.0.0.
1510 * @global int $wp_current_db_version
1512 function upgrade_400() {
1513 global $wp_current_db_version;
1514 if ( $wp_current_db_version < 29630 ) {
1515 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) {
1516 if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages() ) ) {
1517 update_option( 'WPLANG', WPLANG );
1519 update_option( 'WPLANG', '' );
1526 * Execute changes made in WordPress 4.2.0.
1531 * @global int $wp_current_db_version
1532 * @global wpdb $wpdb
1534 function upgrade_420() {}
1537 * Executes changes made in WordPress 4.3.0.
1542 * @global int $wp_current_db_version Current version.
1543 * @global wpdb $wpdb WordPress database abstraction object.
1545 function upgrade_430() {
1546 global $wp_current_db_version, $wpdb;
1548 if ( $wp_current_db_version < 32364 ) {
1549 upgrade_430_fix_comments();
1552 // Shared terms are split in a separate process.
1553 if ( $wp_current_db_version < 32814 ) {
1554 update_option( 'finished_splitting_shared_terms', 0 );
1555 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
1558 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) {
1559 if ( is_multisite() ) {
1560 $tables = $wpdb->tables( 'blog' );
1562 $tables = $wpdb->tables( 'all' );
1563 if ( ! wp_should_upgrade_global_tables() ) {
1564 $global_tables = $wpdb->tables( 'global' );
1565 $tables = array_diff_assoc( $tables, $global_tables );
1569 foreach ( $tables as $table ) {
1570 maybe_convert_table_to_utf8mb4( $table );
1576 * Executes comments changes made in WordPress 4.3.0.
1581 * @global int $wp_current_db_version Current version.
1582 * @global wpdb $wpdb WordPress database abstraction object.
1584 function upgrade_430_fix_comments() {
1585 global $wp_current_db_version, $wpdb;
1587 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' );
1589 if ( is_wp_error( $content_length ) ) {
1593 if ( false === $content_length ) {
1594 $content_length = array(
1598 } elseif ( ! is_array( $content_length ) ) {
1599 $length = (int) $content_length > 0 ? (int) $content_length : 65535;
1600 $content_length = array(
1606 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) {
1607 // Sites with malformed DB schemas are on their own.
1611 $allowed_length = intval( $content_length['length'] ) - 10;
1613 $comments = $wpdb->get_results(
1614 "SELECT `comment_ID` FROM `{$wpdb->comments}`
1615 WHERE `comment_date_gmt` > '2015-04-26'
1616 AND LENGTH( `comment_content` ) >= {$allowed_length}
1617 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )"
1620 foreach ( $comments as $comment ) {
1621 wp_delete_comment( $comment->comment_ID, true );
1626 * Executes changes made in WordPress 4.3.1.
1631 function upgrade_431() {
1632 // Fix incorrect cron entries for term splitting
1633 $cron_array = _get_cron_array();
1634 if ( isset( $cron_array['wp_batch_split_terms'] ) ) {
1635 unset( $cron_array['wp_batch_split_terms'] );
1636 _set_cron_array( $cron_array );
1641 * Executes changes made in WordPress 4.4.0.
1646 * @global int $wp_current_db_version Current version.
1647 * @global wpdb $wpdb WordPress database abstraction object.
1649 function upgrade_440() {
1650 global $wp_current_db_version, $wpdb;
1652 if ( $wp_current_db_version < 34030 ) {
1653 $wpdb->query( "ALTER TABLE {$wpdb->options} MODIFY option_name VARCHAR(191)" );
1656 // Remove the unused 'add_users' role.
1657 $roles = wp_roles();
1658 foreach ( $roles->role_objects as $role ) {
1659 if ( $role->has_cap( 'add_users' ) ) {
1660 $role->remove_cap( 'add_users' );
1666 * Executes changes made in WordPress 4.5.0.
1671 * @global int $wp_current_db_version Current database version.
1672 * @global wpdb $wpdb WordPress database abstraction object.
1674 function upgrade_450() {
1675 global $wp_current_db_version, $wpdb;
1677 if ( $wp_current_db_version < 36180 ) {
1678 wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
1681 // Remove unused email confirmation options, moved to usermeta.
1682 if ( $wp_current_db_version < 36679 && is_multisite() ) {
1683 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^[0-9]+_new_email$'" );
1686 // Remove unused user setting for wpLink.
1687 delete_user_setting( 'wplink' );
1691 * Executes network-level upgrade routines.
1695 * @global int $wp_current_db_version
1696 * @global wpdb $wpdb
1698 function upgrade_network() {
1699 global $wp_current_db_version, $wpdb;
1702 if ( is_main_network() ) {
1704 * Deletes all expired transients. The multi-table delete syntax is used
1705 * to delete the transient record from table a, and the corresponding
1706 * transient_timeout record from table b.
1709 $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
1710 WHERE a.meta_key LIKE %s
1711 AND a.meta_key NOT LIKE %s
1712 AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1713 AND b.meta_value < %d";
1714 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
1718 if ( $wp_current_db_version < 11549 ) {
1719 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' );
1720 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' );
1721 if ( $wpmu_sitewide_plugins ) {
1722 if ( !$active_sitewide_plugins )
1723 $sitewide_plugins = (array) $wpmu_sitewide_plugins;
1725 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins );
1727 update_site_option( 'active_sitewide_plugins', $sitewide_plugins );
1729 delete_site_option( 'wpmu_sitewide_plugins' );
1730 delete_site_option( 'deactivated_sitewide_plugins' );
1733 while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) {
1734 foreach ( $rows as $row ) {
1735 $value = $row->meta_value;
1736 if ( !@unserialize( $value ) )
1737 $value = stripslashes( $value );
1738 if ( $value !== $row->meta_value ) {
1739 update_site_option( $row->meta_key, $value );
1747 if ( $wp_current_db_version < 13576 )
1748 update_site_option( 'global_terms_enabled', '1' );
1751 if ( $wp_current_db_version < 19390 )
1752 update_site_option( 'initial_db_version', $wp_current_db_version );
1754 if ( $wp_current_db_version < 19470 ) {
1755 if ( false === get_site_option( 'active_sitewide_plugins' ) )
1756 update_site_option( 'active_sitewide_plugins', array() );
1760 if ( $wp_current_db_version < 20148 ) {
1761 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name.
1762 $allowedthemes = get_site_option( 'allowedthemes' );
1763 $allowed_themes = get_site_option( 'allowed_themes' );
1764 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) {
1765 $converted = array();
1766 $themes = wp_get_themes();
1767 foreach ( $themes as $stylesheet => $theme_data ) {
1768 if ( isset( $allowed_themes[ $theme_data->get('Name') ] ) )
1769 $converted[ $stylesheet ] = true;
1771 update_site_option( 'allowedthemes', $converted );
1772 delete_site_option( 'allowed_themes' );
1777 if ( $wp_current_db_version < 21823 )
1778 update_site_option( 'ms_files_rewriting', '1' );
1781 if ( $wp_current_db_version < 24448 ) {
1782 $illegal_names = get_site_option( 'illegal_names' );
1783 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) {
1784 $illegal_name = reset( $illegal_names );
1785 $illegal_names = explode( ' ', $illegal_name );
1786 update_site_option( 'illegal_names', $illegal_names );
1791 if ( $wp_current_db_version < 31351 && $wpdb->charset === 'utf8mb4' ) {
1792 if ( wp_should_upgrade_global_tables() ) {
1793 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1794 $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" );
1795 $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
1796 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1798 $tables = $wpdb->tables( 'global' );
1800 // sitecategories may not exist.
1801 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) {
1802 unset( $tables['sitecategories'] );
1805 foreach ( $tables as $table ) {
1806 maybe_convert_table_to_utf8mb4( $table );
1812 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) {
1813 if ( wp_should_upgrade_global_tables() ) {
1815 $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" );
1816 foreach ( $indexes as $index ) {
1817 if ( 'domain_path' == $index->Key_name && 'domain' == $index->Column_name && 140 != $index->Sub_part ) {
1824 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" );
1827 $tables = $wpdb->tables( 'global' );
1829 // sitecategories may not exist.
1830 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) {
1831 unset( $tables['sitecategories'] );
1834 foreach ( $tables as $table ) {
1835 maybe_convert_table_to_utf8mb4( $table );
1842 // General functions we use to actually do stuff
1846 * Creates a table in the database if it doesn't already exist.
1848 * This method checks for an existing database and creates a new one if it's not
1849 * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses
1850 * to query all tables first and then run the SQL statement creating the table.
1854 * @global wpdb $wpdb
1856 * @param string $table_name Database table name to create.
1857 * @param string $create_ddl SQL statement to create table.
1858 * @return bool If table already exists or was created by function.
1860 function maybe_create_table($table_name, $create_ddl) {
1863 $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
1865 if ( $wpdb->get_var( $query ) == $table_name ) {
1869 // Didn't find it try to create it..
1870 $wpdb->query($create_ddl);
1872 // We cannot directly tell that whether this succeeded!
1873 if ( $wpdb->get_var( $query ) == $table_name ) {
1880 * Drops a specified index from a table.
1884 * @global wpdb $wpdb
1886 * @param string $table Database table name.
1887 * @param string $index Index name to drop.
1888 * @return true True, when finished.
1890 function drop_index($table, $index) {
1892 $wpdb->hide_errors();
1893 $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
1894 // Now we need to take out all the extra ones we may have created
1895 for ($i = 0; $i < 25; $i++) {
1896 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
1898 $wpdb->show_errors();
1903 * Adds an index to a specified table.
1907 * @global wpdb $wpdb
1909 * @param string $table Database table name.
1910 * @param string $index Database table index column.
1911 * @return true True, when done with execution.
1913 function add_clean_index($table, $index) {
1915 drop_index($table, $index);
1916 $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
1921 * Adds column to a database table if it doesn't already exist.
1925 * @global wpdb $wpdb
1927 * @param string $table_name The table name to modify.
1928 * @param string $column_name The column name to add to the table.
1929 * @param string $create_ddl The SQL statement used to add the column.
1930 * @return bool True if already exists or on successful completion, false on error.
1932 function maybe_add_column($table_name, $column_name, $create_ddl) {
1934 foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1935 if ($column == $column_name) {
1940 // Didn't find it try to create it.
1941 $wpdb->query($create_ddl);
1943 // We cannot directly tell that whether this succeeded!
1944 foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
1945 if ($column == $column_name) {
1953 * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4.
1957 * @global wpdb $wpdb
1959 * @param string $table The table to convert.
1960 * @return bool true if the table was converted, false if it wasn't.
1962 function maybe_convert_table_to_utf8mb4( $table ) {
1965 $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" );
1970 foreach ( $results as $column ) {
1971 if ( $column->Collation ) {
1972 list( $charset ) = explode( '_', $column->Collation );
1973 $charset = strtolower( $charset );
1974 if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) {
1975 // Don't upgrade tables that have non-utf8 columns.
1981 $table_details = $wpdb->get_row( "SHOW TABLE STATUS LIKE '$table'" );
1982 if ( ! $table_details ) {
1986 list( $table_charset ) = explode( '_', $table_details->Collation );
1987 $table_charset = strtolower( $table_charset );
1988 if ( 'utf8mb4' === $table_charset ) {
1992 return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
1996 * Retrieve all options as it was for 1.2.
2000 * @global wpdb $wpdb
2002 * @return stdClass List of options.
2004 function get_alloptions_110() {
2006 $all_options = new stdClass;
2007 if ( $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ) ) {
2008 foreach ( $options as $option ) {
2009 if ( 'siteurl' == $option->option_name || 'home' == $option->option_name || 'category_base' == $option->option_name )
2010 $option->option_value = untrailingslashit( $option->option_value );
2011 $all_options->{$option->option_name} = stripslashes( $option->option_value );
2014 return $all_options;
2018 * Utility version of get_option that is private to install/upgrade.
2024 * @global wpdb $wpdb
2026 * @param string $setting Option name.
2029 function __get_option($setting) {
2032 if ( $setting == 'home' && defined( 'WP_HOME' ) )
2033 return untrailingslashit( WP_HOME );
2035 if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) )
2036 return untrailingslashit( WP_SITEURL );
2038 $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) );
2040 if ( 'home' == $setting && '' == $option )
2041 return __get_option( 'siteurl' );
2043 if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting || 'tag_base' == $setting )
2044 $option = untrailingslashit( $option );
2046 return maybe_unserialize( $option );
2050 * Filters for content to remove unnecessary slashes.
2054 * @param string $content The content to modify.
2055 * @return string The de-slashed content.
2057 function deslash($content) {
2058 // Note: \\\ inside a regex denotes a single backslash.
2061 * Replace one or more backslashes followed by a single quote with
2064 $content = preg_replace("/\\\+'/", "'", $content);
2067 * Replace one or more backslashes followed by a double quote with
2070 $content = preg_replace('/\\\+"/', '"', $content);
2072 // Replace one or more backslashes with one backslash.
2073 $content = preg_replace("/\\\+/", "\\", $content);
2079 * Modifies the database based on specified SQL statements.
2081 * Useful for creating new tables and updating existing tables to a new structure.
2085 * @global wpdb $wpdb
2087 * @param string|array $queries Optional. The query to run. Can be multiple queries
2088 * in an array, or a string of queries separated by
2089 * semicolons. Default empty.
2090 * @param bool $execute Optional. Whether or not to execute the query right away.
2092 * @return array Strings containing the results of the various update queries.
2094 function dbDelta( $queries = '', $execute = true ) {
2097 if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) )
2098 $queries = wp_get_db_schema( $queries );
2100 // Separate individual queries into an array
2101 if ( !is_array($queries) ) {
2102 $queries = explode( ';', $queries );
2103 $queries = array_filter( $queries );
2107 * Filter the dbDelta SQL queries.
2111 * @param array $queries An array of dbDelta SQL queries.
2113 $queries = apply_filters( 'dbdelta_queries', $queries );
2115 $cqueries = array(); // Creation Queries
2116 $iqueries = array(); // Insertion Queries
2117 $for_update = array();
2119 // Create a tablename index for an array ($cqueries) of queries
2120 foreach ($queries as $qry) {
2121 if ( preg_match( "|CREATE TABLE ([^ ]*)|", $qry, $matches ) ) {
2122 $cqueries[ trim( $matches[1], '`' ) ] = $qry;
2123 $for_update[$matches[1]] = 'Created table '.$matches[1];
2124 } elseif ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
2125 array_unshift( $cqueries, $qry );
2126 } elseif ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
2128 } elseif ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
2131 // Unrecognized query type
2136 * Filter the dbDelta SQL queries for creating tables and/or databases.
2138 * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE".
2142 * @param array $cqueries An array of dbDelta create SQL queries.
2144 $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries );
2147 * Filter the dbDelta SQL queries for inserting or updating.
2149 * Queries filterable via this hook contain "INSERT INTO" or "UPDATE".
2153 * @param array $iqueries An array of dbDelta insert or update SQL queries.
2155 $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries );
2157 $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' );
2158 $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' );
2160 $global_tables = $wpdb->tables( 'global' );
2161 foreach ( $cqueries as $table => $qry ) {
2162 // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal.
2163 if ( in_array( $table, $global_tables ) && ! wp_should_upgrade_global_tables() ) {
2164 unset( $cqueries[ $table ], $for_update[ $table ] );
2168 // Fetch the table column structure from the database
2169 $suppress = $wpdb->suppress_errors();
2170 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
2171 $wpdb->suppress_errors( $suppress );
2173 if ( ! $tablefields )
2176 // Clear the field and index arrays.
2177 $cfields = $indices = array();
2179 // Get all of the field names in the query from between the parentheses.
2180 preg_match("|\((.*)\)|ms", $qry, $match2);
2181 $qryline = trim($match2[1]);
2183 // Separate field lines into an array.
2184 $flds = explode("\n", $qryline);
2186 // todo: Remove this?
2187 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
2189 // For every field line specified in the query.
2190 foreach ($flds as $fld) {
2192 // Extract the field name.
2193 preg_match("|^([^ ]*)|", trim($fld), $fvals);
2194 $fieldname = trim( $fvals[1], '`' );
2196 // Verify the found field name.
2198 switch (strtolower($fieldname)) {
2205 $validfield = false;
2206 $indices[] = trim(trim($fld), ", \n");
2211 // If it's a valid field, add it to the field array.
2213 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
2217 // For every field in the table.
2218 foreach ($tablefields as $tablefield) {
2220 // If the table field exists in the field array ...
2221 if (array_key_exists(strtolower($tablefield->Field), $cfields)) {
2223 // Get the field type from the query.
2224 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
2225 $fieldtype = $matches[1];
2227 // Is actual field type different from the field type in query?
2228 if ($tablefield->Type != $fieldtype) {
2230 if ( in_array( strtolower( $fieldtype ), $text_fields ) && in_array( strtolower( $tablefield->Type ), $text_fields ) ) {
2231 if ( array_search( strtolower( $fieldtype ), $text_fields ) < array_search( strtolower( $tablefield->Type ), $text_fields ) ) {
2236 if ( in_array( strtolower( $fieldtype ), $blob_fields ) && in_array( strtolower( $tablefield->Type ), $blob_fields ) ) {
2237 if ( array_search( strtolower( $fieldtype ), $blob_fields ) < array_search( strtolower( $tablefield->Type ), $blob_fields ) ) {
2243 // Add a query to change the column type
2244 $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
2245 $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
2249 // Get the default value from the array
2250 // todo: Remove this?
2251 //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
2252 if (preg_match("| DEFAULT '(.*?)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
2253 $default_value = $matches[1];
2254 if ($tablefield->Default != $default_value) {
2255 // Add a query to change the column's default value
2256 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
2257 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
2261 // Remove the field from the array (so it's not added).
2262 unset($cfields[strtolower($tablefield->Field)]);
2264 // This field exists in the table, but not in the creation queries?
2268 // For every remaining field specified for the table.
2269 foreach ($cfields as $fieldname => $fielddef) {
2270 // Push a query line into $cqueries that adds the field to that table.
2271 $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
2272 $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
2275 // Index stuff goes here. Fetch the table index structure from the database.
2276 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
2278 if ($tableindices) {
2279 // Clear the index array.
2280 $index_ary = array();
2282 // For every index in the table.
2283 foreach ($tableindices as $tableindex) {
2285 // Add the index to the index data array.
2286 $keyname = $tableindex->Key_name;
2287 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
2288 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
2289 $index_ary[$keyname]['index_type'] = $tableindex->Index_type;
2292 // For each actual index in the index array.
2293 foreach ($index_ary as $index_name => $index_data) {
2295 // Build a create string to compare to the query.
2297 if ($index_name == 'PRIMARY') {
2298 $index_string .= 'PRIMARY ';
2299 } elseif ( $index_data['unique'] ) {
2300 $index_string .= 'UNIQUE ';
2302 if ( 'FULLTEXT' === strtoupper( $index_data['index_type'] ) ) {
2303 $index_string .= 'FULLTEXT ';
2305 $index_string .= 'KEY ';
2306 if ($index_name != 'PRIMARY') {
2307 $index_string .= $index_name;
2309 $index_columns = '';
2311 // For each column in the index.
2312 foreach ($index_data['columns'] as $column_data) {
2313 if ($index_columns != '') $index_columns .= ',';
2315 // Add the field to the column list string.
2316 $index_columns .= $column_data['fieldname'];
2317 if ($column_data['subpart'] != '') {
2318 $index_columns .= '('.$column_data['subpart'].')';
2322 // The alternative index string doesn't care about subparts
2323 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
2325 // Add the column list to the index create string.
2326 $index_strings = array(
2327 "$index_string ($index_columns)",
2328 "$index_string ($alt_index_columns)",
2331 foreach ( $index_strings as $index_string ) {
2332 if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
2333 unset( $indices[ $aindex ] );
2335 // todo: Remove this?
2336 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
2339 // todo: Remove this?
2340 //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";
2344 // For every remaining index specified for the table.
2345 foreach ( (array) $indices as $index ) {
2346 // Push a query line into $cqueries that adds the index to that table.
2347 $cqueries[] = "ALTER TABLE {$table} ADD $index";
2348 $for_update[] = 'Added index ' . $table . ' ' . $index;
2351 // Remove the original table creation query from processing.
2352 unset( $cqueries[ $table ], $for_update[ $table ] );
2355 $allqueries = array_merge($cqueries, $iqueries);
2357 foreach ($allqueries as $query) {
2358 // todo: Remove this?
2359 //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
2360 $wpdb->query($query);
2368 * Updates the database tables to a new schema.
2370 * By default, updates all the tables to use the latest defined schema, but can also
2371 * be used to update a specific set of tables in wp_get_db_schema().
2377 * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2379 function make_db_current( $tables = 'all' ) {
2380 $alterations = dbDelta( $tables );
2382 foreach ($alterations as $alteration) echo "<li>$alteration</li>\n";
2387 * Updates the database tables to a new schema, but without displaying results.
2389 * By default, updates all the tables to use the latest defined schema, but can
2390 * also be used to update a specific set of tables in wp_get_db_schema().
2394 * @see make_db_current()
2396 * @param string $tables Optional. Which set of tables to update. Default is 'all'.
2398 function make_db_current_silent( $tables = 'all' ) {
2403 * Creates a site theme from an existing theme.
2405 * {@internal Missing Long Description}}
2409 * @param string $theme_name The name of the theme.
2410 * @param string $template The directory name of the theme.
2413 function make_site_theme_from_oldschool($theme_name, $template) {
2414 $home_path = get_home_path();
2415 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2417 if (! file_exists("$home_path/index.php"))
2421 * Copy files from the old locations to the site theme.
2422 * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
2424 $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
2426 foreach ($files as $oldfile => $newfile) {
2427 if ($oldfile == 'index.php')
2428 $oldpath = $home_path;
2432 // Check to make sure it's not a new index.
2433 if ($oldfile == 'index.php') {
2434 $index = implode('', file("$oldpath/$oldfile"));
2435 if (strpos($index, 'WP_USE_THEMES') !== false) {
2436 if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile"))
2439 // Don't copy anything.
2444 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
2447 chmod("$site_dir/$newfile", 0777);
2449 // Update the blog header include in each file.
2450 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
2452 $f = fopen("$site_dir/$newfile", 'w');
2454 foreach ($lines as $line) {
2455 if (preg_match('/require.*wp-blog-header/', $line))
2456 $line = '//' . $line;
2458 // Update stylesheet references.
2459 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
2461 // Update comments template inclusion.
2462 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
2464 fwrite($f, "{$line}\n");
2470 // Add a theme header.
2471 $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";
2473 $stylelines = file_get_contents("$site_dir/style.css");
2475 $f = fopen("$site_dir/style.css", 'w');
2477 fwrite($f, $header);
2478 fwrite($f, $stylelines);
2486 * Creates a site theme from the default theme.
2488 * {@internal Missing Long Description}}
2492 * @param string $theme_name The name of the theme.
2493 * @param string $template The directory name of the theme.
2494 * @return false|void
2496 function make_site_theme_from_default($theme_name, $template) {
2497 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2498 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
2500 // Copy files from the default theme to the site theme.
2501 //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
2503 $theme_dir = @ opendir($default_dir);
2505 while(($theme_file = readdir( $theme_dir )) !== false) {
2506 if (is_dir("$default_dir/$theme_file"))
2508 if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
2510 chmod("$site_dir/$theme_file", 0777);
2513 @closedir($theme_dir);
2515 // Rewrite the theme header.
2516 $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
2518 $f = fopen("$site_dir/style.css", 'w');
2520 foreach ($stylelines as $line) {
2521 if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
2522 elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
2523 elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
2524 elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
2525 elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
2526 fwrite($f, $line . "\n");
2533 if (! mkdir("$site_dir/images", 0777)) {
2537 $images_dir = @ opendir("$default_dir/images");
2539 while(($image = readdir($images_dir)) !== false) {
2540 if (is_dir("$default_dir/images/$image"))
2542 if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
2544 chmod("$site_dir/images/$image", 0777);
2547 @closedir($images_dir);
2551 * Creates a site theme.
2553 * {@internal Missing Long Description}}
2557 * @return false|string
2559 function make_site_theme() {
2560 // Name the theme after the blog.
2561 $theme_name = __get_option('blogname');
2562 $template = sanitize_title($theme_name);
2563 $site_dir = WP_CONTENT_DIR . "/themes/$template";
2565 // If the theme already exists, nothing to do.
2566 if ( is_dir($site_dir)) {
2570 // We must be able to write to the themes dir.
2571 if (! is_writable(WP_CONTENT_DIR . "/themes")) {
2576 if (! mkdir($site_dir, 0777)) {
2580 if (file_exists(ABSPATH . 'wp-layout.css')) {
2581 if (! make_site_theme_from_oldschool($theme_name, $template)) {
2582 // TODO: rm -rf the site theme directory.
2586 if (! make_site_theme_from_default($theme_name, $template))
2587 // TODO: rm -rf the site theme directory.
2591 // Make the new site theme active.
2592 $current_template = __get_option('template');
2593 if ($current_template == WP_DEFAULT_THEME) {
2594 update_option('template', $template);
2595 update_option('stylesheet', $template);
2601 * Translate user level to user role name.
2605 * @param int $level User level.
2606 * @return string User role name.
2608 function translate_level_to_role($level) {
2613 return 'administrator';
2623 return 'contributor';
2625 return 'subscriber';
2630 * Checks the version of the installed MySQL binary.
2634 * @global wpdb $wpdb
2636 function wp_check_mysql_version() {
2638 $result = $wpdb->check_database_version();
2639 if ( is_wp_error( $result ) )
2640 die( $result->get_error_message() );
2644 * Disables the Automattic widgets plugin, which was merged into core.
2648 function maybe_disable_automattic_widgets() {
2649 $plugins = __get_option( 'active_plugins' );
2651 foreach ( (array) $plugins as $plugin ) {
2652 if ( basename( $plugin ) == 'widgets.php' ) {
2653 array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
2654 update_option( 'active_plugins', $plugins );
2661 * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
2665 * @global int $wp_current_db_version
2666 * @global wpdb $wpdb WordPress database abstraction object.
2668 function maybe_disable_link_manager() {
2669 global $wp_current_db_version, $wpdb;
2671 if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) )
2672 update_option( 'link_manager_enabled', 0 );
2676 * Runs before the schema is upgraded.
2680 * @global int $wp_current_db_version
2681 * @global wpdb $wpdb WordPress database abstraction object.
2683 function pre_schema_upgrade() {
2684 global $wp_current_db_version, $wpdb;
2686 // Upgrade versions prior to 2.9
2687 if ( $wp_current_db_version < 11557 ) {
2688 // Delete duplicate options. Keep the option with the highest option_id.
2689 $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id");
2691 // Drop the old primary key and add the new.
2692 $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)");
2694 // Drop the old option_name index. dbDelta() doesn't do the drop.
2695 $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name");
2698 // Multisite schema upgrades.
2699 if ( $wp_current_db_version < 25448 && is_multisite() && wp_should_upgrade_global_tables() ) {
2701 // Upgrade verions prior to 3.7
2702 if ( $wp_current_db_version < 25179 ) {
2703 // New primary key for signups.
2704 $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
2705 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
2708 if ( $wp_current_db_version < 25448 ) {
2709 // Convert archived from enum to tinyint.
2710 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
2711 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
2715 // Upgrade versions prior to 4.2.
2716 if ( $wp_current_db_version < 31351 ) {
2717 if ( ! is_multisite() && wp_should_upgrade_global_tables() ) {
2718 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2720 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
2721 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
2722 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2723 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2724 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
2727 // Upgrade versions prior to 4.4.
2728 if ( $wp_current_db_version < 34978 ) {
2729 // If compatible termmeta table is found, use it, but enforce a proper index and update collation.
2730 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) && $wpdb->get_results( "SHOW INDEX FROM {$wpdb->termmeta} WHERE Column_name = 'meta_key'" ) ) {
2731 $wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
2732 maybe_convert_table_to_utf8mb4( $wpdb->termmeta );
2738 * Install global terms.
2742 * @global wpdb $wpdb
2743 * @global string $charset_collate
2745 if ( !function_exists( 'install_global_terms' ) ) :
2746 function install_global_terms() {
2747 global $wpdb, $charset_collate;
2749 CREATE TABLE $wpdb->sitecategories (
2750 cat_ID bigint(20) NOT NULL auto_increment,
2751 cat_name varchar(55) NOT NULL default '',
2752 category_nicename varchar(200) NOT NULL default '',
2753 last_updated timestamp NOT NULL,
2754 PRIMARY KEY (cat_ID),
2755 KEY category_nicename (category_nicename),
2756 KEY last_updated (last_updated)
2759 // now create tables
2760 dbDelta( $ms_queries );
2765 * Determine if global tables should be upgraded.
2767 * This function performs a series of checks to ensure the environment allows
2768 * for the safe upgrading of global WordPress database tables. It is necessary
2769 * because global tables will commonly grow to millions of rows on large
2770 * installations, and the ability to control their upgrade routines can be
2771 * critical to the operation of large networks.
2773 * In a future iteration, this function may use `wp_is_large_network()` to more-
2774 * intelligently prevent global table upgrades. Until then, we make sure
2775 * WordPress is on the main site of the main network, to avoid running queries
2776 * more than once in multi-site or multi-network environments.
2780 * @return bool Whether to run the upgrade routines on global tables.
2782 function wp_should_upgrade_global_tables() {
2784 // Return false early if explicitly not upgrading
2785 if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
2789 // Assume global tables should be upgraded
2790 $should_upgrade = true;
2792 // Set to false if not on main network (does not matter if not multi-network)
2793 if ( ! is_main_network() ) {
2794 $should_upgrade = false;
2797 // Set to false if not on main site of current network (does not matter if not multi-site)
2798 if ( ! is_main_site() ) {
2799 $should_upgrade = false;
2803 * Filter if upgrade routines should be run on global tables.
2805 * @param bool $should_upgrade Whether to run the upgrade routines on global tables.
2807 return apply_filters( 'wp_should_upgrade_global_tables', $should_upgrade );